mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:56:46 +00:00
feature/add_required_field_annotation : all required field validation put at startConnector, at this single place.
This commit is contained in:
parent
97d45e07a9
commit
9fdc819968
@ -2128,7 +2128,7 @@ Returns a string showed to the developer
|
||||
* @param box Some boxed type
|
||||
* @return Boxed value or throw some exception
|
||||
*/
|
||||
def fullBoxOrException[T](box: Box[T])(implicit m: Manifest[T]) : Box[T]= {
|
||||
def fullBoxOrException[T](box: Box[T]) : Box[T]= {
|
||||
box match {
|
||||
case Full(v) => // Just forwarding
|
||||
Full(v)
|
||||
|
||||
@ -4,7 +4,7 @@ import java.util.Date
|
||||
import java.util.UUID.randomUUID
|
||||
|
||||
import code.accountholders.{AccountHolders, MapperAccountHolders}
|
||||
import code.api.ApiVersionHolder
|
||||
import code.api.{APIFailure, APIFailureNewStyle}
|
||||
import code.api.cache.Caching
|
||||
import code.api.util.APIUtil.{OBPReturnType, _}
|
||||
import code.api.util.ApiRole._
|
||||
@ -38,7 +38,7 @@ import code.views.Views
|
||||
import com.openbankproject.commons.model.enums.{AccountAttributeType, CardAttributeType, DynamicEntityOperation, ProductAttributeType}
|
||||
import com.openbankproject.commons.model.{AccountApplication, Bank, CounterpartyTrait, CustomerAddress, Product, ProductCollection, ProductCollectionItem, TaxResidence, TransactionRequestStatus, UserAuthContext, UserAuthContextUpdate, _}
|
||||
import com.tesobe.CacheKeyFromArguments
|
||||
import net.liftweb.common.{Box, Empty, Failure, Full}
|
||||
import net.liftweb.common.{Box, Empty, EmptyBox, Failure, Full, ParamFailure}
|
||||
import net.liftweb.json.{Formats, JObject, JValue}
|
||||
import net.liftweb.mapper.By
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
@ -47,7 +47,7 @@ import net.liftweb.util.SimpleInjector
|
||||
import scala.collection.immutable.{List, Nil}
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.json
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.duration._
|
||||
@ -96,6 +96,29 @@ object Connector extends SimpleInjector {
|
||||
|
||||
}
|
||||
|
||||
|
||||
def extractAdapterResponse[T: Manifest](responseJson: String): Box[T] = {
|
||||
val clazz = manifest[T].runtimeClass
|
||||
val boxJValue: Box[Box[JValue]] = tryo {
|
||||
val jValue = json.parse(responseJson)
|
||||
if (ErrorMessage.isErrorMessage(jValue)) {
|
||||
val ErrorMessage(code, message) = jValue.extract[ErrorMessage]
|
||||
ParamFailure(message, Empty, Empty, APIFailure(message, code))
|
||||
} else {
|
||||
Box !! jValue
|
||||
}
|
||||
} ~> APIFailureNewStyle(s"INTERNAL-$InvalidJsonFormat The Json body should be the ${clazz.getName} ", 400)
|
||||
|
||||
boxJValue match {
|
||||
case Full(Full(jValue)) =>
|
||||
tryo {
|
||||
jValue.extract[T](CustomJsonFormats.nullTolerateFormats, manifest[T])
|
||||
} ~> APIFailureNewStyle(s"INTERNAL-$InvalidJsonFormat The Json body should be the ${clazz.getName} ", 400)
|
||||
|
||||
case Full(failure) => failure.asInstanceOf[Box[T]]
|
||||
case empty: EmptyBox => empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait Connector extends MdcLoggable {
|
||||
@ -129,8 +152,6 @@ trait Connector extends MdcLoggable {
|
||||
protected val statusOfCreditcardOrders = getSecondsCache("getStatusOfCreditCardOrderFuture")
|
||||
protected val bankAccountsBalancesTTL = getSecondsCache("getBankAccountsBalances")
|
||||
|
||||
protected def apiVersion: ApiVersion = ApiVersionHolder.getApiVersion
|
||||
|
||||
/**
|
||||
* convert original return type future to OBPReturnType
|
||||
*
|
||||
@ -1922,4 +1943,4 @@ trait Connector extends MdcLoggable {
|
||||
callContext: Option[CallContext]): OBPReturnType[Box[StandingOrderTrait]] = Future {
|
||||
(Failure(setUnimplementedError), callContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,8 @@ package code
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
import code.api.util.NewStyle
|
||||
import code.api.{APIFailure, APIFailureNewStyle, ApiVersionHolder}
|
||||
import code.api.util.{CallContext, NewStyle}
|
||||
import code.bankconnectors.akka.AkkaConnector_vDec2018
|
||||
import code.bankconnectors.rest.RestConnector_vMar2019
|
||||
import code.bankconnectors.storedprocedure.StoredProcedureConnector_vDec2019
|
||||
@ -11,14 +12,26 @@ import code.bankconnectors.vMar2017.KafkaMappedConnector_vMar2017
|
||||
import code.bankconnectors.vMay2019.KafkaMappedConnector_vMay2019
|
||||
import code.bankconnectors.vSept2018.KafkaMappedConnector_vSept2018
|
||||
import code.methodrouting.MethodRouting
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.openbankproject.commons.model.BankId
|
||||
import com.openbankproject.commons.util.ReflectUtils.{findMethodByArgs, getConstructorArgs}
|
||||
import net.liftweb.common.{Box, EmptyBox}
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.{Box, Empty, EmptyBox, Full, ParamFailure}
|
||||
import net.sf.cglib.proxy.{Enhancer, MethodInterceptor, MethodProxy}
|
||||
|
||||
import scala.reflect.runtime.universe.{Type, typeOf}
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.reflect.runtime.universe.{MethodSymbol, Type, typeOf}
|
||||
import code.api.util.ErrorMessages.InvalidConnectorResponseForMissingRequiredValues
|
||||
import code.api.util.APIUtil.{fullBoxOrException, unboxFull}
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import com.openbankproject.commons.util.ReflectUtils._
|
||||
import com.openbankproject.commons.util.Functions.RichCollection
|
||||
|
||||
package object bankconnectors {
|
||||
import scala.collection.GenTraversableOnce
|
||||
import scala.concurrent.Future
|
||||
|
||||
package object bankconnectors extends MdcLoggable {
|
||||
|
||||
/**
|
||||
* a star connector object, usage:
|
||||
@ -44,8 +57,11 @@ package object bankconnectors {
|
||||
if(method.getName.contains("$default$")) {
|
||||
method.invoke(StubConnector, args:_*)
|
||||
} else {
|
||||
val objToCall = getConnectorObject(method, args)
|
||||
method.invoke(objToCall, args:_*)
|
||||
val (objToCall, methodSymbol) = getConnectorObject(method, args)
|
||||
val connectorMethodResult = method.invoke(objToCall, args: _*)
|
||||
logger.debug(s"do required field validation for ${methodSymbol.typeSignature}")
|
||||
val apiVersion = ApiVersionHolder.getApiVersion
|
||||
validatRequiredFields(connectorMethodResult, methodSymbol.returnType, apiVersion)
|
||||
}
|
||||
}
|
||||
val enhancer: Enhancer = new Enhancer()
|
||||
@ -60,9 +76,10 @@ package object bankconnectors {
|
||||
* @param args passed arguments
|
||||
* @return connector Object
|
||||
*/
|
||||
private[this]def getConnectorObject(method: Method, args: Seq[Any]): Connector = {
|
||||
private[this]def getConnectorObject(method: Method, args: Seq[Any]): (Connector, MethodSymbol) = {
|
||||
val methodName = method.getName
|
||||
val methodSymbol = findMethodByArgs(typeOf[Connector], methodName, args:_*).getOrElse(sys.error(s"not found matched method, method name: ${methodName}, params: ${args.mkString(",")}"))
|
||||
val tpe = typeOf[Connector]
|
||||
val methodSymbol: MethodSymbol = findMethodByArgs(tpe, methodName, args:_*).getOrElse(sys.error(s"not found matched method, method name: ${methodName}, params: ${args.mkString(",")}"))
|
||||
val paramList = methodSymbol.paramLists.headOption.getOrElse(Nil)
|
||||
val paramNameToType: Map[String, Type] = paramList.map(param => (param.name.toString, param.info)).toMap
|
||||
val paramNameToValue: Map[String, Any] = paramList.zip(args).map(pair =>(pair._1.name.toString, pair._2)).toMap
|
||||
@ -101,7 +118,7 @@ package object bankconnectors {
|
||||
}
|
||||
}
|
||||
|
||||
connectorName.getOrElse("mapped") match {
|
||||
val connector = connectorName.getOrElse("mapped") match {
|
||||
case "mapped" => LocalMappedConnector
|
||||
case "akka_vDec2018" => AkkaConnector_vDec2018
|
||||
case "kafka" => KafkaMappedConnector
|
||||
@ -114,6 +131,7 @@ package object bankconnectors {
|
||||
case "stored_procedure_vDec2019" => StoredProcedureConnector_vDec2019
|
||||
case _ => throw new IllegalStateException(s"config of connector.start.methodName.${methodName} have wrong value, not exists connector of name ${connectorName.get}")
|
||||
}
|
||||
(connector, methodSymbol)
|
||||
}
|
||||
|
||||
|
||||
@ -177,4 +195,104 @@ package object bankconnectors {
|
||||
}
|
||||
}
|
||||
|
||||
private def validatRequiredFields(value: AnyRef, returnType: Type, apiVersion: ApiVersion): AnyRef = {
|
||||
value match {
|
||||
case Unit => value
|
||||
case coll @(_:Array[_] | _: ArrayBuffer[_] | _: GenTraversableOnce[_]) =>
|
||||
val elementTpe = returnType.typeArgs.head
|
||||
validate(value, elementTpe, coll, apiVersion, None, false)
|
||||
|
||||
case Full((coll: GenTraversableOnce[_], cc: Option[_]))
|
||||
if coll.nonEmpty && getNestTypeArg(returnType, 0, 1, 0) =:= typeOf[CallContext] =>
|
||||
val elementTpe = getNestTypeArg(returnType, 0, 0, 0)
|
||||
val callContext = cc.asInstanceOf[Option[CallContext]]
|
||||
validate(value, elementTpe, coll, apiVersion, callContext)
|
||||
|
||||
case Full((v, cc: Option[_]))
|
||||
if getNestTypeArg(returnType, 0, 1, 0) =:= typeOf[CallContext] =>
|
||||
val elementTpe = getNestTypeArg(returnType, 0, 0)
|
||||
val callContext = cc.asInstanceOf[Option[CallContext]]
|
||||
validate(value, elementTpe, v, apiVersion, callContext)
|
||||
|
||||
case Full((v1, v2)) =>
|
||||
val tpe1 = getNestTypeArg(returnType, 0, 0)
|
||||
val tpe2 = getNestTypeArg(returnType, 0, 1)
|
||||
validateMultiple(value, apiVersion)(v1 -> tpe1, v2 -> tpe2)
|
||||
|
||||
// return type is: Box[List[(ProductCollectionItem, Product, List[ProductAttribute])]]
|
||||
case Full(coll: Traversable[_])
|
||||
if coll.nonEmpty &&
|
||||
getNestTypeArg(returnType, 0, 0) <:< typeOf[(_, _, GenTraversableOnce[_])] =>
|
||||
val tpe1 = getNestTypeArg(returnType, 0, 0, 0)
|
||||
val tpe2 = getNestTypeArg(returnType, 0, 0, 1)
|
||||
val tpe3 = getNestTypeArg(returnType, 0, 0, 2, 0)
|
||||
val collTuple = coll.asInstanceOf[Traversable[(_, _, _)]]
|
||||
val v1 = collTuple.map(_._1)
|
||||
val v2 = collTuple.map(_._2)
|
||||
val v3 = collTuple.map(_._3)
|
||||
validateMultiple(value, apiVersion)(v1 -> tpe1, v2 -> tpe2, v3 -> tpe3)
|
||||
|
||||
case Full(coll: GenTraversableOnce[_]) if coll.nonEmpty =>
|
||||
val elementTpe = getNestTypeArg(returnType, 0, 0)
|
||||
validate(value, elementTpe, coll, apiVersion)
|
||||
|
||||
case Full(v) =>
|
||||
val elementTpe = returnType.typeArgs.head
|
||||
validate(value, elementTpe, v, apiVersion)
|
||||
|
||||
case (f @Full(v), cc: Option[_])
|
||||
if getNestTypeArg(returnType, 1, 0) =:= typeOf[CallContext] =>
|
||||
val elementTpe = getNestTypeArg(returnType, 0, 0)
|
||||
val callContext = cc.asInstanceOf[Option[CallContext]]
|
||||
val result = validate(f, elementTpe, v, apiVersion, callContext)
|
||||
(result, cc)
|
||||
|
||||
case (v, cc: Option[_])
|
||||
if getNestTypeArg(returnType, 1, 0) =:= typeOf[CallContext] =>
|
||||
val elementTpe = returnType.typeArgs.head
|
||||
val callContext = cc.asInstanceOf[Option[CallContext]]
|
||||
validate(value, elementTpe, v, apiVersion, callContext, false)
|
||||
|
||||
case future: Future[_] =>
|
||||
val futureType = returnType.typeArgs.head
|
||||
future.map(v => validatRequiredFields(v.asInstanceOf[AnyRef], futureType, apiVersion))
|
||||
|
||||
case _ => validate(value, returnType, value, apiVersion, None, false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private def validate[T: Manifest](originValue: AnyRef,
|
||||
validateType: Type,
|
||||
any: Any,
|
||||
apiVersion: ApiVersion,
|
||||
cc: Option[CallContext] = None,
|
||||
resultIsBox: Boolean = true): AnyRef =
|
||||
validateMultiple[T](originValue, apiVersion, cc, resultIsBox)(any -> validateType)
|
||||
|
||||
|
||||
private def validateMultiple[T: Manifest](originValue: AnyRef,
|
||||
apiVersion: ApiVersion,
|
||||
cc: Option[CallContext] = None,
|
||||
resultIsBox: Boolean = true)(valueAndType: (Any, Type)*): AnyRef = {
|
||||
val (lefts, _) = valueAndType
|
||||
.map(it => Helper.getRequiredFieldInfo(it._2).validate(it._1, apiVersion))
|
||||
.classify(_.isLeft)
|
||||
|
||||
if(lefts.isEmpty) { // all validation passed
|
||||
originValue
|
||||
} else {
|
||||
val missingFields = lefts.flatMap(_.left.get)
|
||||
val value = missingFieldsToFailure(missingFields, cc)
|
||||
if(resultIsBox) value else fullBoxOrException(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private def missingFieldsToFailure(missingFields: Seq[String], cc: Option[CallContext] = None): ParamFailure[APIFailureNewStyle] = {
|
||||
val message = missingFields.map(it => s"data.$it")
|
||||
.mkString(s"INTERNAL-$InvalidConnectorResponseForMissingRequiredValues The missing fields: [", ", ", "]")
|
||||
logger.error(message)
|
||||
ParamFailure(message, Empty, Empty, APIFailureNewStyle(message, 400, cc.map(_.toLight)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -9458,26 +9458,10 @@ trait RestConnector_vMar2019 extends Connector with KafkaHelper with MdcLoggable
|
||||
}
|
||||
|
||||
private[this] def extractEntity[T: TypeTag: Manifest](responseEntity: ResponseEntity): Future[Box[T]] = {
|
||||
val tp = typeTag[T].tpe
|
||||
this.extractBody(responseEntity)
|
||||
.map({
|
||||
case null => Empty
|
||||
case str => {
|
||||
val box: Box[Box[T]] = tryo {
|
||||
implicit val formats: Formats = CustomJsonFormats.nullTolerateFormats
|
||||
val jValue = parse(str)
|
||||
val extractResult: Either[List[String], T] = Helper.getRequiredFieldInfo(tp).validateAndExtract[T](jValue, apiVersion)
|
||||
extractResult match {
|
||||
case Left(missingFields) =>
|
||||
val message = missingFields.mkString(s"INTERNAL-$InvalidConnectorResponseForMissingRequiredValues The missing fields: [", ", ", "]")
|
||||
logger.error(message)
|
||||
ParamFailure(message, Empty, Empty, APIFailure(message, 400))
|
||||
case Right(entity) => Full(entity)
|
||||
}
|
||||
} ~> APIFailureNewStyle(s"$InvalidJsonFormat The Json body should be the ${tp.typeSymbol.fullName} ", 400)
|
||||
|
||||
box.flatten
|
||||
}
|
||||
case str => Connector.extractAdapterResponse[T](str)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -13016,34 +13016,8 @@ trait StoredProcedureConnector_vDec2019 extends Connector with MdcLoggable {
|
||||
private[this] def sendRequest[T <: InBoundTrait[_]: TypeTag : Manifest](procedureName: String, outBound: TopicTrait, callContext: Option[CallContext]): Future[Box[T]] = {
|
||||
//transfer accountId to accountReference and customerId to customerReference in outBound
|
||||
this.convertToReference(outBound)
|
||||
val apiVersion = ApiVersionHolder.getApiVersion
|
||||
val tp = typeTag[T].tpe
|
||||
Future{
|
||||
val jValue = StoredProcedureUtils.callProcedure(procedureName, outBound)
|
||||
val box: Box[T] = jValue match {
|
||||
case v if ErrorMessage.isErrorMessage(v) =>
|
||||
val ErrorMessage(code, message) = v.extract[ErrorMessage]
|
||||
ParamFailure(message, Empty, Empty, APIFailure(message, code))
|
||||
case _ => {
|
||||
val boxBox: Box[Box[T]] = tryo {
|
||||
implicit val formats: Formats = CustomJsonFormats.nullTolerateFormats
|
||||
val extractResult: Either[List[String], T] = Helper.getRequiredFieldInfo(tp).validateAndExtract[T](jValue, apiVersion)
|
||||
extractResult match {
|
||||
case Left(missingFields) =>
|
||||
val message = missingFields.mkString(s"INTERNAL-$InvalidConnectorResponseForMissingRequiredValues The missing fields: [", ", ", "]")
|
||||
logger.error(message)
|
||||
ParamFailure(message, Empty, Empty, APIFailure(message, 400))
|
||||
case Right(entity) => Full(entity)
|
||||
}
|
||||
} ~> APIFailureNewStyle(s"INTERNAL-$InvalidJsonFormat The Json body should be the ${tp.typeSymbol.fullName} ", 400)
|
||||
|
||||
boxBox match {
|
||||
case Full(v) => v
|
||||
case e: EmptyBox => e
|
||||
}
|
||||
}
|
||||
}
|
||||
box
|
||||
StoredProcedureUtils.callProcedure[T](procedureName, outBound)
|
||||
}.map(convertToId(_)) recoverWith {
|
||||
case e: Exception => Future.failed(new Exception(s"$AdapterUnknownError Please Check Adapter Side! Details: ${e.getMessage}", e))
|
||||
}
|
||||
|
||||
@ -3,9 +3,9 @@ package code.bankconnectors.storedprocedure
|
||||
import java.sql.Connection
|
||||
|
||||
import code.api.util.APIUtil
|
||||
import code.bankconnectors.Connector
|
||||
import com.openbankproject.commons.model.TopicTrait
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json.JValue
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.json.Serialization.write
|
||||
import scalikejdbc.{DB, _}
|
||||
|
||||
@ -16,6 +16,8 @@ import scalikejdbc.{DB, _}
|
||||
*/
|
||||
object StoredProcedureUtils {
|
||||
|
||||
private implicit val formats = code.api.util.CustomJsonFormats.nullTolerateFormats
|
||||
|
||||
// lazy initial DB connection
|
||||
{
|
||||
val driver = APIUtil.getPropsValue("stored_procedure_connector.driver").openOrThrowException("mandatory property stored_procedure_connector.driver is missing!")
|
||||
@ -42,8 +44,7 @@ object StoredProcedureUtils {
|
||||
}
|
||||
|
||||
|
||||
def callProcedure(procedureName: String, outBound: TopicTrait): JValue = {
|
||||
implicit val formats = code.api.util.CustomJsonFormats.formats
|
||||
def callProcedure[T: Manifest](procedureName: String, outBound: TopicTrait): Box[T] = {
|
||||
val procedureParam: String = write(outBound) // convert OutBound to json string
|
||||
|
||||
val responseJson: String =
|
||||
@ -72,8 +73,6 @@ object StoredProcedureUtils {
|
||||
callableStatement.getString(2)
|
||||
}
|
||||
}
|
||||
|
||||
json.parse(responseJson)
|
||||
Connector.extractAdapterResponse[T](responseJson)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ class CommonGenerator(val methodName: String, tp: Type) {
|
||||
|
|
||||
| val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get ${params})
|
||||
| logger.debug(s"Kafka ${methodName} Req is: $$req")
|
||||
| processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
| processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
| }
|
||||
""".stripMargin
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get )
|
||||
logger.debug(s"Kafka getAdapterInfo Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -236,7 +236,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId)
|
||||
logger.debug(s"Kafka getBank Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -313,7 +313,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get )
|
||||
logger.debug(s"Kafka getBanks Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -393,7 +393,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankIdAccountIds)
|
||||
logger.debug(s"Kafka getBankAccountsBalances Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -520,7 +520,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, branchId)
|
||||
logger.debug(s"Kafka getBranch Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -650,7 +650,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, OBPQueryParam.getLimit(queryParams), OBPQueryParam.getOffset(queryParams), OBPQueryParam.getFromDate(queryParams), OBPQueryParam.getToDate(queryParams))
|
||||
logger.debug(s"Kafka getBranches Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -757,7 +757,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, atmId)
|
||||
logger.debug(s"Kafka getAtm Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -867,7 +867,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, OBPQueryParam.getLimit(queryParams), OBPQueryParam.getOffset(queryParams), OBPQueryParam.getFromDate(queryParams), OBPQueryParam.getToDate(queryParams))
|
||||
logger.debug(s"Kafka getAtms Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -959,7 +959,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , userId)
|
||||
logger.debug(s"Kafka getCustomersByUserId Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -1051,7 +1051,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , customerId)
|
||||
logger.debug(s"Kafka getCustomerByCustomerId Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -1144,7 +1144,7 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , customerNumber, bankId)
|
||||
logger.debug(s"Kafka getCustomerByCustomerNumber Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -1152,21 +1152,6 @@ trait KafkaMappedConnector_vMay2019 extends Connector with KafkaHelper with MdcL
|
||||
|
||||
|
||||
//---------------- dynamic end ---------------------please don't modify this line
|
||||
|
||||
private[this] def validateRequiredFields[T: TypeTag: Manifest](version: ApiVersion)(box: Box[T]): Box[T] =
|
||||
box match {
|
||||
case Full(entity) => {
|
||||
val value: Either[List[String], T] = RequiredFieldValidation.getRequiredInfo(typeTag[T].tpe).validate(entity, version)
|
||||
value match {
|
||||
case Left(missingFields) =>
|
||||
val message = missingFields.mkString(s"INTERNAL-$InvalidConnectorResponseForMissingRequiredValues The missing fields: [", ", ", "]")
|
||||
logger.error(message)
|
||||
ParamFailure(message, Empty, Empty, APIFailure(message, 400))
|
||||
case _ => box
|
||||
}
|
||||
}
|
||||
case _ => box
|
||||
}
|
||||
|
||||
//-----helper methods
|
||||
|
||||
|
||||
@ -204,7 +204,7 @@ class CommonGenerator(val methodName: String, typeSignature: Type) {
|
||||
|
|
||||
| val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get ${parametersNamesString})
|
||||
| logger.debug(s"Kafka ${methodName} Req is: $$req")
|
||||
| processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
| processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
| }
|
||||
""".stripMargin
|
||||
|
||||
|
||||
@ -3160,7 +3160,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, accountId, accountType, accountLabel, currency, initialBalance, accountHolderName, branchId, accountRoutingScheme, accountRoutingAddress)
|
||||
logger.debug(s"Kafka createBankAccount Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
|
||||
@ -3260,7 +3260,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, legalName, mobileNumber, email, faceImage, dateOfBirth, relationshipStatus, dependents, dobOfDependents, highestEducationAttained, employmentStatus, kycStatus, lastOkDate, creditRating, creditLimit, title, branchId, nameSuffix)
|
||||
logger.debug(s"Kafka createCustomer Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
|
||||
@ -3336,7 +3336,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, customerId, id, customerNumber, date, how, staffUserId, mStaffName, mSatisfied, comments)
|
||||
logger.debug(s"Kafka createOrUpdateKycCheck Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
|
||||
@ -3410,7 +3410,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, customerId, id, customerNumber, `type`, number, issueDate, issuePlace, expiryDate)
|
||||
logger.debug(s"Kafka createOrUpdateKycDocument Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
|
||||
@ -3484,7 +3484,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, customerId, id, customerNumber, `type`, url, date, relatesToKycDocumentId, relatesToKycCheckId)
|
||||
logger.debug(s"Kafka createOrUpdateKycMedia Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
|
||||
@ -3550,7 +3550,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , bankId, customerId, customerNumber, ok, date)
|
||||
logger.debug(s"Kafka createOrUpdateKycStatus Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
|
||||
@ -3626,7 +3626,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , customerId)
|
||||
logger.debug(s"Kafka getKycChecks Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -3704,7 +3704,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , customerId)
|
||||
logger.debug(s"Kafka getKycDocuments Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -3782,7 +3782,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , customerId)
|
||||
logger.debug(s"Kafka getKycMedias Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -3856,7 +3856,7 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).get , customerId)
|
||||
logger.debug(s"Kafka getKycStatuses Req is: $req")
|
||||
processRequest[InBound](req) map(validateRequiredFields(apiVersion)) map (convertToTuple(callContext))
|
||||
processRequest[InBound](req) map (convertToTuple(callContext))
|
||||
}
|
||||
|
||||
}
|
||||
@ -3877,22 +3877,6 @@ trait KafkaMappedConnector_vSept2018 extends Connector with KafkaHelper with Mdc
|
||||
|
||||
//-----helper methods
|
||||
|
||||
private[this] def validateRequiredFields[T: TypeTag: Manifest](version: ApiVersion)(box: Box[T]): Box[T] =
|
||||
box match {
|
||||
case Full(entity) => {
|
||||
val value: Either[List[String], T] = RequiredFieldValidation.getRequiredInfo(typeTag[T].tpe).validate(entity, version)
|
||||
value match {
|
||||
case Left(missingFields) =>
|
||||
val message = missingFields.mkString(s"INTERNAL-$InvalidConnectorResponseForMissingRequiredValues The missing fields: [", ", ", "]")
|
||||
logger.error(message)
|
||||
ParamFailure(message, Empty, Empty, APIFailure(message, 400))
|
||||
case _ => box
|
||||
}
|
||||
}
|
||||
case _ => box
|
||||
}
|
||||
|
||||
|
||||
private[this] def convertToTuple[T](callContext: Option[CallContext]) (inbound: Box[InBoundTrait[T]]): (Box[T], Option[CallContext]) = {
|
||||
val boxedResult = inbound match {
|
||||
case Full(in) if (in.status.hasNoError) => Full(in.data)
|
||||
|
||||
@ -12,6 +12,7 @@ import net.liftweb.json.{Formats, JValue}
|
||||
import net.liftweb.json.JsonDSL._
|
||||
|
||||
import scala.collection.GenTraversableOnce
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
/**
|
||||
* Mark given type's field or constructor variable is required for some apiVersion
|
||||
@ -100,8 +101,8 @@ case class RequiredInfo(requiredArgs: Seq[RequiredArgs]) extends RequiredFields
|
||||
|
||||
val scannedPathValue: JValue = prePathValue match {
|
||||
case JArray(arr) => {
|
||||
val (jArrayList: List[JArray], jValueList) = arr.classify(_.isInstanceOf[JArray])
|
||||
val newArr: List[JValue] = jArrayList.flatMap(_.arr) :: jValueList
|
||||
val (jArrayList: List[_], jValueList) = arr.classify(_.isInstanceOf[JArray])
|
||||
val newArr: List[JValue] = jArrayList.flatMap(_.asInstanceOf[JArray].arr) :: jValueList
|
||||
|
||||
val noEmpties = newArr.filterNot(isEmpty)
|
||||
JArray(noEmpties) \ currentPath
|
||||
@ -132,7 +133,7 @@ case class RequiredInfo(requiredArgs: Seq[RequiredArgs]) extends RequiredFields
|
||||
}
|
||||
}
|
||||
|
||||
def validate[T: Manifest](entity: T, apiVersion: ApiVersion)(implicit formats: Formats): Either[List[String], T] = {
|
||||
def validate[T](entity: T, apiVersion: ApiVersion): Either[List[String], T] = {
|
||||
|
||||
val noValuePath = scala.collection.mutable.ListBuffer[String]()
|
||||
val map = scala.collection.mutable.Map[String, Any]()
|
||||
@ -184,6 +185,7 @@ case class RequiredInfo(requiredArgs: Seq[RequiredArgs]) extends RequiredFields
|
||||
*/
|
||||
private def flatten(any: Any): Any = any match {
|
||||
case a:Array[_] => Functions.deepFlatten(a)
|
||||
case ab: ArrayBuffer[_] => Functions.deepFlatten(ab.toArray[Any])
|
||||
case coll: GenTraversableOnce[_] => Functions.deepFlatten(coll.toArray[Any])
|
||||
case _ => any
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user