mirror of
https://github.com/OpenBankProject/API-Explorer.git
synced 2026-02-06 18:56:49 +00:00
Merge pull request #109 from hongwei1/develop
feature/separated the dynamic and static endpoints
This commit is contained in:
commit
070f9a5a43
@ -10,11 +10,12 @@ import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.util.cache.Caching
|
||||
import net.liftweb.common.{Box, Failure, Full, _}
|
||||
import net.liftweb.http.{RequestVar, S}
|
||||
import net.liftweb.http.{RequestVar, S, SessionVar}
|
||||
import net.liftweb.json.JsonAST.{JBool, JValue}
|
||||
import net.liftweb.json.JsonDSL._
|
||||
import net.liftweb.json._
|
||||
import net.liftweb.util.Helpers.{intToTimeSpanBuilder=>_,_} //This will break the cache days, so here we hide it in import
|
||||
import net.liftweb.util.Helpers.{intToTimeSpanBuilder => _, _}
|
||||
|
||||
import scala.xml.NodeSeq
|
||||
import com.tesobe.CacheKeyFromArguments
|
||||
import scala.collection.immutable.{List, Nil}
|
||||
@ -50,7 +51,8 @@ object ObpAPI extends Loggable {
|
||||
def allBanks : Box[BanksJson]= {
|
||||
allBanksVar.get match {
|
||||
case Full(a) => Full(a)
|
||||
case _ => ObpGet(s"$obpPrefix/v3.1.0/banks").flatMap(_.extractOpt[BanksJson])
|
||||
case _ => allBanksVar.set(ObpGet(s"$obpPrefix/v3.1.0/banks").flatMap(_.extractOpt[BanksJson]))
|
||||
allBanksVar.get
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,17 +147,50 @@ object ObpAPI extends Loggable {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The request vars ensure that for one page load, the same API call isn't made multiple times
|
||||
*/
|
||||
object allResoucesVar extends SessionVar[Box[ResourceDocsJson]] (Empty)
|
||||
|
||||
|
||||
// Returns Json containing Resource Docs
|
||||
def getResourceDocsJson(apiVersion : String) : Box[ResourceDocsJson] = {
|
||||
val requestParams = List("tags", "language", "functions")
|
||||
def getResourceDocsJson(apiVersion : String) : List[ResourceDocJson] = {
|
||||
|
||||
//Note: ?content=true&content=false
|
||||
// if there are two content parameters there, only the first one is valid for the api call.
|
||||
// so requestParams have the high priority
|
||||
val requestParams = List("tags", "language", "functions", "content")
|
||||
.map(paramName => (paramName, S.param(paramName)))
|
||||
.collect{
|
||||
case (paramName, Full(paramValue)) if(paramValue.trim.size > 0) => s"$paramName=$paramValue"
|
||||
}
|
||||
.mkString("?", "&", "")
|
||||
|
||||
ObpGet(s"$obpPrefix/v3.1.0/resource-docs/$apiVersion/obp$requestParams").map(extractResourceDocsJson)
|
||||
val staticResourcesDocs= getStaticResourceDocs(apiVersion,requestParams)
|
||||
|
||||
if(requestParams.contains("content=static")) {
|
||||
staticResourcesDocs
|
||||
} else if (requestParams.contains("content=dynamic")){
|
||||
getDynamicResourceDocs(apiVersion,requestParams)
|
||||
} else{
|
||||
val dynamicResourcesDocs= getDynamicResourceDocs(apiVersion,requestParams)
|
||||
staticResourcesDocs ++ dynamicResourcesDocs
|
||||
}
|
||||
}
|
||||
|
||||
// static resourceDocs can be cached for a long time, only be changed when new deployment.
|
||||
val getStaticResourceDocsJsonTTL: FiniteDuration = 365 days
|
||||
def getStaticResourceDocs(apiVersion : String, requestParams: String): List[ResourceDocJson] = {
|
||||
var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString)
|
||||
CacheKeyFromArguments.buildCacheKey {
|
||||
Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(getStaticResourceDocsJsonTTL) {
|
||||
ObpGet(s"$obpPrefix/v3.1.0/resource-docs/$apiVersion/obp$requestParams&content=static").map(extractResourceDocsJson).map(_.resource_docs).head
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def getDynamicResourceDocs(apiVersion : String, requestParams: String) =
|
||||
ObpGet(s"$obpPrefix/v3.1.0/resource-docs/$apiVersion/obp$requestParams&content=dynamic").map(extractResourceDocsJson).map(_.resource_docs).head
|
||||
|
||||
/**
|
||||
* extract ResourceDocsJson and output details of error if extract json to case class fail
|
||||
@ -211,6 +246,7 @@ object OBPRequest extends MdcLoggable {
|
||||
implicit val formats = DefaultFormats
|
||||
//returns a tuple of the status code, response body and list of headers
|
||||
def apply(apiPath : String, jsonBody : Option[JValue], method : String, headers : List[Header]) : Box[(Int, String, List[String])] = {
|
||||
logger.debug(s"before $apiPath call:")
|
||||
val statusAndBody = tryo {
|
||||
val credentials = OAuthClient.getAuthorizedCredential
|
||||
val apiUrl = OAuthClient.currentApiBaseUrl
|
||||
@ -271,7 +307,7 @@ object OBPRequest extends MdcLoggable {
|
||||
(status, builder.toString(), adjustedResponseHeaders)
|
||||
}
|
||||
|
||||
statusAndBody pass {
|
||||
val result = statusAndBody pass {
|
||||
case Failure(msg, ex, _) => {
|
||||
val sw = new StringWriter()
|
||||
val writer = new PrintWriter(sw)
|
||||
@ -280,6 +316,8 @@ object OBPRequest extends MdcLoggable {
|
||||
}
|
||||
case _ => Unit
|
||||
}
|
||||
logger.debug(s"after $apiPath call:")
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,7 +413,11 @@ object APIUtils extends MdcLoggable {
|
||||
|
||||
def getAPIResponseBody(responseCode : Int, body : String) : Box[JValue] = {
|
||||
responseCode match {
|
||||
case 200 | 201 | 202 |204 => tryo{parse(body)}
|
||||
case 200 | 201 | 202 |204 =>
|
||||
logger.debug("Before getAPIResponseBody(String ->JValue): ")
|
||||
val jvalue = tryo{parse(body)}
|
||||
logger.debug("After getAPIResponseBody(String -> JValue): ")
|
||||
jvalue
|
||||
case _ => {
|
||||
val failMsg = "Bad response code (" + responseCode + ") from OBP API server: " + body
|
||||
logger.warn(failMsg)
|
||||
|
||||
@ -218,6 +218,14 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
val languagesParamString = "&language=" + rawLanguageParam.mkString(",")
|
||||
|
||||
logger.info(s"languagesParamString is $languagesParamString")
|
||||
|
||||
val rawContentParam = S.param("content")
|
||||
|
||||
logger.info(s"contentParam is $rawContentParam")
|
||||
|
||||
val contentParamString = "&content=" + rawContentParam.mkString(",")
|
||||
|
||||
logger.info(s"contentParamString is $contentParamString")
|
||||
|
||||
val tagsParam: Option[List[String]] = rawTagsParam match {
|
||||
// if tags= is supplied in the url we want to ignore it
|
||||
@ -246,6 +254,11 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
case _ => ""
|
||||
}
|
||||
|
||||
val contentHeadline : String = rawContentParam match {
|
||||
case Full(x) => x
|
||||
case _ => ""
|
||||
}
|
||||
|
||||
val implementedHereHeadline : String = nativeParam match {
|
||||
case Some(true) => "(those added or modified in this version)"
|
||||
case Some(false) => "(those inherited from previous versions)"
|
||||
@ -395,23 +408,23 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
val baseVersionUrl = s"${OAuthClient.currentApiBaseUrl}"
|
||||
|
||||
// Link to the API endpoint for the resource docs json TODO change apiVersion so it doesn't have a "v" prefix
|
||||
val resourceDocsPath = s"${OAuthClient.currentApiBaseUrl}/obp/v1.4.0/resource-docs/${apiVersion.stripPrefix("v")}/obp?${tagsParamString}${languagesParamString}"
|
||||
val resourceDocsPath = s"${OAuthClient.currentApiBaseUrl}/obp/v1.4.0/resource-docs/${apiVersion.stripPrefix("v")}/obp?${tagsParamString}${languagesParamString}${contentParamString}"
|
||||
|
||||
// Link to the API endpoint for the swagger json
|
||||
val swaggerPath = s"${OAuthClient.currentApiBaseUrl}/obp/v1.4.0/resource-docs/${apiVersion.stripPrefix("v")}/swagger?${tagsParamString}${languagesParamString}"
|
||||
val swaggerPath = s"${OAuthClient.currentApiBaseUrl}/obp/v1.4.0/resource-docs/${apiVersion.stripPrefix("v")}/swagger?${tagsParamString}${languagesParamString}${contentParamString}"
|
||||
|
||||
val chineseVersionPath = "?language=zh"
|
||||
val allPartialFunctions = "/partial-functions.html"
|
||||
|
||||
//Note > this method is only for partial-functions.html .
|
||||
def showPartialFunctions = {
|
||||
// Get a list of resource docs from the API server
|
||||
// This will throw an exception if resource_docs key is not populated
|
||||
// Convert the json representation to ResourceDoc (pretty much a one to one mapping)
|
||||
// The overview contains html. Just need to convert it to a NodeSeq so the template will render it as such
|
||||
val allResources: List[ResourceDocJson] = for {
|
||||
rs <- getResourceDocsJson(apiVersion).toList
|
||||
r <- rs.resource_docs
|
||||
} yield r
|
||||
rs <- getResourceDocsJson(apiVersion)
|
||||
} yield rs
|
||||
// The list generated here might be used by an administrator as a white or black list of API calls for the API itself.
|
||||
val commaSeparatedListOfResources = allResources.map(_.implemented_by.function).mkString("[", ", ", "]")
|
||||
|
||||
@ -596,14 +609,13 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
|
||||
|
||||
def showResources = {
|
||||
|
||||
logger.debug("before showResources:")
|
||||
// Get a list of resource docs from the API server
|
||||
// This will throw an exception if resource_docs key is not populated
|
||||
// Convert the json representation to ResourceDoc (pretty much a one to one mapping)
|
||||
// The overview contains html. Just need to convert it to a NodeSeq so the template will render it as such
|
||||
val allResources = for {
|
||||
rs <- getResourceDocsJson(apiVersion).toList
|
||||
r <- rs.resource_docs
|
||||
r <- getResourceDocsJson(apiVersion)
|
||||
} yield ResourceDocPlus(
|
||||
//in OBP-API, before it returned v3_1_0, but now, only return v3.1.0
|
||||
//But this filed will be used in JavaScript, so need clean the field.
|
||||
@ -735,7 +747,7 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
// Title / Headline we display including count of APIs
|
||||
val headline : String = s"""
|
||||
${apiVersionRequested.stripPrefix("OBP").stripPrefix("BG").stripPrefix("STET").stripPrefix("UK")}
|
||||
$tagsHeadline $languageHeadline $implementedHereHeadline (${resources.length} APIs)
|
||||
$tagsHeadline $languageHeadline $contentHeadline $implementedHereHeadline (${resources.length} APIs)
|
||||
""".trim()
|
||||
|
||||
|
||||
@ -912,7 +924,7 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
|
||||
|
||||
|
||||
val thisApplicationUrl = s"${CurrentReq.value.uri}?version=${apiVersionRequested}&list-all-banks=${listAllBanks}${tagsParamString}${languagesParamString}"
|
||||
val thisApplicationUrl = s"${CurrentReq.value.uri}?version=${apiVersionRequested}&list-all-banks=${listAllBanks}${tagsParamString}${languagesParamString}${contentParamString}"
|
||||
|
||||
|
||||
val obpVersionUrls: List[(String, String)] = obpVersionsSupported.map(i => (i.replace("OBPv", "v"), s"?version=${i}&list-all-banks=${listAllBanks}"))
|
||||
@ -1169,8 +1181,7 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
|
||||
// In case we use Extraction.decompose
|
||||
implicit val formats = net.liftweb.json.DefaultFormats
|
||||
|
||||
"#login_status_message" #> loggedInStatusMessage &
|
||||
val cssResult = "#login_status_message" #> loggedInStatusMessage &
|
||||
"#bank_selector" #> doBankSelect _ &
|
||||
"#account_selector" #> doAccountSelect _ &
|
||||
"#view_selector" #> doViewSelect _ &
|
||||
@ -1245,7 +1256,7 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
else if (resources.find(_.id == currentOperationId).map(_.tags.head).getOrElse("API")==resources.find(_.id == i.id).map(_.tags.head).getOrElse("API")) //If the Tag is the current Tag.We do not need parameters.
|
||||
s"#${i.id}"
|
||||
else
|
||||
s"?version=$apiVersionRequested&operation_id=${i.id}&bank_id=${presetBankId}&account_id=${presetAccountId}&view_id=${presetViewId}&counterparty_id=${presetCounterpartyId}&transaction_id=${presetTransactionId}#${i.id}") &
|
||||
s"?version=$apiVersionRequested&operation_id=${i.id}¤tTag=${i.tags.head}&bank_id=${presetBankId}&account_id=${presetAccountId}&view_id=${presetViewId}&counterparty_id=${presetCounterpartyId}&transaction_id=${presetTransactionId}#${i.id}") &
|
||||
"@api_list_item_link *" #> i.summary &
|
||||
"@api_list_item_link [id]" #> s"index_of_${i.id}"
|
||||
// ".content-box__available-since *" #> s"Implmented in ${i.implementedBy.version} by ${i.implementedBy.function}"
|
||||
@ -1411,6 +1422,8 @@ WIP to add comments on resource docs. This code copied from Sofit.
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.debug("after showResources:")
|
||||
cssResult
|
||||
}
|
||||
|
||||
def showGlossary = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user