From 2d422db5de491bcd08cfa061c3f46023e93bdb38 Mon Sep 17 00:00:00 2001 From: hongwei Date: Mon, 4 Dec 2023 12:45:15 +0100 Subject: [PATCH 1/9] refactor/remove the basicUrlValidation, use basicUriAndQueryStringValidation stead --- obp-api/src/main/scala/code/api/util/APIUtil.scala | 14 -------------- obp-api/src/main/scala/code/util/Helper.scala | 2 +- obp-api/src/test/scala/code/util/APIUtilTest.scala | 10 +++++++--- obp-api/src/test/scala/code/util/HelperTest.scala | 4 ++++ 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/obp-api/src/main/scala/code/api/util/APIUtil.scala b/obp-api/src/main/scala/code/api/util/APIUtil.scala index 4bf30c681..239e2fb3a 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -777,20 +777,6 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ } } - def basicUrlValidation(urlString: String): Boolean = { - //in scala test - org.scalatest.FeatureSpecLike.scenario: - // redirectUrl = http%3A%2F%2Flocalhost%3A8016%3Foauth_token%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461 - // URLDecoder.decode(urlString,"UTF-8")-->http://localhost:8016?oauth_token=EBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK&oauth_verifier=63461 - val regex = - """((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_\/]*)#?(?:[\w]*))?)""".r - val decodeUrlValue = URLDecoder.decode(urlString, "UTF-8").trim() - decodeUrlValue match { - case regex(_*) if (decodeUrlValue.length <= 2048) => true - case _ => false - } - } - - /** only A-Z, a-z, 0-9,-,_,. =, & and max length <= 2048 */ def basicUriAndQueryStringValidation(urlString: String): Boolean = { val regex = diff --git a/obp-api/src/main/scala/code/util/Helper.scala b/obp-api/src/main/scala/code/util/Helper.scala index 15c12c894..ddc6bb13a 100644 --- a/obp-api/src/main/scala/code/util/Helper.scala +++ b/obp-api/src/main/scala/code/util/Helper.scala @@ -461,7 +461,7 @@ object Helper extends Loggable { }else if((args.length>0) && args.apply(0).toString.equalsIgnoreCase("consumer_key")){ result.asInstanceOf[Box[String]].filter(APIUtil.basicConsumerKeyValidation(_)==SILENCE_IS_GOLDEN) }else if((args.length>0) && args.apply(0).toString.equalsIgnoreCase("redirectUrl")){ - result.asInstanceOf[Box[String]].filter(APIUtil.basicUrlValidation(_)) + result.asInstanceOf[Box[String]].filter(APIUtil.basicUriAndQueryStringValidation(_)) } else{ result.asInstanceOf[Box[String]].filter(APIUtil.checkMediumString(_)==SILENCE_IS_GOLDEN) } diff --git a/obp-api/src/test/scala/code/util/APIUtilTest.scala b/obp-api/src/test/scala/code/util/APIUtilTest.scala index 44b354495..fbe2d0359 100644 --- a/obp-api/src/test/scala/code/util/APIUtilTest.scala +++ b/obp-api/src/test/scala/code/util/APIUtilTest.scala @@ -698,12 +698,16 @@ class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with Prop APIUtil.getObpFormatOperationId("xxx") should be ("xxx") } - feature("test APIUtil.basicUrlValidation method") { + feature("test APIUtil.basicUriAndQueryStringValidation method") { val testString1 = "https%3A%2F%2Fapisandbox.openbankproject.com%2Foauth%2Fauthorize%3Fnext%3D%2Fen%2Fusers%2Fmyuser%26oauth_token%3DWTOBT2YRCTMI1BCCF4XAIKRXPLLZDZPFAIL5K03Z%26oauth_verifier%3D45381" val testString2 = "http%3A%2F%2Flocalhost%3A8016%3Foauth_token%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" + val testString3 = "myapp://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" + val testString4 = "fb00000000:://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" - APIUtil.basicUrlValidation(testString1) should be (true) - APIUtil.basicUrlValidation(testString2) should be (true) + APIUtil.basicUriAndQueryStringValidation(testString1) should be (true) + APIUtil.basicUriAndQueryStringValidation(testString2) should be (true) + APIUtil.basicUriAndQueryStringValidation(testString3) should be (true) + APIUtil.basicUriAndQueryStringValidation(testString4) should be (true) } diff --git a/obp-api/src/test/scala/code/util/HelperTest.scala b/obp-api/src/test/scala/code/util/HelperTest.scala index eaad59c97..452d9a59c 100644 --- a/obp-api/src/test/scala/code/util/HelperTest.scala +++ b/obp-api/src/test/scala/code/util/HelperTest.scala @@ -38,9 +38,13 @@ class HelperTest extends FeatureSpec with Matchers with GivenWhenThen with Props feature("test APIUtil.basicUrlValidation method") { val testString1 = "http://localhost:8082/oauthcallback?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" val testString2 = "http://localhost:8082?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" + val testString3 = "myapp://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" + val testString4 = "fb00000000:://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" Helper.extractCleanRedirectURL(testString1).head should be("http://localhost:8082/oauthcallback") Helper.extractCleanRedirectURL(testString2).head should be("http://localhost:8082") + Helper.extractCleanRedirectURL(testString3).head should be("myapp://callback") + Helper.extractCleanRedirectURL(testString4).head should be("fb00000000:://callback") } From f6b83f130a6a533995ea14cd75251cd612a4cbe5 Mon Sep 17 00:00:00 2001 From: hongwei Date: Mon, 4 Dec 2023 13:12:01 +0100 Subject: [PATCH 2/9] refactor/remove the basicUrlValidation, use basicUriAndQueryStringValidation stead - step2 --- obp-api/src/main/scala/code/util/Helper.scala | 2 +- obp-api/src/test/scala/code/util/APIUtilTest.scala | 2 ++ obp-api/src/test/scala/code/util/HelperTest.scala | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/obp-api/src/main/scala/code/util/Helper.scala b/obp-api/src/main/scala/code/util/Helper.scala index ddc6bb13a..f6492a545 100644 --- a/obp-api/src/main/scala/code/util/Helper.scala +++ b/obp-api/src/main/scala/code/util/Helper.scala @@ -168,7 +168,7 @@ object Helper extends Loggable { } def extractCleanRedirectURL(input: String): Box[String] = { - Full(input.split("\\?oauth_token=")(0)) + Full(input.split("\\?")(0)) } /** diff --git a/obp-api/src/test/scala/code/util/APIUtilTest.scala b/obp-api/src/test/scala/code/util/APIUtilTest.scala index fbe2d0359..450def8dc 100644 --- a/obp-api/src/test/scala/code/util/APIUtilTest.scala +++ b/obp-api/src/test/scala/code/util/APIUtilTest.scala @@ -703,11 +703,13 @@ class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with Prop val testString2 = "http%3A%2F%2Flocalhost%3A8016%3Foauth_token%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" val testString3 = "myapp://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" val testString4 = "fb00000000:://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" + val testString5 = "http://127.0.0.1:8000/oauth/authorize?next=/en/metrics/api/&oauth_token=TN0124OCPRCL4KUJRF5LNLVMRNHTVZPJDBS2PNWU&oauth_verifier=10470" APIUtil.basicUriAndQueryStringValidation(testString1) should be (true) APIUtil.basicUriAndQueryStringValidation(testString2) should be (true) APIUtil.basicUriAndQueryStringValidation(testString3) should be (true) APIUtil.basicUriAndQueryStringValidation(testString4) should be (true) + APIUtil.basicUriAndQueryStringValidation(testString5) should be (true) } diff --git a/obp-api/src/test/scala/code/util/HelperTest.scala b/obp-api/src/test/scala/code/util/HelperTest.scala index 452d9a59c..d3f7472ce 100644 --- a/obp-api/src/test/scala/code/util/HelperTest.scala +++ b/obp-api/src/test/scala/code/util/HelperTest.scala @@ -40,12 +40,13 @@ class HelperTest extends FeatureSpec with Matchers with GivenWhenThen with Props val testString2 = "http://localhost:8082?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" val testString3 = "myapp://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" val testString4 = "fb00000000:://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" + val testString5 = "http://127.0.0.1:8000/oauth/authorize?next=/en/metrics/api/&oauth_token=TN0124OCPRCL4KUJRF5LNLVMRNHTVZPJDBS2PNWU&oauth_verifier=10470" Helper.extractCleanRedirectURL(testString1).head should be("http://localhost:8082/oauthcallback") Helper.extractCleanRedirectURL(testString2).head should be("http://localhost:8082") Helper.extractCleanRedirectURL(testString3).head should be("myapp://callback") Helper.extractCleanRedirectURL(testString4).head should be("fb00000000:://callback") - + Helper.extractCleanRedirectURL(testString5).head should be("http://127.0.0.1:8000/oauth/authorize") } } \ No newline at end of file From ffee2c118f67ba3dcb01a0d0b6d778ebda19e8ed Mon Sep 17 00:00:00 2001 From: hongwei Date: Mon, 4 Dec 2023 17:30:36 +0100 Subject: [PATCH 3/9] refactor/rename extractCleanRedirectURL to getStaticPortionOfRedirectURL --- .../main/scala/code/snippet/OAuthWorkedThanks.scala | 2 +- obp-api/src/main/scala/code/util/Helper.scala | 10 ++++++++-- obp-api/src/test/scala/code/util/HelperTest.scala | 13 +++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala b/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala index 982b4a4dc..e6a5e307b 100644 --- a/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala +++ b/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala @@ -48,7 +48,7 @@ class OAuthWorkedThanks extends MdcLoggable { val redirectUrl = ObpS.param("redirectUrl").map(urlDecode(_)) logger.debug(s"OAuthWorkedThanks.thanks.redirectUrl $redirectUrl") //extract the clean(omit the parameters) redirect url from request url - val requestedRedirectURL = Helper.extractCleanRedirectURL(redirectUrl.openOr("invalidRequestedRedirectURL")) openOr("invalidRequestedRedirectURL") + val requestedRedirectURL = Helper.getStaticPortionOfRedirectURL(redirectUrl.openOr("invalidRequestedRedirectURL")) openOr("invalidRequestedRedirectURL") logger.debug(s"OAuthWorkedThanks.thanks.requestedRedirectURL $requestedRedirectURL") val requestedOauthToken = Helper.extractOauthToken(redirectUrl.openOr("No Oauth Token here")) openOr("No Oauth Token here") diff --git a/obp-api/src/main/scala/code/util/Helper.scala b/obp-api/src/main/scala/code/util/Helper.scala index f6492a545..41f7a1a77 100644 --- a/obp-api/src/main/scala/code/util/Helper.scala +++ b/obp-api/src/main/scala/code/util/Helper.scala @@ -167,8 +167,14 @@ object Helper extends Loggable { prettyRender(decompose(input)) } - def extractCleanRedirectURL(input: String): Box[String] = { - Full(input.split("\\?")(0)) + + /** + * + * @param redirectUrl eg: http://localhost:8082/oauthcallback?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018 + * @return http://localhost:8082/oauthcallback + */ + def getStaticPortionOfRedirectURL(redirectUrl: String): Box[String] = { + Full(redirectUrl.split("\\?")(0)) //return everything before the "?" } /** diff --git a/obp-api/src/test/scala/code/util/HelperTest.scala b/obp-api/src/test/scala/code/util/HelperTest.scala index d3f7472ce..76a265f7d 100644 --- a/obp-api/src/test/scala/code/util/HelperTest.scala +++ b/obp-api/src/test/scala/code/util/HelperTest.scala @@ -35,18 +35,19 @@ import org.scalatest.{FeatureSpec, GivenWhenThen, Matchers} class HelperTest extends FeatureSpec with Matchers with GivenWhenThen with PropsReset { - feature("test APIUtil.basicUrlValidation method") { + feature("test APIUtil.getStaticPortionOfRedirectURL method") { + // The redirectURl is `http://localhost:8082/oauthcallback` val testString1 = "http://localhost:8082/oauthcallback?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" val testString2 = "http://localhost:8082?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" val testString3 = "myapp://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" val testString4 = "fb00000000:://callback?oauth_token=%3DEBRZBMOPDXEUGGJP421FPFGK01IY2DGM5O3TLVSK%26oauth_verifier%3D63461" val testString5 = "http://127.0.0.1:8000/oauth/authorize?next=/en/metrics/api/&oauth_token=TN0124OCPRCL4KUJRF5LNLVMRNHTVZPJDBS2PNWU&oauth_verifier=10470" - Helper.extractCleanRedirectURL(testString1).head should be("http://localhost:8082/oauthcallback") - Helper.extractCleanRedirectURL(testString2).head should be("http://localhost:8082") - Helper.extractCleanRedirectURL(testString3).head should be("myapp://callback") - Helper.extractCleanRedirectURL(testString4).head should be("fb00000000:://callback") - Helper.extractCleanRedirectURL(testString5).head should be("http://127.0.0.1:8000/oauth/authorize") + Helper.getStaticPortionOfRedirectURL(testString1).head should be("http://localhost:8082/oauthcallback") + Helper.getStaticPortionOfRedirectURL(testString2).head should be("http://localhost:8082") + Helper.getStaticPortionOfRedirectURL(testString3).head should be("myapp://callback") + Helper.getStaticPortionOfRedirectURL(testString4).head should be("fb00000000:://callback") + Helper.getStaticPortionOfRedirectURL(testString5).head should be("http://127.0.0.1:8000/oauth/authorize") } } \ No newline at end of file From 5f58e7c6ef897d30adca322e203e2afacfc3891a Mon Sep 17 00:00:00 2001 From: hongwei Date: Tue, 5 Dec 2023 10:19:05 +0100 Subject: [PATCH 4/9] bugfix/supported both staticPortionOfRedirectUrl and hostOnlyOfRedirectUrlLegacy --- .../code/snippet/OAuthWorkedThanks.scala | 15 ++++++------ obp-api/src/main/scala/code/util/Helper.scala | 24 +++++++++++++++++++ .../src/test/scala/code/util/HelperTest.scala | 9 +++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala b/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala index e6a5e307b..59b017efd 100644 --- a/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala +++ b/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala @@ -48,8 +48,10 @@ class OAuthWorkedThanks extends MdcLoggable { val redirectUrl = ObpS.param("redirectUrl").map(urlDecode(_)) logger.debug(s"OAuthWorkedThanks.thanks.redirectUrl $redirectUrl") //extract the clean(omit the parameters) redirect url from request url - val requestedRedirectURL = Helper.getStaticPortionOfRedirectURL(redirectUrl.openOr("invalidRequestedRedirectURL")) openOr("invalidRequestedRedirectURL") - logger.debug(s"OAuthWorkedThanks.thanks.requestedRedirectURL $requestedRedirectURL") + val staticPortionOfRedirectUrl = Helper.getStaticPortionOfRedirectURL(redirectUrl.openOr("invalidRequestedRedirectURL")) openOr("invalidRequestedRedirectURL") + val hostOnlyOfRedirectUrlLegacy = Helper.getHostOnlyOfRedirectURL(redirectUrl.openOr("invalidRequestedRedirectURL")) openOr("invalidRequestedRedirectURL") + logger.debug(s"OAuthWorkedThanks.thanks.staticPortionOfRedirectUrl $staticPortionOfRedirectUrl") + logger.debug(s"OAuthWorkedThanks.thanks.hostOnlyOfRedirectUrlLegacy $hostOnlyOfRedirectUrlLegacy") val requestedOauthToken = Helper.extractOauthToken(redirectUrl.openOr("No Oauth Token here")) openOr("No Oauth Token here") logger.debug(s"OAuthWorkedThanks.thanks.requestedOauthToken $requestedOauthToken") @@ -62,13 +64,10 @@ class OAuthWorkedThanks extends MdcLoggable { redirectUrl match { case Full(url) => - //this redirect url is checked by following, no open redirect issue. - // TODO maybe handle case of extra trailing / on the url ? + val incorrectRedirectUrlMessage = s"The validRedirectURL is $validRedirectURL but the staticPortionOfRedirectUrl was $staticPortionOfRedirectUrl" - val incorrectRedirectUrlMessage = s"The validRedirectURL is $validRedirectURL but the requestedRedirectURL was $requestedRedirectURL" - - - if(validRedirectURL.equals(requestedRedirectURL)) { + //hostOnlyOfRedirectUrlLegacy is deprecated now, we use the staticPortionOfRedirectUrl stead, + if(validRedirectURL.equals(staticPortionOfRedirectUrl)|| validRedirectURL.equals(hostOnlyOfRedirectUrlLegacy)) { "#redirect-link [href]" #> url & ".app-name"#> appName //there may be several places to be modified in html, so here use the class, not the id. }else{ diff --git a/obp-api/src/main/scala/code/util/Helper.scala b/obp-api/src/main/scala/code/util/Helper.scala index 41f7a1a77..a9889d3b2 100644 --- a/obp-api/src/main/scala/code/util/Helper.scala +++ b/obp-api/src/main/scala/code/util/Helper.scala @@ -177,6 +177,30 @@ object Helper extends Loggable { Full(redirectUrl.split("\\?")(0)) //return everything before the "?" } + /** + * extract clean redirect url from input value, because input may have some parameters, such as the following examples
+ * eg1: http://localhost:8082/oauthcallback?....--> http://localhost:8082
+ * eg2: http://localhost:8016?oautallback?=3NLMGV ...--> http://localhost:8016 + * + * @param input a long url with parameters + * @return clean redirect url + */ + @deprecated("We can not only use hostname as the redirectUrl, now add new method `getStaticPortionOfRedirectURL` ","05.12.2023") + def getHostOnlyOfRedirectURL(redirectUrl: String): Box[String] = { + /** + * pattern eg1: http://xxxxxx?oautxxxx -->http://xxxxxx + * pattern eg2: https://xxxxxx/oautxxxx -->http://xxxxxx + */ + //Note: the pattern should be : val pattern = "(https?):\\/\\/(.*)(?=((\\/)|(\\?))oauthcallback*)".r, but the OAuthTest is different, so add the following logic + val pattern = "([A-Za-z][A-Za-z0-9+.-]*):\\/\\/(.*)(?=((\\/)|(\\?))oauth*)".r + val validRedirectURL = pattern findFirstIn redirectUrl + // Now for the OAuthTest, the redirect format is : http://localhost:8016?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018 + // It is not the normal case: http://localhost:8082/oauthcallback?oauth_token=LUDKELGJXRDOC1AK1X1TOYIXM5W1AORFJT5KE43B&oauth_verifier=14062 + // So add the split function to select the first value; eg: Array(http://localhost:8082, thcallback) --> http://localhost:8082 + val extractCleanURL = validRedirectURL.getOrElse("").split("/oauth")(0) + Full(extractCleanURL) + } + /** * extract Oauth Token String from input value, because input may have some parameters, such as the following examples
* http://localhost:8082/oauthcallback?oauth_token=DKR242MB3IRCUVG35UZ0QQOK3MBS1G2HL2ZIKK2O&oauth_verifier=64465 diff --git a/obp-api/src/test/scala/code/util/HelperTest.scala b/obp-api/src/test/scala/code/util/HelperTest.scala index 76a265f7d..deb6cff59 100644 --- a/obp-api/src/test/scala/code/util/HelperTest.scala +++ b/obp-api/src/test/scala/code/util/HelperTest.scala @@ -49,5 +49,14 @@ class HelperTest extends FeatureSpec with Matchers with GivenWhenThen with Props Helper.getStaticPortionOfRedirectURL(testString4).head should be("fb00000000:://callback") Helper.getStaticPortionOfRedirectURL(testString5).head should be("http://127.0.0.1:8000/oauth/authorize") } + + feature("test APIUtil.getHostOnlyOfRedirectURL method") { + // The redirectURl is `http://localhost:8082/oauthcallback` + val testString1 = "http://localhost:8082/oauthcallback?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" + val testString2 = "http://localhost:8082?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" + + Helper.getHostOnlyOfRedirectURL(testString1).head should be("http://localhost:8082") + Helper.getHostOnlyOfRedirectURL(testString2).head should be("http://localhost:8082") + } } \ No newline at end of file From 76a1544c0af33f90a9bc97b540f17116fe14218f Mon Sep 17 00:00:00 2001 From: hongwei Date: Tue, 5 Dec 2023 13:23:12 +0100 Subject: [PATCH 5/9] refactor/tweaked the getHostOnlyOfRedirectURL code --- .../scala/code/snippet/OAuthWorkedThanks.scala | 2 +- obp-api/src/main/scala/code/util/Helper.scala | 14 +++++++------- obp-api/src/test/scala/code/util/HelperTest.scala | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala b/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala index 59b017efd..8b315dbbf 100644 --- a/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala +++ b/obp-api/src/main/scala/code/snippet/OAuthWorkedThanks.scala @@ -49,7 +49,7 @@ class OAuthWorkedThanks extends MdcLoggable { logger.debug(s"OAuthWorkedThanks.thanks.redirectUrl $redirectUrl") //extract the clean(omit the parameters) redirect url from request url val staticPortionOfRedirectUrl = Helper.getStaticPortionOfRedirectURL(redirectUrl.openOr("invalidRequestedRedirectURL")) openOr("invalidRequestedRedirectURL") - val hostOnlyOfRedirectUrlLegacy = Helper.getHostOnlyOfRedirectURL(redirectUrl.openOr("invalidRequestedRedirectURL")) openOr("invalidRequestedRedirectURL") + val hostOnlyOfRedirectUrlLegacy = Helper.getHostOnlyOfRedirectURL(staticPortionOfRedirectUrl) openOr("invalidRequestedRedirectURL") logger.debug(s"OAuthWorkedThanks.thanks.staticPortionOfRedirectUrl $staticPortionOfRedirectUrl") logger.debug(s"OAuthWorkedThanks.thanks.hostOnlyOfRedirectUrlLegacy $hostOnlyOfRedirectUrlLegacy") diff --git a/obp-api/src/main/scala/code/util/Helper.scala b/obp-api/src/main/scala/code/util/Helper.scala index a9889d3b2..f167f4847 100644 --- a/obp-api/src/main/scala/code/util/Helper.scala +++ b/obp-api/src/main/scala/code/util/Helper.scala @@ -3,7 +3,6 @@ package code.util import java.net.{Socket, SocketException} import java.util.UUID.randomUUID import java.util.{Date, GregorianCalendar} - import code.api.util.{APIUtil, CallContext, CallContextLight, CustomJsonFormats} import code.api.{APIFailureNewStyle, Constant} import code.api.util.APIUtil.fullBoxOrException @@ -20,6 +19,7 @@ import com.openbankproject.commons.util.{ReflectUtils, RequiredFieldValidation, import com.tesobe.CacheKeyFromArguments import net.liftweb.http.S import net.liftweb.util.Helpers +import net.liftweb.util.Helpers.tryo import net.sf.cglib.proxy.{Enhancer, MethodInterceptor, MethodProxy} import java.lang.reflect.Method import scala.concurrent.Future @@ -174,7 +174,7 @@ object Helper extends Loggable { * @return http://localhost:8082/oauthcallback */ def getStaticPortionOfRedirectURL(redirectUrl: String): Box[String] = { - Full(redirectUrl.split("\\?")(0)) //return everything before the "?" + tryo(redirectUrl.split("\\?")(0)) //return everything before the "?" } /** @@ -182,23 +182,23 @@ object Helper extends Loggable { * eg1: http://localhost:8082/oauthcallback?....--> http://localhost:8082
* eg2: http://localhost:8016?oautallback?=3NLMGV ...--> http://localhost:8016 * - * @param input a long url with parameters - * @return clean redirect url + * @param redirectUrl -> http://localhost:8082/oauthcallback?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018 + * @return hostOnlyOfRedirectURL-> http://localhost:8082 */ @deprecated("We can not only use hostname as the redirectUrl, now add new method `getStaticPortionOfRedirectURL` ","05.12.2023") def getHostOnlyOfRedirectURL(redirectUrl: String): Box[String] = { + val staticPortionOfRedirectURL = getStaticPortionOfRedirectURL(redirectUrl).getOrElse(redirectUrl) /** * pattern eg1: http://xxxxxx?oautxxxx -->http://xxxxxx * pattern eg2: https://xxxxxx/oautxxxx -->http://xxxxxx */ //Note: the pattern should be : val pattern = "(https?):\\/\\/(.*)(?=((\\/)|(\\?))oauthcallback*)".r, but the OAuthTest is different, so add the following logic val pattern = "([A-Za-z][A-Za-z0-9+.-]*):\\/\\/(.*)(?=((\\/)|(\\?))oauth*)".r - val validRedirectURL = pattern findFirstIn redirectUrl + val validRedirectURL = pattern findFirstIn staticPortionOfRedirectURL // Now for the OAuthTest, the redirect format is : http://localhost:8016?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018 // It is not the normal case: http://localhost:8082/oauthcallback?oauth_token=LUDKELGJXRDOC1AK1X1TOYIXM5W1AORFJT5KE43B&oauth_verifier=14062 // So add the split function to select the first value; eg: Array(http://localhost:8082, thcallback) --> http://localhost:8082 - val extractCleanURL = validRedirectURL.getOrElse("").split("/oauth")(0) - Full(extractCleanURL) + tryo(validRedirectURL.getOrElse("").split("/oauth")(0)) } /** diff --git a/obp-api/src/test/scala/code/util/HelperTest.scala b/obp-api/src/test/scala/code/util/HelperTest.scala index deb6cff59..2e766e37d 100644 --- a/obp-api/src/test/scala/code/util/HelperTest.scala +++ b/obp-api/src/test/scala/code/util/HelperTest.scala @@ -53,10 +53,14 @@ class HelperTest extends FeatureSpec with Matchers with GivenWhenThen with Props feature("test APIUtil.getHostOnlyOfRedirectURL method") { // The redirectURl is `http://localhost:8082/oauthcallback` val testString1 = "http://localhost:8082/oauthcallback?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" - val testString2 = "http://localhost:8082?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" + val testString2 = "http://localhost:8082/oauthcallback" + val testString3 = "http://localhost:8082?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018" + val testString4 = "http://localhost:8082" Helper.getHostOnlyOfRedirectURL(testString1).head should be("http://localhost:8082") Helper.getHostOnlyOfRedirectURL(testString2).head should be("http://localhost:8082") + Helper.getHostOnlyOfRedirectURL(testString3).head should be("http://localhost:8082") + Helper.getHostOnlyOfRedirectURL(testString4).head should be("http://localhost:8082") } } \ No newline at end of file From b8c6e46f0ec7075e5f4386168830956757a21432 Mon Sep 17 00:00:00 2001 From: hongwei Date: Tue, 5 Dec 2023 13:56:58 +0100 Subject: [PATCH 6/9] refactor/use Java URL instead of regular expression --- obp-api/src/main/scala/code/util/Helper.scala | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/obp-api/src/main/scala/code/util/Helper.scala b/obp-api/src/main/scala/code/util/Helper.scala index f167f4847..fa3cd2aa9 100644 --- a/obp-api/src/main/scala/code/util/Helper.scala +++ b/obp-api/src/main/scala/code/util/Helper.scala @@ -1,6 +1,6 @@ package code.util -import java.net.{Socket, SocketException} +import java.net.{Socket, SocketException, URL} import java.util.UUID.randomUUID import java.util.{Date, GregorianCalendar} import code.api.util.{APIUtil, CallContext, CallContextLight, CustomJsonFormats} @@ -21,6 +21,7 @@ import net.liftweb.http.S import net.liftweb.util.Helpers import net.liftweb.util.Helpers.tryo import net.sf.cglib.proxy.{Enhancer, MethodInterceptor, MethodProxy} + import java.lang.reflect.Method import scala.concurrent.Future import scala.util.Random @@ -187,18 +188,10 @@ object Helper extends Loggable { */ @deprecated("We can not only use hostname as the redirectUrl, now add new method `getStaticPortionOfRedirectURL` ","05.12.2023") def getHostOnlyOfRedirectURL(redirectUrl: String): Box[String] = { - val staticPortionOfRedirectURL = getStaticPortionOfRedirectURL(redirectUrl).getOrElse(redirectUrl) - /** - * pattern eg1: http://xxxxxx?oautxxxx -->http://xxxxxx - * pattern eg2: https://xxxxxx/oautxxxx -->http://xxxxxx - */ - //Note: the pattern should be : val pattern = "(https?):\\/\\/(.*)(?=((\\/)|(\\?))oauthcallback*)".r, but the OAuthTest is different, so add the following logic - val pattern = "([A-Za-z][A-Za-z0-9+.-]*):\\/\\/(.*)(?=((\\/)|(\\?))oauth*)".r - val validRedirectURL = pattern findFirstIn staticPortionOfRedirectURL - // Now for the OAuthTest, the redirect format is : http://localhost:8016?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018 - // It is not the normal case: http://localhost:8082/oauthcallback?oauth_token=LUDKELGJXRDOC1AK1X1TOYIXM5W1AORFJT5KE43B&oauth_verifier=14062 - // So add the split function to select the first value; eg: Array(http://localhost:8082, thcallback) --> http://localhost:8082 - tryo(validRedirectURL.getOrElse("").split("/oauth")(0)) + val url = new URL(redirectUrl) //eg: http://localhost:8082/oauthcallback?oauth_token=G5AEA2U1WG404EGHTIGBHKRR4YJZAPPHWKOMNEEV&oauth_verifier=53018 + val protocol = url.getProtocol() // http + val authority = url.getAuthority()// localhost:8082, this will contain the port. + tryo(s"$protocol://$authority") // http://localhost:8082 } /** From d5eb84deef2b622d3c706836f614e3e8ab3e0ec8 Mon Sep 17 00:00:00 2001 From: hongwei Date: Wed, 6 Dec 2023 11:24:10 +0100 Subject: [PATCH 7/9] refactor/remove the EmbeddedKafka --- obp-api/pom.xml | 10 - ...toredProcedureConnector_vDec2019Test.scala | 101 ----- .../KafkaMappedConnector_vMay2019Test.scala | 157 ------- .../src/test/scala/code/kafka/KafkaTest.scala | 401 ------------------ .../test/scala/code/setup/KafkaSetup.scala | 76 ---- 5 files changed, 745 deletions(-) delete mode 100644 obp-api/src/test/scala/code/bankconnectors/StoredProcedureConnector_vDec2019Test.scala delete mode 100644 obp-api/src/test/scala/code/bankconnectors/vMay2019/KafkaMappedConnector_vMay2019Test.scala delete mode 100644 obp-api/src/test/scala/code/kafka/KafkaTest.scala delete mode 100644 obp-api/src/test/scala/code/setup/KafkaSetup.scala diff --git a/obp-api/pom.xml b/obp-api/pom.xml index 714d8986c..211c527f2 100644 --- a/obp-api/pom.xml +++ b/obp-api/pom.xml @@ -360,16 +360,6 @@ geocalc 0.5.7 - - - - io.github.embeddedkafka - embedded-kafka_2.12 - 2.4.1.1 - test - - - com.twilio.sdk twilio diff --git a/obp-api/src/test/scala/code/bankconnectors/StoredProcedureConnector_vDec2019Test.scala b/obp-api/src/test/scala/code/bankconnectors/StoredProcedureConnector_vDec2019Test.scala deleted file mode 100644 index c60464054..000000000 --- a/obp-api/src/test/scala/code/bankconnectors/StoredProcedureConnector_vDec2019Test.scala +++ /dev/null @@ -1,101 +0,0 @@ -package code.bankconnectors.vMay2019 - -/* -Open Bank Project - API -Copyright (C) 2011-2019, TESOBE GmbH - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see http://www.gnu.org/licenses/. - -Email: contact@tesobe.com -TESOBE GmbH -Osloerstrasse 16/17 -Berlin 13359, Germany -*/ - - -import code.actorsystem.ObpActorInit -import code.api.JSONFactoryGateway.PayloadOfJwtJSON -import code.api.util.{APIUtil, CallContext, CustomJsonFormats} -import code.bankconnectors.Connector -import code.bankconnectors.storedprocedure.StoredProcedureConnector_vDec2019 -import code.bankconnectors.vSept2018._ -import code.kafka.KafkaHelper -import code.setup.{DefaultUsers, KafkaSetup, ServerSetupWithTestData} -import com.openbankproject.commons.dto.InBoundGetBanks -import com.openbankproject.commons.model._ -import net.liftweb.common.{Box, Failure, Full} -import org.scalatest.Tag - -class StoredProcedureConnector_vDec2019Test extends ServerSetupWithTestData with DefaultUsers with ObpActorInit{ - - override implicit val formats = CustomJsonFormats.formats - - object StoredProcedureConnector_vDec2019Test extends Tag("StoredProcedureConnector_vDec2019") - - val callContext = Some( - CallContext( - gatewayLoginRequestPayload = Some(PayloadOfJwtJSON( - login_user_name = "", - is_first = false, - app_id = "", - app_name = "", - time_stamp = "", - cbs_token = Some(""), - cbs_id = "", - session_id = Some(""))), - user = Full(resourceUser1) - ) - ) - - val PropsConnectorVersion = APIUtil.getPropsValue("connector").openOrThrowException("connector props filed `connector` not set") - - - feature("Test all stored_procedure methods") { - if (PropsConnectorVersion == "stored_procedure_vDec2019") { -// scenario("test `checkBankAccountExists` method, there no need Adapter message for this method!", StoredProcedureConnector_vDec2019Test) { -// val checkBankAccountExists = StoredProcedureConnector_vDec2019.checkBankAccountExists(testBankId1,testAccountId1,callContext) -// getValueFromFuture(checkBankAccountExists)._1.isDefined equals (true) -// } -// -// scenario("test `getBankAccounts` method, there no need Adapter message for this method!", StoredProcedureConnector_vDec2019Test) { -// val checkBankAccountExists = StoredProcedureConnector_vDec2019.checkBankAccountExists(testBankId1,testAccountId1,callContext) -// getValueFromFuture(checkBankAccountExists)._1.isDefined equals (true) -// } -// scenario("test `getBank` method, there no need Adapter message for this method!", StoredProcedureConnector_vDec2019Test) { -// val transantionRequests210 = StoredProcedureConnector_vDec2019.getBank(testBankId1, callContext) -// getValueFromFuture(transantionRequests210).isDefined equals (true) -// } -// -// -// scenario("test `getBanks` method, there no need Adapter message for this method!", StoredProcedureConnector_vDec2019Test) { -// val transantionRequests210 = StoredProcedureConnector_vDec2019.getBanks(callContext) -// getValueFromFuture(transantionRequests210).isDefined equals (true) -// } -// -// scenario("test `getTransactionRequests210` method, there no need Adapter message for this method!", StoredProcedureConnector_vDec2019Test) { -// val transantionRequests210: Box[(List[TransactionRequest], Option[CallContext])] = StoredProcedureConnector_vDec2019.getTransactionRequests210(resourceUser1, null, callContext) -// transantionRequests210.isDefined equals(true) -// } - - scenario("test `getTransactions` method, there no need Adapter message for this method!", StoredProcedureConnector_vDec2019Test) { - val transactions = StoredProcedureConnector_vDec2019.getTransactions(testBankId1, testAccountId1, callContext, Nil) - val trans = getValueFromFuture(transactions)._1.openOrThrowException("Should not be empty!") - trans.head.description.isDefined equals (true) - } - - } else { - ignore("ignore test getObpConnectorLoopback, if it is mapped connector", StoredProcedureConnector_vDec2019Test) {} - } - } -} \ No newline at end of file diff --git a/obp-api/src/test/scala/code/bankconnectors/vMay2019/KafkaMappedConnector_vMay2019Test.scala b/obp-api/src/test/scala/code/bankconnectors/vMay2019/KafkaMappedConnector_vMay2019Test.scala deleted file mode 100644 index e3883ac1b..000000000 --- a/obp-api/src/test/scala/code/bankconnectors/vMay2019/KafkaMappedConnector_vMay2019Test.scala +++ /dev/null @@ -1,157 +0,0 @@ -package code.bankconnectors.vMay2019 - -/* -Open Bank Project - API -Copyright (C) 2011-2019, TESOBE GmbH - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see http://www.gnu.org/licenses/. - -Email: contact@tesobe.com -TESOBE GmbH -Osloerstrasse 16/17 -Berlin 13359, Germany -*/ - - -import code.api.JSONFactoryGateway.PayloadOfJwtJSON -import code.api.util.{APIUtil, CallContext, CustomJsonFormats} -import code.bankconnectors.Connector -import code.bankconnectors.vSept2018._ -import code.kafka.KafkaHelper -import code.setup.{KafkaSetup, ServerSetupWithTestData} -import com.openbankproject.commons.dto.InBoundGetBanks -import com.openbankproject.commons.model._ -import net.liftweb.common.{Box, Failure, Full} -import org.scalatest.Tag - -class KafkaMappedConnector_vMay2019Test extends KafkaSetup with ServerSetupWithTestData { - - override implicit val formats = CustomJsonFormats.formats - - object kafkaTest extends Tag("kafkaTest") - - val callContext = Some( - CallContext( - gatewayLoginRequestPayload = Some(PayloadOfJwtJSON( - login_user_name = "", - is_first = false, - app_id = "", - app_name = "", - time_stamp = "", - cbs_token = Some(""), - cbs_id = "", - session_id = Some(""))), - user = Full(resourceUser1) - ) - ) - - val PropsConnectorVersion = APIUtil.getPropsValue("connector").openOrThrowException("connector props filed `connector` not set") - - - feature("Send and retrieve message") { - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star") { - ignore("ignore test getObpConnectorLoopback, if it is mapped connector", kafkaTest) {} - } else - scenario("1st test `getObpConnectorLoopback` method, there no need Adapter message for this method!", kafkaTest) { - //This method is only used for `kafka` connector, should first set `connector=kafka_vSept2018` in test.default.props. - //and also need to set up `api_instance_id` and `remotedata.timeout` field for it. - val propsApiInstanceId = code.api.Constant.ApiInstanceId - val propsRemotedataTimeout = APIUtil.getPropsValue("remotedata.timeout").openOrThrowException("connector props filed `remotedata.timeout` not set") - - PropsConnectorVersion contains ("kafka") should be(true) - propsApiInstanceId should be("1") - propsRemotedataTimeout should be("10") - - When("We call this method, and get the response. ") - val future = KafkaHelper.echoKafkaServer - val result = future.getContent - - Then("If it return value successfully, that mean api <--> kafka is working well. We only need check one filed of response.") - val connectorVersion = result.connectorVersion - connectorVersion should be(PropsConnectorVersion) - - Then("For KafkaMappedConnector_vSept2018 connector, we need to make these two methods work `getAuthInfoFirstCbsCall` and `getAuthInfo`") - - val firstAuthInfo: Box[AuthInfo] = for { - firstGetAuthInfo <- KafkaMappedConnector_vSept2018.getAuthInfoFirstCbsCall("","", callContext) - } yield { - (firstGetAuthInfo) - } - firstAuthInfo.openOrThrowException("firstAuthInfo Can not be empty here. ") - - val authInfo: Box[AuthInfo] = for { - getAuthInfo <- KafkaMappedConnector_vSept2018.getAuthInfo(callContext) - } yield { - getAuthInfo - } - authInfo.openOrThrowException("firstAuthInfo Can not be empty here. ") - - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star") { - ignore("ignore test processRequest, if it is mapped connector", kafkaTest) {} - } else - scenario("Send and retrieve message directly to and from kafka", kafkaTest) { - val emptyStatusMessage = InboundStatusMessage("", "", "", "") - val inBound = InboundGetBanks(InboundAuthInfo("", ""), Status("", List(emptyStatusMessage)), List(InboundBank("1", "2", "3", "4"))) - When("send a OutboundGetBanks message") - - dispathResponse(inBound) - val req = OutboundGetBanks(AuthInfo()) - - val future = processRequest[InboundGetBanks](req) - val result: Box[InboundGetBanks] = future.getContent - - result should be(Full(inBound)) - } - - } - - feature("Test the getBank error cases") { - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star") { - ignore("ignore test getBanks, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBanksFuture -- status.hasError", kafkaTest) { - val inbound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InBoundGetBanks]).map(_.exampleInboundMessage).head.asInstanceOf[InBoundGetBanks] - //This inBound.status.errorCode != "", so it will throw the error back. - val expectedValue = Failure("INTERNAL-"+ inbound.status.errorCode+". + CoreBank-Status:" + inbound.status.backendMessages) - dispathResponse(inbound) - val future = Connector.connector.vend.getBanks(callContext) - - dispathResponse(inbound) - val result = future.getContent - result should be(expectedValue) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star") { - ignore("ignore test getBanksFuture -- status.hasNoError, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBanksFuture -- status.hasNoError", kafkaTest) { - val inbound = Connector.connector.vend.messageDocs - .filter(_.exampleInboundMessage.isInstanceOf[InBoundGetBanks]) - .map(_.exampleInboundMessage).head.asInstanceOf[InBoundGetBanks] - .copy(status = Status("", Nil)) // This will set errorCode to "", no it works - //This inBound.status.errorCode != "", so it will throw the error back. - val expectedValue = Full(inbound.data.head.bankId).toString - dispathResponse(inbound) - val future = Connector.connector.vend.getBanks(callContext) - - dispathResponse(inbound) - val result = future.getContent - result.map(_._1.head.bankId).toString should be(expectedValue) - } - - } -} \ No newline at end of file diff --git a/obp-api/src/test/scala/code/kafka/KafkaTest.scala b/obp-api/src/test/scala/code/kafka/KafkaTest.scala deleted file mode 100644 index 5f342f1ae..000000000 --- a/obp-api/src/test/scala/code/kafka/KafkaTest.scala +++ /dev/null @@ -1,401 +0,0 @@ -package code.kafka - -import java.util.{Date, UUID} - -import code.api.JSONFactoryGateway.PayloadOfJwtJSON -import code.api.util.{APIUtil, CallContext, CustomJsonFormats} -import code.api.v2_1_0.TransactionRequestBodyCommonJSON -import code.bankconnectors.Connector -import code.bankconnectors.vSept2018._ -import code.setup.{KafkaSetup, ServerSetupWithTestData} -import com.openbankproject.commons.dto.{InBoundGetKycChecks, InBoundGetKycMedias, InBoundGetKycStatuses} -import com.openbankproject.commons.model._ -import net.liftweb.common.{Box, Full} -import org.scalatest.Tag - -import scala.collection.immutable.List - -class KafkaTest extends KafkaSetup with ServerSetupWithTestData { - - override implicit val formats = CustomJsonFormats.formats - - object kafkaTest extends Tag("kafkaTest") - - val callContext = Some( - CallContext( - gatewayLoginRequestPayload = Some(PayloadOfJwtJSON( - login_user_name = "", - is_first = false, - app_id = "", - app_name = "", - time_stamp = "", - cbs_token = Some(""), - cbs_id = "", - session_id = Some(""))), - user = Full(resourceUser1) - ) - ) - - val PropsConnectorVersion = APIUtil.getPropsValue("connector").openOrThrowException("connector props filed `connector` not set") - - - feature("Send and retrieve message") { - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getObpConnectorLoopback, if it is mapped connector", kafkaTest) {} - } else - scenario("1st test `getObpConnectorLoopback` method, there no need Adapter message for this method!", kafkaTest) { - //This method is only used for `kafka` connector, should first set `connector=kafka_vSept2018` in test.default.props. - //and also need to set up `api_instance_id` and `remotedata.timeout` field for it. - val propsApiInstanceId = code.api.Constant.ApiInstanceId - val propsRemotedataTimeout = APIUtil.getPropsValue("remotedata.timeout").openOrThrowException("connector props filed `remotedata.timeout` not set") - - PropsConnectorVersion contains ("kafka") should be (true) - propsApiInstanceId should be ("1") - propsRemotedataTimeout should be ("10") - - When("We call this method, and get the response. ") - val future = KafkaHelper.echoKafkaServer - val result = future.getContent - - Then("If it return value successfully, that mean api <--> kafka is working well. We only need check one filed of response.") - val connectorVersion= result.connectorVersion - connectorVersion should be (PropsConnectorVersion) - - Then("For KafkaMappedConnector_vSept2018 connector, we need to make these two methods work `getAuthInfoFirstCbsCall` and `getAuthInfo`") - - val firstAuthInfo: Box[AuthInfo] = for{ - firstGetAuthInfo <- KafkaMappedConnector_vSept2018.getAuthInfoFirstCbsCall("","", callContext) - } yield { - (firstGetAuthInfo) - } - firstAuthInfo.openOrThrowException("firstAuthInfo Can not be empty here. ") - - val authInfo: Box[AuthInfo] = for{ - getAuthInfo <- KafkaMappedConnector_vSept2018.getAuthInfo(callContext) - } yield { - getAuthInfo - } - authInfo.openOrThrowException("firstAuthInfo Can not be empty here. ") - - } - -// if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ -// ignore("ignore test processRequest, if it is mapped connector", kafkaTest) {} -// } else -// scenario("Send and retrieve message directly to and from kafka", kafkaTest) { -// val emptyStatusMessage = InboundStatusMessage("", "", "", "") -// val inBound = InboundGetBanks(InboundAuthInfo("", ""), Status("", List(emptyStatusMessage)), List(InboundBank("1", "2", "3", "4"))) -// When("send a OutboundGetBanks message") -// -// dispathResponse(inBound) -// val req = OutboundGetBanks(AuthInfo()) -// -// val future = processRequest[InboundGetBanks](req) -// val result: Box[InboundGetBanks] = future.getContent -// -// result should be (Full(inBound)) -// } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getKycStatuses, if it is mapped connector", kafkaTest) {} - } else - scenario("test `getKycStatuses` method",kafkaTest) { - When("send a OutboundGetKycStatuses api message") - val emptyStatusMessage = InboundStatusMessage("", "", "", "") - val kycStatusCommons = KycStatusCommons(bankId = "hello_bank_id", customerId = "hello_customer_id", customerNumber = "hello_customer_number", ok = true, date = new Date()) - val singleInboundBank = List(kycStatusCommons) - val inboundAdapterCallContext = InboundAdapterCallContext(correlationId="some_correlationId") - val inBound = InBoundGetKycStatuses(inboundAdapterCallContext, Status("", List(emptyStatusMessage)), singleInboundBank) - - dispathResponse(inBound) - val future = Connector.connector.vend.getKycStatuses(kycStatusCommons.customerId, Some(CallContext())) - - val result: (Box[List[KycStatus]], Option[CallContext]) = future.getContent - val expectResult = Full(singleInboundBank) - result._1.toString should be (expectResult.toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getKycChecks, if it is mapped connector", kafkaTest) {} - } else - scenario("test `getKycChecks` method", kafkaTest) { - When("send a OutboundGetKycChecks api message") - val inBound = Connector.connector.vend.messageDocs.filter(_.process =="obp.getKycChecks").map(_.exampleInboundMessage).head.asInstanceOf[InBoundGetKycChecks] - - dispathResponse(inBound) - - val future = Connector.connector.vend.getKycChecks(inBound.data.head.customerId, Some(CallContext())) - val result: (Box[List[KycCheck]], Option[CallContext]) = future.getContent - val expectResult = Full(inBound.data) - result._1.toString should be (expectResult.toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getKycMedias, if it is mapped connector", kafkaTest) {} - } else - scenario("test `getKycMedias` method",kafkaTest) { - When("send a OutboundetKycMedias api message") - val inBound = Connector.connector.vend.messageDocs.filter(_.process =="obp.getKycMedias").map(_.exampleInboundMessage).head.asInstanceOf[InBoundGetKycMedias] - - dispathResponse(inBound) - val future = Connector.connector.vend.getKycMedias(inBound.data.head.customerId, Some(CallContext())) - - val result: (Box[List[KycMedia]], Option[CallContext]) = future.getContent - val expectResult = Full(inBound.data) - result._1.toString should be (expectResult.toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getAdapterInfo, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getAdapterInfo method",kafkaTest) { - When("send a getAdapterInfo api message") - val inBound = Connector.connector.vend.messageDocs.filter(_.process.toString.contains("getAdapterInfo")).map(_.exampleInboundMessage).head.asInstanceOf[InboundAdapterInfo] - - dispathResponse(inBound) - val future = Connector.connector.vend.getAdapterInfo(None) - - val result: Box[(InboundAdapterInfoInternal, Option[CallContext])] = future.getContent - result.map(_._1) should be (Full(inBound.data)) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getUser, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getUser method",kafkaTest) { - When("send a getUser api message") - val inBound = Connector.connector.vend.messageDocs.filter(_.process.toString.contains("getUser")).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetUserByUsernamePassword] - - dispathResponse(inBound) - val box = Connector.connector.vend.getUser("username","password") - - box.map(_.displayName) should be (Full(inBound.data.displayName)) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBanksFuture, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBanksFuture method", kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.process.toString.contains("getBanks")).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetBanks] - - dispathResponse(inBound) - val future = Connector.connector.vend.getBanks(None) - - val result = future.getContent - result.map(_._1.head.bankId).toString should be (Full(inBound.data.head.bankId).toString) - - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBanks, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBanks method", kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.process.toString.contains("getBanks")).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetBanks] - - dispathResponse(inBound) - val box = Connector.connector.vend.getBanksLegacy(None) - - box.map(_._1.head.bankId).toString should be (Full(inBound.data.head.bankId).toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBank, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBank method", kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetBank]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetBank] - - dispathResponse(inBound) - val box = Connector.connector.vend.getBankLegacy(BankId(""), None) - - box.map(_._1.bankId).toString should be (Full(inBound.data.bankId).toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBankFuture, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBankFuture method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetBank]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetBank] - - dispathResponse(inBound) - val future = Connector.connector.vend.getBank(BankId(""), None) - val result = future.getContent - - result.map(_._1.bankId).toString should be (Full(inBound.data.bankId).toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBankAccountsForUserFuture, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBankAccountsForUserFuture method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetAccounts]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetAccounts] - - dispathResponse(inBound) - val future = Connector.connector.vend.getBankAccountsForUser("", "", callContext) - val result = future.getContent - - result.map(_._1.head).toString should be (Full(inBound.data.head).toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBankAccountsForUser, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBankAccountsForUser method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetAccounts]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetAccounts] - dispathResponse(inBound) - val box = Connector.connector.vend.getBankAccountsForUserLegacy("","", callContext) - - box.map(_._1.head).toString should be (Full(inBound.data.head).toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBankAccount, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBankAccount method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetAccountbyAccountID]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetAccountbyAccountID] - dispathResponse(inBound) - val box = Connector.connector.vend.getBankAccountLegacy(BankId(""), AccountId(""), callContext) - - box.map(_._1.bankId).toString should be (Full(inBound.data.head.bankId).toString) - box.map(_._1.accountId).toString should be (Full(inBound.data.head.accountId).toString) - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getBankAccountFuture, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getBankAccountFuture method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetAccountbyAccountID]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetAccountbyAccountID] - dispathResponse(inBound) - val future = Connector.connector.vend.checkBankAccountExists(BankId(""), AccountId(""), callContext) - - val result = future.getContent - - result._1.map(_.accountId.value).toString should be (Full(inBound.data.head.accountId).toString) - result._1.map(_.bankId.value).toString should be (Full(inBound.data.head.bankId).toString) - - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getChallengeThreshold, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getChallengeThreshold method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetChallengeThreshold]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetChallengeThreshold] - dispathResponse(inBound) - val future = Connector.connector.vend.getChallengeThreshold("","","","","","","", callContext) - - val result = future.getContent - - result._1.map(_.amount).toString should be (Full(inBound.data.amount).toString) - result._1.map(_.currency).toString should be (Full(inBound.data.currency).toString) - - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test makePaymentv210, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test makePaymentv210 method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundCreateTransactionId]).map(_.exampleInboundMessage).head.asInstanceOf[InboundCreateTransactionId] - dispathResponse(inBound) - - val fromAccount = BankAccountSept2018(KafkaMappedConnector_vSept2018.inboundAccountSept2018Example) - val toAccount = BankAccountSept2018(KafkaMappedConnector_vSept2018.inboundAccountSept2018Example) - val transactionRequestId = TransactionRequestId(UUID.randomUUID().toString) - val transactionRequestCommonBody = TransactionRequestBodyCommonJSON(AmountOfMoneyJsonV121("",""),"") - val future = Connector.connector.vend.makePaymentv210( - fromAccount, - toAccount, - transactionRequestId, - transactionRequestCommonBody, - 10, - "", - TransactionRequestType("SANDBOX_TAN"), - "", - callContext) - - val result = future.getContent - - result._1.map(_.value).toString should be (Full(inBound.data.id).toString) - - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test createChallenge, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test createChallenge method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundCreateChallengeSept2018]).map(_.exampleInboundMessage).head.asInstanceOf[InboundCreateChallengeSept2018] - dispathResponse(inBound) - - val account = BankAccountSept2018(KafkaMappedConnector_vSept2018.inboundAccountSept2018Example) - val transactionRequestCommonBody = TransactionRequestBodyCommonJSON(AmountOfMoneyJsonV121("",""),"") - val future = Connector.connector.vend.createChallenge( - account.bankId, - account.accountId, - "", - TransactionRequestType("SANDBOX_TAN"), - "", - None, - callContext) - - val result = future.getContent - - result._1.toString should be (Full(inBound.data.answer).toString) - - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test createCounterparty, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test createCounterparty method",kafkaTest) { - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundCreateCounterparty]).map(_.exampleInboundMessage).head.asInstanceOf[InboundCreateCounterparty] - val outBound = Connector.connector.vend.messageDocs.filter(_.exampleOutboundMessage.isInstanceOf[OutboundCreateCounterparty]).map(_.exampleOutboundMessage).head.asInstanceOf[OutboundCreateCounterparty] - dispathResponse(inBound) - - val account = BankAccountSept2018(KafkaMappedConnector_vSept2018.inboundAccountSept2018Example) - val transactionRequestCommonBody = TransactionRequestBodyCommonJSON(AmountOfMoneyJsonV121("",""),"") - val box = Connector.connector.vend.createCounterparty( - outBound.counterparty.name, - outBound.counterparty.description, - outBound.counterparty.currency, - outBound.counterparty.createdByUserId, - outBound.counterparty.thisBankId, - outBound.counterparty.thisAccountId, - outBound.counterparty.thisViewId, - outBound.counterparty.otherAccountRoutingScheme, - outBound.counterparty.otherAccountRoutingAddress, - outBound.counterparty.otherAccountSecondaryRoutingScheme, - outBound.counterparty.otherAccountSecondaryRoutingAddress, - outBound.counterparty.otherBankRoutingScheme, - outBound.counterparty.otherBankRoutingAddress, - outBound.counterparty.otherBranchRoutingScheme, - outBound.counterparty.otherBranchRoutingAddress, - outBound.counterparty.isBeneficiary, - outBound.counterparty.bespoke, - callContext) - - - box.map(_._1.counterpartyId) should be (Full(inBound.data.get.counterpartyId)) - box.map(_._1.createdByUserId) should be (Full(inBound.data.get.createdByUserId)) - - } - - if (PropsConnectorVersion =="mapped" || PropsConnectorVersion =="star"){ - ignore("ignore test getTransactionRequests210, if it is mapped connector", kafkaTest) {} - } else - scenario(s"test getTransactionRequests210 method",kafkaTest) { - - val inBound = Connector.connector.vend.messageDocs.filter(_.exampleInboundMessage.isInstanceOf[InboundGetTransactionRequests210]).map(_.exampleInboundMessage).head.asInstanceOf[InboundGetTransactionRequests210] - dispathResponse(inBound) - - val account = BankAccountSept2018(KafkaMappedConnector_vSept2018.inboundAccountSept2018Example) - val transactionRequestCommonBody = TransactionRequestBodyCommonJSON(AmountOfMoneyJsonV121("",""),"") - val box = Connector.connector.vend.getTransactionRequests210( - resourceUser1, - account, - callContext) - - box.map(_._1.head.body) should be (inBound.data.head.body) - - - } - - } -} diff --git a/obp-api/src/test/scala/code/setup/KafkaSetup.scala b/obp-api/src/test/scala/code/setup/KafkaSetup.scala deleted file mode 100644 index 4c881e9d6..000000000 --- a/obp-api/src/test/scala/code/setup/KafkaSetup.scala +++ /dev/null @@ -1,76 +0,0 @@ -package code.setup - -import code.actorsystem.ObpActorSystem -import code.api.util.CustomJsonFormats -import code.kafka._ -import code.util.Helper.MdcLoggable -import net.liftweb.json -import net.liftweb.json.Extraction -import net.manub.embeddedkafka.{EmbeddedKafka, EmbeddedKafkaConfig} -import org.apache.kafka.common.serialization.{StringDeserializer, StringSerializer} -import org.scalatest.{FeatureSpec, _} - -import com.openbankproject.commons.ExecutionContext.Implicits.global -import scala.concurrent.{Await, Future} -import scala.concurrent.duration.{Duration, _} - -trait KafkaSetup extends FeatureSpec with EmbeddedKafka with KafkaHelper - with GivenWhenThen with BeforeAndAfterAll - with Matchers with MdcLoggable { - - - - implicit val formats = CustomJsonFormats.formats - implicit val config = EmbeddedKafkaConfig(kafkaPort = 9092, zooKeeperPort = 2181) //TODO the port should read from test.default.props, but fail - implicit val stringSerializer = new StringSerializer - implicit val stringDeserializer = new StringDeserializer - - val requestMapResponseTopics:Map[String, String] = NorthSideConsumer.listOfTopics - .map(Topics.createTopicByClassName) - .map(pair => (pair.request, pair.response)) - .toMap - val requestTopics = requestMapResponseTopics.keySet - - override def beforeAll(): Unit = { - super.beforeAll() - - EmbeddedKafka.start() - - if(!OBPKafkaConsumer.primaryConsumer.started){ - val actorSystem = ObpActorSystem.startLocalActorSystem - KafkaHelperActors.startLocalKafkaHelperWorkers(actorSystem) - // Start North Side Consumer if it's not already started - OBPKafkaConsumer.primaryConsumer.start() - } - } - - override def afterAll(): Unit = { - super.afterAll() - OBPKafkaConsumer.primaryConsumer.complete() - EmbeddedKafka.stop() - } - - /** - * send an object to kafka as response - * - * @param inBound inBound object that will send to kafka as a response - * @tparam T Outbound type - */ - def dispathResponse(inBound: AnyRef): Unit = { - val inBoundStr = inBound match { - case str: String => str - case _ =>json.compactRender(Extraction.decompose(inBound)) - } - Future{ - val requestKeyValue = consumeNumberKeyedMessagesFromTopics(requestTopics, 1, true) - val (requestTopic, keyValueList) = requestKeyValue.find(_._2.nonEmpty).get - val (key, _) = keyValueList.head - val responseTopic = requestMapResponseTopics(requestTopic) - publishToKafka(responseTopic, key, inBoundStr) - } - } - - implicit class FutureExtract[T](future: Future[T]) { - def getContent: T = Await.result(future, 10 seconds) - } -} From f59448effc580a2ceba3a321e9a6f58e1f6f464d Mon Sep 17 00:00:00 2001 From: Simon Redfern Date: Wed, 6 Dec 2023 12:24:38 +0100 Subject: [PATCH 8/9] Tweaking documentation for getMetrics in 5.1.0 --- .../main/scala/code/api/v5_1_0/APIMethods510.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala index 41545ead0..2134c45f9 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala @@ -1422,19 +1422,22 @@ trait APIMethods510 { "GET", "/management/metrics", "Get Metrics", - s"""Get the all metrics + s"""Get API metrics rows. These are records of each REST API call. | |require CanReadMetrics role | |Filters Part 1.*filtering* (no wilde cards etc.) parameters to GET /management/metrics | - |Should be able to filter on the following metrics fields + |You can filter by the following fields by applying url parameters | |eg: /management/metrics?from_date=$DateWithMsExampleString&to_date=$DateWithMsExampleString&limit=50&offset=2 | - |1 from_date (defaults to one week before current date): eg:from_date=$DateWithMsExampleString + |1 from_date e.g.:from_date=$DateWithMsExampleString Defaults to the Unix Epoch i.e. ${theEpochTime} | - |2 to_date (defaults to current date) eg:to_date=$DateWithMsExampleString + |2 to_date e.g.:to_date=$DateWithMsExampleString Defaults to a far future date i.e. ${APIUtil.ToDateInFuture} + | + |Note: it is recommended you send a valid from_date (e.g. 5 seconds ago) and to_date (now + 1 second) if you want to get the latest records + | Otherwise you may receive stale cached results. | |3 limit (for pagination: defaults to 50) eg:limit=200 | From c0f354f10f2b9c21706a94f4e7a4b1bff0ef5fab Mon Sep 17 00:00:00 2001 From: hongwei Date: Wed, 6 Dec 2023 15:37:26 +0100 Subject: [PATCH 9/9] bugfix/move the future out of the cache --- obp-api/src/main/scala/code/api/util/NewStyle.scala | 4 ++-- .../src/main/scala/code/metrics/MappedMetrics.scala | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/obp-api/src/main/scala/code/api/util/NewStyle.scala b/obp-api/src/main/scala/code/api/util/NewStyle.scala index 20325761d..5042e4402 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -3056,7 +3056,7 @@ object NewStyle extends MdcLoggable{ private[this] val endpointMappingTTL = APIUtil.getPropsValue(s"endpointMapping.cache.ttl.seconds", "0").toInt - def getEndpointMappings(bankId: Option[String], callContext: Option[CallContext]): OBPReturnType[List[EndpointMappingT]] = { + def getEndpointMappings(bankId: Option[String], callContext: Option[CallContext]): OBPReturnType[List[EndpointMappingT]] = Future{ import scala.concurrent.duration._ validateBankId(bankId, callContext) @@ -3064,7 +3064,7 @@ object NewStyle extends MdcLoggable{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(endpointMappingTTL second) { - Future{(EndpointMappingProvider.endpointMappingProvider.vend.getAllEndpointMappings(bankId), callContext)} + {(EndpointMappingProvider.endpointMappingProvider.vend.getAllEndpointMappings(bankId), callContext)} } } } diff --git a/obp-api/src/main/scala/code/metrics/MappedMetrics.scala b/obp-api/src/main/scala/code/metrics/MappedMetrics.scala index 0a7c7c747..9f04090db 100644 --- a/obp-api/src/main/scala/code/metrics/MappedMetrics.scala +++ b/obp-api/src/main/scala/code/metrics/MappedMetrics.scala @@ -360,7 +360,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ } // TODO Cache this as long as fromDate and toDate are in the past (before now) - override def getTopApisFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopApi]]] = { + override def getTopApisFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopApi]]] = Future{ /** * Please note that "var cacheKey = (randomUUID().toString, randomUUID().toString, randomUU * is just a temporary value field with UUID values in order to prevent any ambiguity. @@ -369,7 +369,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ */ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey {Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cachedTopApis seconds){ - Future{ + { val fromDate = queryParams.collect { case OBPFromDate(value) => value }.headOption val toDate = queryParams.collect { case OBPToDate(value) => value }.headOption val consumerId = queryParams.collect { case OBPConsumerId(value) => value }.headOption.flatMap(consumerIdToPrimaryKey) @@ -440,7 +440,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ }} // TODO Cache this as long as fromDate and toDate are in the past (before now) - override def getTopConsumersFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopConsumer]]] = { + override def getTopConsumersFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopConsumer]]] = Future { /** * Please note that "var cacheKey = (randomUUID().toString, randomUUID().toString, randomUU * is just a temporary value field with UUID values in order to prevent any ambiguity. @@ -449,7 +449,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ */ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey {Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cachedTopConsumers seconds){ - Future { + val fromDate = queryParams.collect { case OBPFromDate(value) => value }.headOption val toDate = queryParams.collect { case OBPToDate(value) => value }.headOption val consumerId = queryParams.collect { case OBPConsumerId(value) => value }.headOption.flatMap(consumerIdToPrimaryKey) @@ -519,7 +519,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ } tryo(result) } - }}} + }} }