mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:56:46 +00:00
Merge remote-tracking branch 'Simon/develop' into develop
# Conflicts: # obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModel.scala
This commit is contained in:
commit
95b5207972
@ -1,3 +1,3 @@
|
||||
install:
|
||||
- echo "Running a custom install command"
|
||||
- mvn clean source:jar install -pl .,obp-commons && mvn source:jar install -DskipTests -pl obp-api
|
||||
- mvn clean source:jar install -pl .,obp-commons && mvn source:jar install -U -DskipTests -pl obp-api
|
||||
@ -8,7 +8,7 @@
|
||||
<groupId>com.tesobe</groupId>
|
||||
<artifactId>obp-parent</artifactId>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<version>1.6.1</version>
|
||||
<version>1.6.2</version>
|
||||
</parent>
|
||||
<artifactId>obp-api</artifactId>
|
||||
<packaging>war</packaging>
|
||||
@ -27,6 +27,19 @@
|
||||
<groupId>com.tesobe</groupId>
|
||||
<artifactId>obp-commons</artifactId>
|
||||
</dependency>
|
||||
<!--embed akka adapter start-->
|
||||
<dependency>
|
||||
<groupId>com.github.OpenBankProject.OBP-Adapter-Akka-SpringBoot</groupId>
|
||||
<artifactId>adapter-akka-commons</artifactId>
|
||||
<version>v1.1.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--embed akka adapter end-->
|
||||
<dependency>
|
||||
<groupId>com.github.everit-org.json-schema</groupId>
|
||||
<artifactId>org.everit.json.schema</artifactId>
|
||||
|
||||
@ -16,7 +16,7 @@ connector=mapped
|
||||
#connector=stored_procedure_vDec2019
|
||||
#connector=obpjvm
|
||||
#connector=star
|
||||
## proxy connector get data from LocalMappedConnector, and set the follow corresponding fields to be null: @ignore, inbound.ignore.fields props, outbound.ignore.fields props
|
||||
## proxy connector get data from LocalMappedConnector, and set the follow corresponding fields to be null: @optional, inbound.optional.fields props, outbound.optional.fields props
|
||||
## the proxy connector only for test purpose
|
||||
#connector=proxy
|
||||
#connector=...
|
||||
@ -714,6 +714,11 @@ featured_apis=elasticSearchWarehouseV300
|
||||
# akka_connector.loglevel=INFO/DEBUG etc.
|
||||
# In case isn't defined default value is "akka-connector-actor"
|
||||
# akka_connector.name_of_actor=SOME_ACTOR_NAME
|
||||
# akka connector timeout seconds, default is 3 seconds
|
||||
# akka_connector.timeout=10
|
||||
## When akka_connector.embed_adapter set true, will start embed akka adapter,
|
||||
## Outbound akka message will be sent to this embed akka adapter's Actor. the default value is false
|
||||
#akka_connector.embed_adapter=true
|
||||
# --------------------------------------------------------------
|
||||
|
||||
|
||||
@ -837,12 +842,12 @@ dynamic_endpoints_url_prefix=dynamic
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
## Inbound and Outbound ignore field names, case class name can be prefix.
|
||||
inbound.ignore.fields=\
|
||||
inbound.optional.fields=\
|
||||
inboundAdapterCallContext.generalContext,\
|
||||
inboundAdapterCallContext.sessionId,\
|
||||
InBoundGetBanks:data.logoUrl
|
||||
|
||||
outbound.ignore.fields= \
|
||||
outbound.optional.fields= \
|
||||
outboundAdapterCallContext.sessionId, \
|
||||
outboundAdapterCallContext.consumerId, \
|
||||
outboundAdapterCallContext.generalContext
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
#connector=rest
|
||||
#connector=kafka
|
||||
#connector=obpjvm
|
||||
## proxy connector get data from LocalMappedConnector, and set the follow corresponding fields to be null: @ignore, inbound.ignore.fields props, outbound.ignore.fields props
|
||||
## proxy connector get data from LocalMappedConnector, and set the follow corresponding fields to be null: @optional, inbound.optional.fields props, outbound.optional.fields props
|
||||
#connector=proxy
|
||||
connector=mapped
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ import code.views.system.{AccountAccess, ViewDefinition}
|
||||
import code.webhook.{MappedAccountWebhook, WebhookHelperActors}
|
||||
import code.webuiprops.WebUiProps
|
||||
import com.openbankproject.commons.model.ErrorMessage
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import com.openbankproject.commons.util.{ApiVersion, Functions}
|
||||
import com.openbankproject.commons.util.Functions.Implicits._
|
||||
import javax.mail.internet.MimeMessage
|
||||
import net.liftweb.common._
|
||||
@ -613,6 +613,10 @@ class Boot extends MdcLoggable {
|
||||
.filter(it => starConnectorTypes.exists(it.startsWith(_)))
|
||||
|
||||
assert(allSupportedConnectors.contains(connectorName), s"connector.name.export.as.endpoint=$connectorName, this value should be one of ${allSupportedConnectors.mkString(",")}")
|
||||
|
||||
case _ if connectorName == "mapped" =>
|
||||
Functions.doNothing
|
||||
|
||||
case Full(connector) =>
|
||||
assert(connector == connectorName, s"When 'connector=$connector', this props must be: connector.name.export.as.endpoint=$connector, but current it is $connectorName")
|
||||
}
|
||||
|
||||
@ -2,10 +2,12 @@ package code.actorsystem
|
||||
|
||||
import akka.actor.{ActorSelection, ActorSystem}
|
||||
import code.api.util.APIUtil
|
||||
import code.bankconnectors.LocalMappedOutInBoundTransfer
|
||||
import code.bankconnectors.akka.actor.{AkkaConnectorActorConfig, AkkaConnectorHelperActor}
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.webhook.WebhookHelperActors
|
||||
import com.openbankproject.adapter.akka.commons.config.AkkaConfig
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import net.liftweb.common.Full
|
||||
|
||||
@ -106,8 +108,10 @@ trait ObpLookupSystem extends MdcLoggable {
|
||||
|
||||
val hostname = APIUtil.getPropsValue("akka_connector.hostname")
|
||||
val port = APIUtil.getPropsValue("akka_connector.port")
|
||||
val embedAdapter = APIUtil.getPropsAsBoolValue("akka_connector.embed_adapter", false)
|
||||
|
||||
val actorPath: String = (hostname, port) match {
|
||||
case (Full(h), Full(p)) =>
|
||||
case (Full(h), Full(p)) if !embedAdapter =>
|
||||
val hostname = h
|
||||
val port = p
|
||||
val akka_connector_hostname = Helper.getAkkaConnectorHostname
|
||||
@ -120,7 +124,13 @@ trait ObpLookupSystem extends MdcLoggable {
|
||||
if (port == 0) {
|
||||
logger.error("Failed to find an available port.")
|
||||
}
|
||||
AkkaConnectorHelperActor.startAkkaConnectorHelperActors(ObpActorSystem.northSideAkkaConnectorActorSystem)
|
||||
|
||||
if(embedAdapter) {
|
||||
AkkaConfig(LocalMappedOutInBoundTransfer, Some(ObpActorSystem.northSideAkkaConnectorActorSystem))
|
||||
} else {
|
||||
AkkaConnectorHelperActor.startAkkaConnectorHelperActors(ObpActorSystem.northSideAkkaConnectorActorSystem)
|
||||
}
|
||||
|
||||
s"akka.tcp://SouthSideAkkaConnector_${props_hostname}@${hostname}:${port}/user/${actorName}"
|
||||
}
|
||||
this.obpLookupSystem.actorSelection(actorPath)
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package code.api.util
|
||||
|
||||
import code.api.util.ApiRole.rolesMappedToClasses
|
||||
import com.openbankproject.commons.dto.InBoundTrait
|
||||
import com.openbankproject.commons.model.TopicTrait
|
||||
import com.openbankproject.commons.util.Functions.Memo
|
||||
import com.openbankproject.commons.util.{JsonUtils, _}
|
||||
import net.liftweb.json
|
||||
@ -34,20 +36,26 @@ object CustomJsonFormats {
|
||||
}
|
||||
|
||||
|
||||
object FieldIgnoreSerializer extends Serializer[AnyRef] {
|
||||
private val typedIgnoreRegx = "(.+?):(.+)".r
|
||||
object OptionalFieldSerializer extends Serializer[AnyRef] {
|
||||
private val typedOptionalPathRegx = "(.+?):(.+)".r
|
||||
private val memo = new Memo[universe.Type, List[String]]()
|
||||
override def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, json.JValue), AnyRef] = Functions.doNothing
|
||||
private lazy val propsConfigIgnoreFields = Array(
|
||||
APIUtil.getPropsValue("outbound.ignore.fields", "").split("""\s*,\s*"""),
|
||||
APIUtil.getPropsValue("inbound.ignore.fields", "").split("""\s*,\s*""")
|
||||
).flatten.filterNot(StringUtils.isBlank).toList
|
||||
private lazy val propsOutboundOptionalFields =
|
||||
APIUtil.getPropsValue("outbound.optional.fields", "")
|
||||
.split("""\s*,\s*""").filterNot(StringUtils.isBlank).toList
|
||||
|
||||
private lazy val propsInboundOptionalFields =
|
||||
APIUtil.getPropsValue("inbound.optional.fields", "")
|
||||
.split("""\s*,\s*""").filterNot(StringUtils.isBlank).toList
|
||||
|
||||
private val outboundType = typeOf[TopicTrait]
|
||||
private val inboundType = typeOf[InBoundTrait[_]]
|
||||
|
||||
// keep current process InBound or OutBound instance, avoid dead loop.
|
||||
private val threadLocal = new java.lang.ThreadLocal[Any]
|
||||
|
||||
override def serialize(implicit format: Formats): PartialFunction[Any, json.JValue] = {
|
||||
case x if isInOutBoundType(x) && threadLocal.get() == null =>
|
||||
case x if isOutInboundType(x) && threadLocal.get() == null =>
|
||||
threadLocal.set(x)
|
||||
try{
|
||||
toIgnoreFieldJson(x)
|
||||
@ -61,11 +69,22 @@ object FieldIgnoreSerializer extends Serializer[AnyRef] {
|
||||
def toIgnoreFieldJson(any: Any, tp: universe.Type, ignoreFunc: List[String] => List[String] = Functions.unary)(implicit formats: Formats): JValue = {
|
||||
val TYPE_NAME = tp.typeSymbol.name.decodedName.toString
|
||||
// if props value like this InBoundGetBanks:data.logoUrl, the type name must match current process object type.
|
||||
val filterPropsIgnoreFields = propsConfigIgnoreFields collect {
|
||||
case typedIgnoreRegx(TYPE_NAME, ignorePath) => ignorePath
|
||||
case x => x
|
||||
val filterPropsIgnoreFields: List[String] = {
|
||||
val optionalProps = if (tp <:< outboundType) {
|
||||
this.propsOutboundOptionalFields
|
||||
} else if (tp <:< inboundType) {
|
||||
this.propsInboundOptionalFields
|
||||
} else {
|
||||
Nil
|
||||
}
|
||||
|
||||
optionalProps collect {
|
||||
case typedOptionalPathRegx(TYPE_NAME, ignorePath) => ignorePath
|
||||
case x if !x.contains(':') => x
|
||||
}
|
||||
}
|
||||
val ignoreFieldNames: List[String] = getIgnores(tp) ::: filterPropsIgnoreFields
|
||||
|
||||
val ignoreFieldNames: List[String] = getOptionals(tp) ::: filterPropsIgnoreFields
|
||||
val zson = json.Extraction.decompose(any)
|
||||
ignoreFieldNames match {
|
||||
case Nil => zson
|
||||
@ -73,23 +92,19 @@ object FieldIgnoreSerializer extends Serializer[AnyRef] {
|
||||
}
|
||||
}
|
||||
|
||||
private def isInOutBoundType(any: Any) = {
|
||||
if(ReflectUtils.isObpObject(any)) {
|
||||
val className = any.getClass.getSimpleName
|
||||
className.startsWith("OutBound") || className.startsWith("InBound")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
private def isOutInboundType(any: Any) = {
|
||||
val typeName = any.getClass.getSimpleName
|
||||
ReflectUtils.isObpObject(any) && (typeName.startsWith("OutBound") || typeName.startsWith("InBound"))
|
||||
}
|
||||
|
||||
def getIgnores(tp: universe.Type): List[String] = {
|
||||
def getOptionals(tp: universe.Type): List[String] = {
|
||||
if(!ReflectUtils.isObpType(tp)) {
|
||||
return Nil
|
||||
}
|
||||
memo.memoize(tp){
|
||||
val fields: List[universe.Symbol] = tp.decls.filter(decl => decl.isTerm && (decl.asTerm.isVal || decl.asTerm.isVar)).toList
|
||||
val (ignoreFields, notIgnoreFields) = fields.partition(_.annotations.exists(_.tree.tpe <:< typeOf[ignore]))
|
||||
val annotedFieldNames = ignoreFields.map(_.name.decodedName.toString.trim)
|
||||
val (optionalFields, notIgnoreFields) = fields.partition(_.annotations.exists(_.tree.tpe <:< typeOf[optional]))
|
||||
val annotedFieldNames = optionalFields.map(_.name.decodedName.toString.trim)
|
||||
val subAnnotedFieldNames = notIgnoreFields.flatMap(it => {
|
||||
val fieldName = it.name.decodedName.toString.trim
|
||||
val fieldType: universe.Type = it.info match {
|
||||
@ -100,7 +115,7 @@ object FieldIgnoreSerializer extends Serializer[AnyRef] {
|
||||
case x => x
|
||||
}
|
||||
|
||||
getIgnores(fieldType)
|
||||
getOptionals(fieldType)
|
||||
.map(it => s"$fieldName.$it")
|
||||
})
|
||||
annotedFieldNames ++ subAnnotedFieldNames
|
||||
|
||||
@ -29,7 +29,7 @@ package code.api.v2_2_0
|
||||
import java.util.Date
|
||||
|
||||
import code.actorsystem.ObpActorConfig
|
||||
import code.api.util.{APIUtil, ApiPropsWithAlias, CustomJsonFormats, FieldIgnoreSerializer}
|
||||
import code.api.util.{APIUtil, ApiPropsWithAlias, CustomJsonFormats, OptionalFieldSerializer}
|
||||
import code.api.util.APIUtil.{EndpointInfo, MessageDoc, getPropsValue}
|
||||
import code.api.v1_2_1.BankRoutingJsonV121
|
||||
import com.openbankproject.commons.model.{AccountRoutingJsonV121, AmountOfMoneyJsonV121}
|
||||
@ -846,7 +846,7 @@ object JSONFactory220 {
|
||||
MessageDocsJson(messageDocsList.map(createMessageDocJson))
|
||||
}
|
||||
|
||||
private implicit val formats = CustomJsonFormats.formats + FieldIgnoreSerializer
|
||||
private implicit val formats = CustomJsonFormats.formats + OptionalFieldSerializer
|
||||
|
||||
def createMessageDocJson(md: MessageDoc): MessageDocJson = {
|
||||
val inBoundType = ReflectUtils.getType(md.exampleInboundMessage)
|
||||
|
||||
@ -27,7 +27,7 @@ import scala.reflect.runtime.{universe => ru}
|
||||
object ConnectorEndpoints extends RestHelper{
|
||||
|
||||
def registerConnectorEndpoints = {
|
||||
oauthServe(connectorGetMethod)
|
||||
oauthServe(connectorEndpoints)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,13 +40,13 @@ object ConnectorEndpoints extends RestHelper{
|
||||
else None
|
||||
}
|
||||
|
||||
lazy val connectorGetMethod: OBPEndpoint = {
|
||||
lazy val connectorEndpoints: OBPEndpoint = {
|
||||
case "connector" :: methodName :: Nil JsonAny json -> req if(hashMethod(methodName, json)) => {
|
||||
cc => {
|
||||
val methodSymbol: ru.MethodSymbol = getMethod(methodName, json).get
|
||||
val outBoundType = Class.forName(s"com.openbankproject.commons.dto.OutBound${methodName.capitalize}")
|
||||
val mf = ManifestFactory.classType[TopicTrait](outBoundType)
|
||||
val formats = CustomJsonFormats.formats
|
||||
val formats = CustomJsonFormats.nullTolerateFormats
|
||||
val outBound = json.extract[TopicTrait](formats, mf)
|
||||
val optionCC = Option(cc)
|
||||
|
||||
@ -174,8 +174,8 @@ object ConnectorEndpoints extends RestHelper{
|
||||
val (mName, paramNames, _, _, isParamOption) = quadruple
|
||||
mName == methodName && paramNames.forall(paramName => isParamOption(paramName) || (json \ paramName) != JNothing)
|
||||
}
|
||||
.sortBy(_._2.size)
|
||||
.lastOption
|
||||
.sortBy(_._2.size)
|
||||
.lastOption
|
||||
.map(_._3)
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ package code.bankconnectors
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
import code.api.util.{CallContext, CustomJsonFormats, FieldIgnoreSerializer, OBPQueryParam}
|
||||
import code.api.util.{CallContext, CustomJsonFormats, OptionalFieldSerializer, OBPQueryParam}
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.dto.{InBoundTrait, OutInBoundTransfer}
|
||||
import com.openbankproject.commons.model.TopicTrait
|
||||
@ -56,7 +56,7 @@ object ConnectorUtils {
|
||||
def processIgnoreFields(fields: List[String]): List[String] = fields.collect {
|
||||
case x if x.startsWith("data.") => StringUtils.substringAfter(x, "data.")
|
||||
}
|
||||
val zson = FieldIgnoreSerializer.toIgnoreFieldJson(obj, ReflectUtils.classToType(inBoundClass), processIgnoreFields)
|
||||
val zson = OptionalFieldSerializer.toIgnoreFieldJson(obj, ReflectUtils.classToType(inBoundClass), processIgnoreFields)
|
||||
|
||||
val jObj: JValue = "data" -> zson
|
||||
|
||||
@ -64,64 +64,65 @@ object ConnectorUtils {
|
||||
jObj.extract[InBoundTrait[Any]](formats, mainFest).data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lazy val outInboundTransferLocalMapped: OutInBoundTransfer = new OutInBoundTransfer{
|
||||
private val ConnectorMethodRegex = "(?i)OutBound(.)(.+)".r
|
||||
private val connector:Connector = LocalMappedConnector
|
||||
private val queryParamType = universe.typeOf[List[OBPQueryParam]]
|
||||
private val callContextType = universe.typeOf[Option[CallContext]]
|
||||
private implicit val formats = CustomJsonFormats.nullTolerateFormats
|
||||
object LocalMappedOutInBoundTransfer extends OutInBoundTransfer {
|
||||
private val ConnectorMethodRegex = "(?i)OutBound(.)(.+)".r
|
||||
private lazy val connector: Connector = LocalMappedConnector
|
||||
private val queryParamType = universe.typeOf[List[OBPQueryParam]]
|
||||
private val callContextType = universe.typeOf[Option[CallContext]]
|
||||
private implicit val formats = CustomJsonFormats.nullTolerateFormats
|
||||
|
||||
override def transfer(outbound: TopicTrait): Future[InBoundTrait[_]] = {
|
||||
val connectorMethod: String = outbound.getClass.getSimpleName match {
|
||||
case ConnectorMethodRegex(x, y) => s"${x.toLowerCase()}$y"
|
||||
case x => x
|
||||
}
|
||||
implicit val inboundMainFest = ManifestFactory.classType[InBoundTrait[_]](Class.forName(s"com.openbankproject.commons.dto.OutBound${connectorMethod.capitalize}"))
|
||||
|
||||
connector.implementedMethods.get(connectorMethod) match {
|
||||
case None => Future.failed(new IllegalArgumentException(s"Outbound instance $outbound have no corresponding method in the ${connector.getClass.getSimpleName}"))
|
||||
case Some(method) =>
|
||||
val nameToValue = outbound.nameToValue.toMap
|
||||
val argNameToType: List[(String, universe.Type)] = method.paramLists.head.map(it => it.name.decodedName.toString.trim -> it.info)
|
||||
val connectorMethodArgs: List[Any] = argNameToType collect {
|
||||
case (_, tp) if tp <:< callContextType => None // For connector method parameter `callContext: Option[CallContext]`, just pass None
|
||||
case (_, tp) if tp <:< queryParamType =>
|
||||
val limit = nameToValue("limit").asInstanceOf[Int]
|
||||
val offset = nameToValue("offset").asInstanceOf[Int]
|
||||
val fromDate = nameToValue("fromDate").asInstanceOf[String]
|
||||
val toDate = nameToValue("toDate").asInstanceOf[String]
|
||||
val queryParams: List[OBPQueryParam] = OBPQueryParam.toOBPQueryParams(limit, offset, fromDate, toDate)
|
||||
queryParams
|
||||
case (name, _) => nameToValue(name)
|
||||
}
|
||||
|
||||
val connectorResult = ReflectUtils.invokeMethod(connector, method, connectorMethodArgs: _*)
|
||||
val futureResult: Future[_] = transferConnectorResult(connectorResult)
|
||||
futureResult.asInstanceOf[Future[InBoundTrait[_]]]
|
||||
}
|
||||
override def transfer(outbound: TopicTrait): Future[InBoundTrait[_]] = {
|
||||
val connectorMethod: String = outbound.getClass.getSimpleName match {
|
||||
case ConnectorMethodRegex(x, y) => s"${x.toLowerCase()}$y"
|
||||
case x => x
|
||||
}
|
||||
val clazz = Class.forName(s"com.openbankproject.commons.dto.InBound${connectorMethod.capitalize}")
|
||||
implicit val inboundMainFest: Manifest[InBoundTrait[_]] = ManifestFactory.classType[InBoundTrait[_]](clazz)
|
||||
|
||||
private def transferConnectorResult(any: Any)(implicit inboundMainFest: Manifest[Any]): Future[_] = any match {
|
||||
case x: Future[_] => x.map { it =>
|
||||
val dataJson = json.Extraction.decompose(getData(it))
|
||||
val inboundJson: JObject = "data" -> dataJson
|
||||
inboundJson.extract[Any](formats, inboundMainFest)
|
||||
}
|
||||
case x =>
|
||||
Future{
|
||||
val dataJson = json.Extraction.decompose(getData(x))
|
||||
val inboundJson: JObject = "data" -> dataJson
|
||||
inboundJson.extract[Any](formats, inboundMainFest)
|
||||
connector.implementedMethods.get(connectorMethod) match {
|
||||
case None => Future.failed(new IllegalArgumentException(s"Outbound instance $outbound have no corresponding method in the ${connector.getClass.getSimpleName}"))
|
||||
case Some(method) =>
|
||||
val nameToValue = outbound.nameToValue.toMap
|
||||
val argNameToType: List[(String, universe.Type)] = method.paramLists.head.map(it => it.name.decodedName.toString.trim -> it.info)
|
||||
val connectorMethodArgs: List[Any] = argNameToType collect {
|
||||
case (_, tp) if tp <:< callContextType => None // For connector method parameter `callContext: Option[CallContext]`, just pass None
|
||||
case (_, tp) if tp <:< queryParamType =>
|
||||
val limit = nameToValue("limit").asInstanceOf[Int]
|
||||
val offset = nameToValue("offset").asInstanceOf[Int]
|
||||
val fromDate = nameToValue("fromDate").asInstanceOf[String]
|
||||
val toDate = nameToValue("toDate").asInstanceOf[String]
|
||||
val queryParams: List[OBPQueryParam] = OBPQueryParam.toOBPQueryParams(limit, offset, fromDate, toDate)
|
||||
queryParams
|
||||
case (name, _) => nameToValue(name)
|
||||
}
|
||||
}
|
||||
// connector methods return different type value, this method just extract value for InboundXX#data
|
||||
private def getData(any: Any): Any = any match {
|
||||
case (Full(v), _: Option[CallContext]) => v
|
||||
case (v, _: Option[CallContext]) => v
|
||||
case Full((v, _: Option[CallContext])) => v
|
||||
case Full(v) => v
|
||||
case v => v
|
||||
|
||||
val connectorResult = ReflectUtils.invokeMethod(connector, method, connectorMethodArgs: _*)
|
||||
val futureResult: Future[InBoundTrait[_]] = transferConnectorResult(connectorResult)
|
||||
futureResult
|
||||
}
|
||||
}
|
||||
|
||||
private def transferConnectorResult(any: Any)(implicit inboundMainFest: Manifest[InBoundTrait[_]]): Future[InBoundTrait[_]] = any match {
|
||||
case x: Future[_] => x.map { it =>
|
||||
val dataJson = json.Extraction.decompose(getData(it))
|
||||
val inboundJson: JObject = "data" -> dataJson
|
||||
inboundJson.extract[InBoundTrait[_]](formats, inboundMainFest)
|
||||
}
|
||||
case x =>
|
||||
Future{
|
||||
val dataJson = json.Extraction.decompose(getData(x))
|
||||
val inboundJson: JObject = "data" -> dataJson
|
||||
inboundJson.extract[InBoundTrait[_]](formats, inboundMainFest)
|
||||
}
|
||||
}
|
||||
// connector methods return different type value, this method just extract value for InboundXX#data
|
||||
private def getData(any: Any): Any = any match {
|
||||
case (Full(v), _: Option[CallContext]) => v
|
||||
case (v, _: Option[CallContext]) => v
|
||||
case Full((v, _: Option[CallContext])) => v
|
||||
case Full(v) => v
|
||||
case v => v
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import java.util.{Date, TimeZone}
|
||||
import code.api.ResourceDocs1_4_0.MessageDocsSwaggerDefinitions.successStatus
|
||||
import code.api.util.APIUtil.MessageDoc
|
||||
import code.api.util.CustomJsonFormats.formats
|
||||
import code.api.util.{APIUtil, FieldIgnoreSerializer}
|
||||
import code.api.util.{APIUtil, OptionalFieldSerializer}
|
||||
import code.bankconnectors.ConnectorBuilderUtil._
|
||||
import com.openbankproject.commons.model.Status
|
||||
import com.openbankproject.commons.util.Functions
|
||||
@ -36,7 +36,7 @@ object MSsqlStoredProcedureBuilder {
|
||||
// Boot.scala set default TimeZone, So here need also fix the TimeZone to make example Date is a fix value,
|
||||
// not affect by local TimeZone.
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
|
||||
implicit val customFormats = formats + StatusSerializer + FieldIgnoreSerializer
|
||||
implicit val customFormats = formats + StatusSerializer + OptionalFieldSerializer
|
||||
val messageDocs: ArrayBuffer[MessageDoc] = StoredProcedureConnector_vDec2019.messageDocs
|
||||
def toProcedureName(processName: String) = StringHelpers.snakify(processName.replace("obp.", "obp_"))
|
||||
def toJson(any: Any) = json.prettyRender(json.Extraction.decompose(any))
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<groupId>com.tesobe</groupId>
|
||||
<artifactId>obp-parent</artifactId>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<version>1.6.1</version>
|
||||
<version>1.6.2</version>
|
||||
</parent>
|
||||
<artifactId>obp-commons</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@ -28,7 +28,7 @@ package com.openbankproject.commons.model
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import com.openbankproject.commons.util.{OBPRequired, ignore}
|
||||
import com.openbankproject.commons.util.{OBPRequired, optional}
|
||||
|
||||
import scala.collection.immutable.List
|
||||
import scala.math.BigDecimal
|
||||
@ -183,10 +183,10 @@ trait BankAccount{
|
||||
def currency : String
|
||||
def name : String // Is this used? -->It is used for BerlinGroup V1.3, it has the name in account response.
|
||||
// `Name of the account given by the bank or the PSU in online-banking.`
|
||||
@ignore
|
||||
@optional
|
||||
def label: String
|
||||
@deprecated("We should use accountRoutings instead")
|
||||
@ignore
|
||||
@optional
|
||||
def iban : Option[String]
|
||||
def number : String
|
||||
def bankId : BankId
|
||||
@ -194,16 +194,16 @@ trait BankAccount{
|
||||
def lastUpdate : Date
|
||||
def branchId: String
|
||||
@deprecated("We should use accountRoutings instead")
|
||||
@ignore
|
||||
@optional
|
||||
def accountRoutingScheme: String
|
||||
@deprecated("We should use accountRoutings instead")
|
||||
@ignore
|
||||
@optional
|
||||
def accountRoutingAddress: String
|
||||
def accountRoutings: List[AccountRouting] // Introduced in v3.0.0
|
||||
@ignore
|
||||
@optional
|
||||
def accountRules: List[AccountRule]
|
||||
@deprecated("Get the account holder(s) via owners")
|
||||
@ignore
|
||||
@optional
|
||||
def accountHolder : String
|
||||
//This field is really special, it used for OBP side to distinguish the different accounts from the core baning side.
|
||||
//Because of in OBP side, we just have one account table, no difference for different types of accounts.
|
||||
@ -244,7 +244,7 @@ as see from the perspective of the original party.
|
||||
case class Counterparty(
|
||||
|
||||
@deprecated("older version, please first consider the V210, account scheme and address","05/05/2017")
|
||||
@ignore
|
||||
@optional
|
||||
val nationalIdentifier: String, // This is the scheme a consumer would use to instruct a payment e.g. IBAN
|
||||
val kind: String, // Type of bank account.
|
||||
|
||||
@ -253,15 +253,15 @@ case class Counterparty(
|
||||
val counterpartyName: String,
|
||||
val thisBankId: BankId, // i.e. the Account that sends/receives money to/from this Counterparty
|
||||
val thisAccountId: AccountId, // These 2 fields specify the account that uses this Counterparty
|
||||
@ignore
|
||||
@optional
|
||||
val otherBankRoutingScheme: String, // This is the scheme a consumer would use to specify the bank e.g. BIC
|
||||
@ignore
|
||||
@optional
|
||||
val otherBankRoutingAddress: Option[String], // The (BIC) value e.g. 67895
|
||||
@ignore
|
||||
@optional
|
||||
val otherAccountRoutingScheme: String, // This is the scheme a consumer would use to instruct a payment e.g. IBAN
|
||||
@ignore
|
||||
@optional
|
||||
val otherAccountRoutingAddress: Option[String], // The (IBAN) value e.g. 2349870987820374
|
||||
@ignore
|
||||
@optional
|
||||
val otherAccountProvider: String, // hasBankId and hasAccountId would refer to an OBP account
|
||||
val isBeneficiary: Boolean // True if the originAccount can send money to the Counterparty
|
||||
)
|
||||
|
||||
@ -29,10 +29,9 @@ package com.openbankproject.commons.model
|
||||
import java.util.Date
|
||||
|
||||
import com.openbankproject.commons.model.enums._
|
||||
import com.openbankproject.commons.util.{JsonAble, ReflectUtils, ignore}
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json.{Formats, JInt, JString}
|
||||
import com.openbankproject.commons.util.{ReflectUtils, optional}
|
||||
import net.liftweb.json.JsonAST.{JObject, JValue}
|
||||
import net.liftweb.json.{JInt, JString}
|
||||
|
||||
import scala.collection.immutable.List
|
||||
import scala.reflect.runtime.universe._
|
||||
@ -119,22 +118,22 @@ case class BankAccountCommons(
|
||||
balance :BigDecimal,
|
||||
currency :String,
|
||||
name :String,
|
||||
@ignore
|
||||
@optional
|
||||
label :String,
|
||||
@ignore
|
||||
@optional
|
||||
iban :Option[String],
|
||||
number :String,
|
||||
bankId :BankId,
|
||||
lastUpdate :Date,
|
||||
branchId :String,
|
||||
@ignore
|
||||
@optional
|
||||
accountRoutingScheme :String,
|
||||
@ignore
|
||||
@optional
|
||||
accountRoutingAddress :String,
|
||||
accountRoutings :List[AccountRouting],
|
||||
@ignore
|
||||
@optional
|
||||
accountRules :List[AccountRule],
|
||||
@ignore
|
||||
@optional
|
||||
accountHolder :String,
|
||||
override val queryTags : Option[List[String]] = None) extends BankAccount
|
||||
|
||||
@ -193,31 +192,31 @@ object CustomerAddressCommons extends Converter[CustomerAddress, CustomerAddress
|
||||
//It will get the bankId, accountId and viewsToGenerate to create the OBP side data, such as views, accountHolder.
|
||||
case class InboundAccountCommons(
|
||||
bankId :String,
|
||||
@ignore
|
||||
@optional
|
||||
branchId :String,
|
||||
accountId :String,
|
||||
@ignore
|
||||
@optional
|
||||
accountNumber :String,
|
||||
@ignore
|
||||
@optional
|
||||
accountType :String,
|
||||
@ignore
|
||||
@optional
|
||||
balanceAmount :String,
|
||||
@ignore
|
||||
@optional
|
||||
balanceCurrency :String,
|
||||
@ignore
|
||||
@optional
|
||||
owners :List[String],
|
||||
viewsToGenerate :List[String],
|
||||
@ignore
|
||||
@optional
|
||||
bankRoutingScheme :String,
|
||||
@ignore
|
||||
@optional
|
||||
bankRoutingAddress :String,
|
||||
@ignore
|
||||
@optional
|
||||
branchRoutingScheme :String,
|
||||
@ignore
|
||||
@optional
|
||||
branchRoutingAddress :String,
|
||||
@ignore
|
||||
@optional
|
||||
accountRoutingScheme :String,
|
||||
@ignore
|
||||
@optional
|
||||
accountRoutingAddress :String) extends InboundAccount
|
||||
|
||||
object InboundAccountCommons extends Converter[InboundAccount, InboundAccountCommons]
|
||||
@ -268,9 +267,9 @@ case class BankCommons(
|
||||
websiteUrl :String,
|
||||
bankRoutingScheme :String,
|
||||
bankRoutingAddress :String,
|
||||
@ignore
|
||||
@optional
|
||||
swiftBic :String,
|
||||
@ignore
|
||||
@optional
|
||||
nationalIdentifier :String) extends Bank {
|
||||
def this(bankId :BankId,
|
||||
shortName :String,
|
||||
@ -636,19 +635,19 @@ case class SepaCreditTransfers( //This is from berlinGroup
|
||||
)
|
||||
|
||||
case class TransactionRequestBodyAllTypes (
|
||||
@ignore
|
||||
@optional
|
||||
to_sandbox_tan: Option[TransactionRequestAccount],
|
||||
@ignore
|
||||
@optional
|
||||
to_sepa: Option[TransactionRequestIban],
|
||||
@ignore
|
||||
@optional
|
||||
to_counterparty: Option[TransactionRequestCounterpartyId],
|
||||
@ignore
|
||||
@optional
|
||||
to_transfer_to_phone: Option[TransactionRequestTransferToPhone] = None, //TODO not stable
|
||||
@ignore
|
||||
@optional
|
||||
to_transfer_to_atm: Option[TransactionRequestTransferToAtm]= None,//TODO not stable
|
||||
@ignore
|
||||
@optional
|
||||
to_transfer_to_account: Option[TransactionRequestTransferToAccount]= None,//TODO not stable
|
||||
@ignore
|
||||
@optional
|
||||
to_sepa_credit_transfers: Option[SepaCreditTransfers]= None,//TODO not stable, from berlin Group
|
||||
|
||||
value: AmountOfMoney,
|
||||
@ -676,29 +675,29 @@ case class TransactionRequest (
|
||||
end_date: Date,
|
||||
challenge: TransactionRequestChallenge,
|
||||
charge: TransactionRequestCharge,
|
||||
@ignore
|
||||
@optional
|
||||
charge_policy: String,
|
||||
@ignore
|
||||
@optional
|
||||
counterparty_id :CounterpartyId,
|
||||
@ignore
|
||||
@optional
|
||||
name :String,
|
||||
@ignore
|
||||
@optional
|
||||
this_bank_id : BankId,
|
||||
@ignore
|
||||
@optional
|
||||
this_account_id : AccountId,
|
||||
@ignore
|
||||
@optional
|
||||
this_view_id :ViewId,
|
||||
@ignore
|
||||
@optional
|
||||
other_account_routing_scheme : String,
|
||||
@ignore
|
||||
@optional
|
||||
other_account_routing_address : String,
|
||||
@ignore
|
||||
@optional
|
||||
other_bank_routing_scheme : String,
|
||||
@ignore
|
||||
@optional
|
||||
other_bank_routing_address : String,
|
||||
@ignore
|
||||
@optional
|
||||
is_beneficiary :Boolean,
|
||||
@ignore
|
||||
@optional
|
||||
future_date :Option[String] = None
|
||||
)
|
||||
case class TransactionRequestBody (
|
||||
@ -709,7 +708,7 @@ case class TransactionRequestBody (
|
||||
|
||||
case class Transaction(
|
||||
//A universally unique id
|
||||
@ignore
|
||||
@optional
|
||||
uuid: String,
|
||||
//id is unique for transactions of @thisAccount
|
||||
id : TransactionId,
|
||||
|
||||
@ -184,7 +184,7 @@ object FiledRenameSerializer extends Serializer[JsonFieldReName] {
|
||||
|
||||
def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
|
||||
case x: JsonFieldReName => {
|
||||
val ignoreFieldNames = getObjAnnotedFields(x, ru.typeOf[ignore])
|
||||
val ignoreFieldNames = getObjAnnotedFields(x, ru.typeOf[optional])
|
||||
val renamedJFields = ReflectUtils.getConstructorArgs(x)
|
||||
.filter(pair => !ignoreFieldNames.contains(pair._1))
|
||||
.map(pair => {
|
||||
@ -442,10 +442,6 @@ object MapperSerializer extends Serializer[Mapper[_]] {
|
||||
override def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, json.JValue), Mapper[_]] = Functions.doNothing
|
||||
}
|
||||
|
||||
@scala.annotation.meta.field
|
||||
@scala.annotation.meta.param
|
||||
class ignore extends scala.annotation.StaticAnnotation
|
||||
|
||||
@scala.annotation.meta.field
|
||||
@scala.annotation.meta.param
|
||||
class optional extends scala.annotation.StaticAnnotation
|
||||
Loading…
Reference in New Issue
Block a user