refactor/removed the apibuilder endpoints

This commit is contained in:
hongwei 2024-05-10 16:56:28 +02:00
parent a7ed850bb4
commit f13d082dc3
14 changed files with 2 additions and 1985 deletions

View File

@ -42,7 +42,6 @@ import code.api.ResourceDocs1_4_0.ResourceDocs300.{ResourceDocs310, ResourceDocs
import code.api.ResourceDocs1_4_0._
import code.api._
import code.api.attributedefinition.AttributeDefinition
import code.api.builder.APIBuilder_Connector
import code.api.cache.Redis
import code.api.util.APIUtil.{enableVersionIfAllowed, errorJsonResponse, getPropsValue, gitCommit}
import code.api.util._
@ -454,7 +453,6 @@ class Boot extends MdcLoggable {
enableVersionIfAllowed(ApiVersion.v4_0_0)
enableVersionIfAllowed(ApiVersion.v5_0_0)
enableVersionIfAllowed(ApiVersion.v5_1_0)
enableVersionIfAllowed(ApiVersion.b1)
enableVersionIfAllowed(ApiVersion.`dynamic-endpoint`)
enableVersionIfAllowed(ApiVersion.`dynamic-entity`)
@ -1089,7 +1087,7 @@ object ToSchemify {
EndpointTag,
ProductFee,
UserInitAction
)++ APIBuilder_Connector.allAPIBuilderModels
)
// start grpc server
if (APIUtil.getPropsAsBoolValue("grpc.server.enabled", false)) {

View File

@ -1,503 +0,0 @@
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.APIBuilder
import code.api.APIBuilder.APIBuilderModel._
import code.api.util.APIUtil
import scala.meta._
import net.liftweb.json.JsonAST.{JObject, JString}
import net.liftweb.json.JValue
object APIBuilder
{
//you can modify this json file: OBP-API/obp-api/src/main/resources/apiBuilder/apisResource.json
def main(args: Array[String]): Unit = overwriteApiCode(apiSource,jsonFactorySource)
val jsonJValueFromFile: JValue = APIUtil.getJValueFromJsonFile("apiBuilder/apisResource.json")
val resourceDocsJObject= jsonJValueFromFile.\("resource_docs").children.asInstanceOf[List[JObject]]
val getMultipleApiJValue = resourceDocsJObject.filter(jObject => jObject.\("request_verb") == JString("GET")&& !jObject.\("request_url").asInstanceOf[JString].values.contains("_ID")).head
val getSingleApiJValue = resourceDocsJObject.filter(jObject => jObject.\("request_verb") == JString("GET")&& jObject.\("request_url").asInstanceOf[JString].values.contains("_ID")).head
val createSingleApiJValue = resourceDocsJObject.filter(_.\("request_verb") == JString("POST")).head
val deleteSingleApiJValue = resourceDocsJObject.filter(_.\("request_verb") == JString("DELETE")).head
val getSingleApiResponseBody: JValue = getSingleApiJValue \ "success_response_body"
//"template"
val modelName = getModelName(getSingleApiResponseBody)
//All the fields in the template object.
val modelFieldsJValue: JValue = getSingleApiResponseBody \ modelName
//TEMPLATE
val modelNameUpperCase = modelName.toUpperCase
//template
val modelNameLowerCase = modelName.toLowerCase
//Template
val modelNameCapitalized = modelNameLowerCase.capitalize
//MappedTemplate_123123
val modelMappedName = s"Mapped${modelNameCapitalized}_"+Math.abs(scala.util.Random.nextLong())
val modelTypeName = Type.Name(modelMappedName)
val modelTermName = Term.Name(modelMappedName)
val modelInit =Init.apply(Type.Name(modelMappedName), Term.Name(modelMappedName), Nil)
val getMultipleApiSummary: String = (getMultipleApiJValue \ "summary").asInstanceOf[JString].values
val getSingleApiSummary: String = (getSingleApiJValue \ "summary").asInstanceOf[JString].values
val createSingleApiSummary: String = (createSingleApiJValue \ "summary").asInstanceOf[JString].values
val deleteSingleApiSummary: String = (deleteSingleApiJValue \ "summary").asInstanceOf[JString].values
val getApiSummaryFromJsonFile: String = getMultipleApiSummary +"(from Json File)"
val getApiDescription: String = (getMultipleApiJValue \ "description").asInstanceOf[JString].values
val getSingleApiDescription: String = (getSingleApiJValue \ "description").asInstanceOf[JString].values
val createSingleApiDescription: String = (createSingleApiJValue \ "description").asInstanceOf[JString].values
val deleteSingleApiDescription: String = (deleteSingleApiJValue \ "description").asInstanceOf[JString].values
val getApiDescriptionFromJsonFile: String = getApiDescription + "(From Json File)"
//TODO, for now this is only in description, could be a single field later.
val getMultipleApiAuthentication:Boolean = getApiDescriptionFromJsonFile.contains("Authentication is Mandatory")
val getSingleApiAuthentication:Boolean = getSingleApiDescription.contains("Authentication is Mandatory")
val createSingleApiAuthentication:Boolean = createSingleApiDescription.contains("Authentication is Mandatory")
val deleteSingleApiAuthentication:Boolean = deleteSingleApiDescription.contains("Authentication is Mandatory")
val getMultipleAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(getMultipleApiAuthentication)
val getSingleApiAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(getSingleApiAuthentication)
val createSingleApiAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(createSingleApiAuthentication)
val deleteSingleApiAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(deleteSingleApiAuthentication)
val getMultipleApiUrl: String = getApiUrl(getMultipleApiJValue)//eg: /my/template
val getSingleApiUrl: String = getApiUrl(getSingleApiJValue) //eg: /my/template
val createSingleApiUrl: String = getApiUrl(createSingleApiJValue)//eg: /my/template
val deleteSingleApiUrl: String = getApiUrl(deleteSingleApiJValue)//eg: /my/template
val getApiUrlFromJsonFile: String = "/file"+getMultipleApiUrl //eg: /file/my/template
val getMultipleApiUrlVal = Lit.String(s"$getMultipleApiUrl")
val getSingleApiUrlVal = Lit.String(s"$getSingleApiUrl")
val createSingleApiUrlVal = Lit.String(s"$createSingleApiUrl")
val deleteSingleApiUrlVal = Lit.String(s"$deleteSingleApiUrl")
val getApiUrlFromJsonFileVal = Lit.String(s"$getApiUrlFromJsonFile")
//TODO, escape issue:return the space, I added quotes in the end: allSourceCode.syntax.replaceAll(""" :: ""","""" :: """")
//from "/my/template" --> "my :: template"
val getApiUrlLiftFormat = getMultipleApiUrl.replaceFirst("/", "").split("/").mkString("""""",""" :: ""","""""")
val createApiUrlLiftFormat = createSingleApiUrl.replaceFirst("/", "").split("/").mkString("""""",""" :: ""","""""")
val deleteApiUrlLiftFormat = deleteSingleApiUrl.replaceFirst("/", "").split("/").dropRight(1).mkString("""""",""" :: ""","""""")
val getSingleApiUrlLiftFormat = getSingleApiUrl.replaceFirst("/", "").split("/").dropRight(1).mkString("""""",""" :: ""","""""")
val getApiUrlLiftweb: Lit.String = Lit.String(getApiUrlLiftFormat)
val createApiUrlLiftweb: Lit.String = Lit.String(createApiUrlLiftFormat)
val deleteApiUrlLiftweb: Lit.String = Lit.String(deleteApiUrlLiftFormat)
val getSingleApiUrlLiftweb: Lit.String = Lit.String(getSingleApiUrlLiftFormat)
val getMultipleApiSummaryVal = Lit.String(s"$getMultipleApiSummary")
val getSingleApiSummaryVal = Lit.String(s"$getSingleApiSummary")
val createSingleApiSummaryVal = Lit.String(s"$createSingleApiSummary")
val deleteSingleApiSummaryVal = Lit.String(s"$deleteSingleApiSummary")
val getApiSummaryFromJsonFileVal = Lit.String(s"$getApiSummaryFromJsonFile")
val getMultipleApiDescriptionVal = Lit.String(s"$getApiDescription")
val getSingleApiDescriptionVal = Lit.String(s"$getSingleApiDescription")
val createSingleApiDescriptionVal = Lit.String(s"$createSingleApiDescription")
val deleteSingleApiDescriptionVal = Lit.String(s"$deleteSingleApiDescription")
val getApiDescriptionFromJsonFileVal = Lit.String(s"$getApiDescriptionFromJsonFile")
val errorMessageBody: Lit.String = Lit.String(s"OBP-31001: ${modelNameCapitalized} not found. Please specify a valid value for ${modelNameUpperCase}_ID.")
val errorMessageName: Pat.Var = Pat.Var(Term.Name(s"${modelNameCapitalized}NotFound"))
val errorMessageVal: Defn.Val = q"""val TemplateNotFound = $errorMessageBody""".copy(pats = List(errorMessageName))
val errorMessage: Term.Name = Term.Name(errorMessageVal.pats.head.toString())
val getTemplateFromFileResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
getTemplatesFromFile,
apiVersion,
"getTemplatesFromFile",
"GET",
$getApiUrlFromJsonFileVal,
$getApiSummaryFromJsonFileVal,
$getApiDescriptionFromJsonFileVal,
emptyObjectJson,
templatesJson,
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val getTemplatesResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
getTemplates,
apiVersion,
"getTemplates",
"GET",
$getMultipleApiUrlVal,
$getMultipleApiSummaryVal,
$getMultipleApiDescriptionVal,
emptyObjectJson,
templatesJson,
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val getTemplateResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
getTemplate,
apiVersion,
"getTemplate",
"GET",
$getSingleApiUrlVal,
$getSingleApiSummaryVal,
$getSingleApiDescriptionVal,
emptyObjectJson,
templateJson,
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val createTemplateResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
createTemplate,
apiVersion,
"createTemplate",
"POST",
$createSingleApiUrlVal,
$createSingleApiSummaryVal,
$createSingleApiDescriptionVal,
createTemplateJson,
templateJson,
List(UnknownError),
apiTagApiBuilder :: Nil
)"""
val deleteTemplateResourceCode: Term.ApplyInfix = q"""
resourceDocs += ResourceDoc(
deleteTemplate,
apiVersion,
"deleteTemplate",
"DELETE",
$deleteSingleApiUrlVal,
$deleteSingleApiSummaryVal,
$deleteSingleApiDescriptionVal,
emptyObjectJson,
emptyObjectJson.copy("true"),
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val getTemplateFromFilePartialFunction: Defn.Val = q"""
lazy val getTemplatesFromFile: OBPEndpoint = {
case ("file" :: $getApiUrlLiftweb :: Nil) JsonGet req =>
cc => {
for {
u <- $getMultipleAuthenticationStatement
resourceDocsJObject= jsonFromApisResource.\("resource_docs").children.asInstanceOf[List[JObject]]
getMethodJValue = resourceDocsJObject.filter(jObject => jObject.\("request_verb") == JString("GET")&& !jObject.\("request_url").asInstanceOf[JString].values.contains("_ID")).head
jsonObject = getMethodJValue \ "success_response_body"
} yield {
successJsonResponse(jsonObject)
}
}
}"""
val getTemplatesPartialFunction: Defn.Val = q"""
lazy val getTemplates: OBPEndpoint ={
case ($getApiUrlLiftweb:: Nil) JsonGet req =>
cc =>
{
for{
u <- $getMultipleAuthenticationStatement
templates <- APIBuilder_Connector.getTemplates
templatesJson = JsonFactory_APIBuilder.createTemplates(templates)
jsonObject:JValue = decompose(templatesJson)
}yield{
successJsonResponse(jsonObject)
}
}
}"""
val getTemplatePartialFunction: Defn.Val = q"""
lazy val getTemplate: OBPEndpoint ={
case ($getSingleApiUrlLiftweb :: templateId :: Nil) JsonGet _ => {
cc =>
{
for{
u <- $getSingleApiAuthenticationStatement
template <- APIBuilder_Connector.getTemplateById(templateId) ?~! $errorMessage
templateJson = JsonFactory_APIBuilder.createTemplate(template)
jsonObject:JValue = decompose(templateJson)
}yield{
successJsonResponse(jsonObject)
}
}
}
}"""
val createTemplatePartialFunction: Defn.Val = q"""
lazy val createTemplate: OBPEndpoint ={
case ($createApiUrlLiftweb:: Nil) JsonPost json -> _ => {
cc =>
{
for{
createTemplateJson <- tryo(json.extract[CreateTemplateJson]) ?~! InvalidJsonFormat
u <- $createSingleApiAuthenticationStatement
template <- APIBuilder_Connector.createTemplate(createTemplateJson)
templateJson = JsonFactory_APIBuilder.createTemplate(template)
jsonObject:JValue = decompose(templateJson)
}yield{
successJsonResponse(jsonObject)
}
}
}
}
"""
val deleteTemplatePartialFunction: Defn.Val = q"""
lazy val deleteTemplate: OBPEndpoint ={
case ($deleteApiUrlLiftweb :: templateId :: Nil) JsonDelete _ => {
cc =>
{
for{
u <- $deleteSingleApiAuthenticationStatement
template <- APIBuilder_Connector.getTemplateById(templateId) ?~! $errorMessage
deleted <- APIBuilder_Connector.deleteTemplate(templateId)
}yield{
if(deleted)
noContentJsonResponse
else
errorJsonResponse("Delete not completed")
}
}
}
}
"""
//List(author, pages, points)
val modelFieldsNames: List[String] = getModelFieldsNames(modelFieldsJValue)
//List(String, Int, Double)
val modelFieldsTypes: List[String] = getModelFieldsTypes(modelFieldsNames, modelFieldsJValue)
//List(Chinua Achebe, 209, 1.3)
val modelFieldsDefaultValues: List[Any] = getModelFieldDefaultValues(modelFieldsNames, modelFieldsJValue)
//List(author: String = `Chinua Achebe`, tutor: String = `1123123 1312`, pages: Int = 209, points: Double = 1.3)
val modelCaseClassParams: List[Term.Param] = getModelCaseClassParams(modelFieldsNames, modelFieldsTypes, modelFieldsDefaultValues)
//def createTemplate(createTemplateJson: CreateTemplateJson) = Full(
// MappedTemplate_6099750036365020434.create
// .mTemplateId(UUID.randomUUID().toString)
// .mAuthor(createTemplateJson.author)
// .mPages(createTemplateJson.pages)
// .mPoints(createTemplateJson.points)
// .saveMe())
val createModelJsonMethod: Defn.Def = generateCreateModelJsonMethod(modelFieldsNames, modelMappedName)
//trait Template { `_` =>
// def author: String
// def tutor: String
// def pages: Int
// def points: Double
// def templateId: String
//}
val modelTrait: Defn.Trait = getModelTrait(modelFieldsNames, modelFieldsTypes)
//class MappedTemplate extends Template with LongKeyedMapper[MappedTemplate] with IdPK {
// object mAuthor extends MappedString(this, 100)
// override def author: String = mAuthor.get
// object mPages extends MappedInt(this)
// override def pages: Int = mPages.get
// object mPoints extends MappedDouble(this)
// override def points: Double = mPoints.get
// def getSingleton = MappedTemplate
// object mTemplateId extends MappedString(this, 100)
// override def templateId: String = mTemplateId.get
//}
val modelClass = getModelClass(modelTypeName, modelTermName, modelFieldsNames, modelFieldsTypes)
val apiSource: Source = source"""
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.builder
import java.util.UUID
import code.api.builder.JsonFactory_APIBuilder._
import code.api.util.APIUtil._
import code.api.util.ApiTag._
import com.openbankproject.commons.util.ApiVersion
import code.api.util.ErrorMessages._
import net.liftweb.common.Full
import net.liftweb.http.rest.RestHelper
import net.liftweb.json
import net.liftweb.json.Extraction._
import net.liftweb.json._
import net.liftweb.mapper.By
import net.liftweb.util.Helpers.tryo
import scala.collection.immutable.Nil
import scala.collection.mutable.ArrayBuffer
trait APIMethods_APIBuilder
{
self: RestHelper =>
val ImplementationsBuilderAPI = new Object()
{
val apiVersion = ApiVersion.apiBuilder
val resourceDocs = ArrayBuffer[ResourceDoc]()
val apiRelations = ArrayBuffer[ApiRelation]()
val codeContext = CodeContext(resourceDocs, apiRelations)
implicit val formats = code.api.util.CustomJsonFormats.formats
$errorMessageVal;
def endpointsOfBuilderAPI = getTemplatesFromFile :: getTemplate :: createTemplate :: getTemplates :: deleteTemplate :: Nil
val jsonFromApisResource: JValue = getJValueFromJsonFile("apiBuilder/apisResource.json")
$getTemplateFromFileResourceCode
$getTemplateFromFilePartialFunction
$getTemplatesResourceCode
$getTemplatesPartialFunction
$getTemplateResourceCode
$getTemplatePartialFunction
$createTemplateResourceCode
$createTemplatePartialFunction
$deleteTemplateResourceCode
$deleteTemplatePartialFunction
}
}
object APIBuilder_Connector
{
val allAPIBuilderModels = List($modelTermName)
$createModelJsonMethod;
def getTemplates()= Full($modelTermName.findAll())
def getTemplateById(templateId: String)= $modelTermName.find(By($modelTermName.mTemplateId, templateId))
def deleteTemplate(templateId: String)= $modelTermName.find(By($modelTermName.mTemplateId, templateId)).map(_.delete_!)
}
import net.liftweb.mapper._
$modelClass
object $modelTermName extends $modelInit with LongKeyedMetaMapper[$modelTypeName] {}
$modelTrait
"""
/*
* ######################################JsonFactory_APIBuilder.scala###################################################
* */
//List(templateId:String = "11231231312" ,author: String = `Chinua Achebe`, tutor: String = `11231231312`, pages: Int = 209, points: Double = 1.3)
//Added the templatedId to `modelCaseClassParams`
val templateJsonClassParams = List(APIBuilderModel.templateIdField)++ modelCaseClassParams
//case class TemplateJson(templateId: String = """1123123 1312""", author: String = """Chinua Achebe""", tutor: String = """1123123 1312""", pages: Int = 209, points: Double = 1.3)
val TemplateJsonClass: Defn.Class = q"""case class TemplateJson(..$templateJsonClassParams) """
//case class Template(author: String = `Chinua Achebe`, pages: Int = 209, points: Double = 1.3)
//Note: No `templateId` in this class, the bank no need provide it, obp create a uuid for it.
val createTemplateJsonClass: Defn.Class = q"""case class CreateTemplateJson(..$modelCaseClassParams) """
//TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points)
val createTemplateJsonApply: Term.Apply = generateCreateTemplateJsonApply(modelFieldsNames)
//def createTemplate(template: Template) = TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points)
val createTemplateDef: Defn.Def =q"""def createTemplate(template: Template) = $createTemplateJsonApply"""
//def createTemplates(templates: List[Template]) = templates.map(template => TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points))
val createTemplatesDef: Defn.Def = q"""def createTemplates(templates: List[Template])= templates.map(template => $createTemplateJsonApply)"""
val jsonFactorySource: Source =source"""
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.builder
import code.api.util.APIUtil
$TemplateJsonClass
$createTemplateJsonClass
object JsonFactory_APIBuilder{
val templateJson = TemplateJson()
val templatesJson = List(templateJson)
val createTemplateJson = CreateTemplateJson()
$createTemplateDef;
$createTemplatesDef;
val allFields =
for (
v <- this.getClass.getDeclaredFields
//add guard, ignore the SwaggerJSONsV220.this and allFieldsAndValues fields
if (APIUtil.notExstingBaseClass(v.getName()))
)
yield {
v.setAccessible(true)
v.get(this)
}
}
"""
}

View File

@ -1,669 +0,0 @@
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.APIBuilder
import java.io.File
import java.nio.file.Files
import code.api.util.APIUtil
import net.liftweb.json.JsonAST.{JField, JObject, JString}
import net.liftweb.json.JValue
import scala.meta._
object APIBuilderModel
{
// you can modify this json file: OBP-API/obp-api/src/main/resources/apiBuilder/APIModelSource.json
def main(args: Array[String]) = overwriteApiCode(apiSource, jsonFactorySource)
def createTemplateJsonClass(className: String, templateJsonClassParams: List[Term.Param]) = q"""case class TemplateJson(..$templateJsonClassParams) """.copy(name = Type.Name(className))
def getApiUrl(jsonJValueFromFile: JValue) = {
val inputUrl = (jsonJValueFromFile \"request_url").asInstanceOf[JString].values
// if input is `my/template` --> `/my/template`
val checkedStartWith = inputUrl match {
case inputUrl if (!inputUrl.startsWith("""/""")) =>"""/"""+inputUrl
case _ => inputUrl
}
// if input is `/my/template/` --> `/my/template`
checkedStartWith.endsWith("""/""") match {
case true => checkedStartWith.dropRight(1)
case _ => checkedStartWith
}
} //eg: /my/template
def getModelName(jsonJValueFromFile: JValue) = jsonJValueFromFile.asInstanceOf[JObject].obj.map(_.name).filter(_!="request_url").head
def getModelFieldsNames(modelFieldsJValue: JValue)= modelFieldsJValue.asInstanceOf[JObject].obj.map(_.name)
def getModelFieldsTypes(modelFieldsNames: List[String], modelFieldsJValue: JValue)= modelFieldsNames
.map(key => modelFieldsJValue.findField{case JField(n, v) => n == key})
.map(_.get.value.getClass.getSimpleName.replaceFirst("J",""))
def getModelFieldDefaultValues(modelFieldsNames: List[String], modelFieldsJValue: JValue)= modelFieldsNames
.map(key => modelFieldsJValue.findField{case JField(n, v) => n == key})
.map(_.get.value.values)
def getModelTrait(modelFieldsNames: List[String], modelFieldTypes: List[String])= {
val methodStatements = for
{
i <- 0 until modelFieldsNames.size
methodName = Term.Name(modelFieldsNames(i).toLowerCase)
methodType = Type.Name(s"${modelFieldTypes(i)}")
} yield
Decl.Def(Nil, methodName, Nil, Nil, methodType)
//List(def author: String,
// def tutor: String,
// def pages: Int,
// def points: Double,
// def templateId: String)
val modelTraitMethods = methodStatements.toList++ List(Decl.Def(Nil, Term.Name("templateId"), Nil, Nil, Type.Name("String")))
val modelTraitSelf: Self = Self.apply(Name("_"), None)
//{
// `_` => def author: String
// def pages: Int
// def points: Double
// def templateId: String
//}
val modelTraitImpl = Template.apply(Nil, Nil, modelTraitSelf, modelTraitMethods)
// trait Template { `_` =>
// def author: String
// def tutor: String
// def pages: Int
// def points: Double
// def templateId: String
// }
q"""trait Template {}""".copy(templ = modelTraitImpl)
}
def getModelCaseClassParams(modelFieldsNames: List[String], modelFieldTypes: List[String], modelFieldDefaultValues: List[Any]) ={
val fieldNames = for {
i <- 0 until modelFieldsNames.size
modelFieldName = Term.Name(modelFieldsNames(i).toLowerCase)
modelFieldType = Type.Name(modelFieldTypes(i))
modelFieldDefaultValue = modelFieldDefaultValues(i) match{
case inputDefaultValue: String if (!inputDefaultValue.contains(" ")) => Term.Name(s"`$inputDefaultValue`")
case inputDefaultValue => Term.Name(s"$inputDefaultValue")
}} yield
Term.Param(Nil, modelFieldName, Some(modelFieldType), Some(modelFieldDefaultValue))
fieldNames.toList
}
def getAuthenticationStatement (needAuthentication: Boolean) = needAuthentication match {
case true => q"cc.user ?~ UserNotLoggedIn"
case false => q"Full(1) ?~ UserNotLoggedIn" //This will not throw error, only a placeholder
}
//object mAuthor extends MappedString(this, 100)
def stringToMappedObject(objectName: String, objectType: String): Defn.Object = {
val objectTermName = Term.Name(objectName)
objectType match {
case "String" => q"""object $objectTermName extends MappedString(this,100) """
case "Int" => q"""object $objectTermName extends MappedInt(this) """
case "Double" => q"""object $objectTermName extends MappedDouble(this) """
}
}
//override def author: String = mAuthor.get
def stringToMappedMethod(methodNameString: String, methodReturnTypeString: String): Defn.Def ={
val methodName = Term.Name(methodNameString)
val methodReturnType = Type.Name(methodReturnTypeString)
val mappedObject = Term.Name(s"m${methodNameString.capitalize}")
q"""override def $methodName: $methodReturnType = $mappedObject.get"""
}
def getModelClassStatements(modelFieldsNames: List[String], modelFieldTypes: List[String]) ={
val fieldNames = for
{
i <- 0 until modelFieldsNames.size
fieldNameString = modelFieldsNames(i)
fieldTypeString = modelFieldTypes(i)
mappedObject = stringToMappedObject(s"m${fieldNameString.capitalize}", fieldTypeString.capitalize)
mappedMethod = stringToMappedMethod(fieldNameString, fieldTypeString)
} yield
(mappedObject,mappedMethod)
fieldNames.flatMap (x => List(x._1, x._2)).toList
}
def getModelClass(modelTypeName: Type.Name, modelTermName: Term.Name, modelFieldsNames: List[String], modelFieldTypes: List[String]) ={
val modelClassStatements = getModelClassStatements(modelFieldsNames, modelFieldTypes)
val modelClassExample: Defn.Class = q"""
class $modelTypeName extends Template with LongKeyedMapper[$modelTypeName] with IdPK {
def getSingleton = $modelTermName
object mTemplateId extends MappedString(this,100)
override def templateId: String = mTemplateId.get
}"""
//Template with LongKeyedMapper[MappedTemplate] with IdPK {
// def getSingleton = MappedTemplate
// object mTemplateId extends MappedString(this, 100)
// override def templateId: String = mTemplateId.get
//}
val modelClassExampleTempl= modelClassExample.templ
//Template with LongKeyedMapper[MappedTemplate] with IdPK {
// override def author: String = mAuthor.get
// object mPages extends MappedInt(this)
// override def pages: Int = mPages.get
// object mPoints extends MappedDouble(this)
// override def points: Double = mPoints.get
// def getSingleton = MappedTemplate
// object mTemplateId extends MappedString(this, 100)
// override def templateId: String = mTemplateId.get
//}
val newTempls = modelClassExampleTempl.copy(stats = modelClassStatements++modelClassExampleTempl.stats)
//class MappedTemplate extends Template with LongKeyedMapper[MappedTemplate] with IdPK {
// object mAuthor extends MappedString(this, 100)
// override def author: String = mAuthor.get
// object mPages extends MappedInt(this)
// override def pages: Int = mPages.get
// object mPoints extends MappedDouble(this)
// override def points: Double = mPoints.get
// def getSingleton = MappedTemplate
// object mTemplateId extends MappedString(this, 100)
// override def templateId: String = mTemplateId.get
//}
modelClassExample.copy(templ = newTempls)
}
//def createTemplate(createTemplateJson: CreateTemplateJson) =
// Full(MappedTemplate_2145180497484573086.create
// .mTemplateId(UUID.randomUUID().toString)
// .mAuthor(createTemplateJson.author)
// .mPages(createTemplateJson.pages)
// .mPoints(createTemplateJson.points)
// .saveMe())"
def generateCreateModelJsonMethod(modelFieldsNames: List[String], modelMappedName: String)= {
val fieldNames = for {
i <- 0 until modelFieldsNames.size
fieldName = modelFieldsNames(i)
} yield
Term.Name(s".m${fieldName.capitalize}(createTemplateJson.${fieldName})")
val createModelJsonMethodFields = fieldNames.toList.mkString("")
val createModelJsonMethodBody: Term.Apply = q"""MappedTemplate.create.saveMe()""".copy(fun = Term.Name(s"$modelMappedName.create.mTemplateId(UUID.randomUUID().toString)$createModelJsonMethodFields.saveMe"))
q"""def createTemplate(createTemplateJson: CreateTemplateJson) = Full($createModelJsonMethodBody)"""
}
// TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points)
def generateCreateTemplateJsonApply(modelFieldsNames: List[String]): Term.Apply = {
val fieldNames = for{
i <- 0 until modelFieldsNames.size
} yield
Term.Name("template." + modelFieldsNames(i))
//List(template.templateId, template.author, template.tutor, template.pages, template.points)
val createTemplateJsonArgs = List(Term.Name("template.templateId")) ++ (fieldNames.toList)
q"""TemplateJson()""".copy(fun = Term.Name("TemplateJson"), args = createTemplateJsonArgs)
}
def overwriteCurrentFile(sourceCode: Source, path: String) = {
val builderAPIMethodsFile = new File(path)
builderAPIMethodsFile.getParentFile.mkdirs()
if(path.contains("APIMethods_APIBuilder"))
Files.write(
builderAPIMethodsFile.toPath,
sourceCode.syntax
//TODO,maybe fix later ! in scalameta, Term.Param(Nil, modelFieldName, Some(modelFieldType), Some(modelFieldDefaultValue)) => the default value should be a string in API code.
.replaceAll("""`""","")
.replaceAll("trait Template \\{ _ =>","trait Template \\{ `_` =>")
.replaceAll(""" :: ""","""" :: """")
.getBytes("UTF-8")
)
else
Files.write(
builderAPIMethodsFile.toPath,
sourceCode.syntax
//TODO,maybe fix later ! in scalameta, Term.Param(Nil, modelFieldName, Some(modelFieldType), Some(modelFieldDefaultValue)) => the default value should be a string in API code.
.replaceAll("""`""",""""""""")
.getBytes("UTF-8")
)
}
def overwriteApiCode(apiSource: Source, jsonFactorySource:Source =jsonFactorySource) = {
//APIMethods_APIBuilder.scala
overwriteCurrentFile(apiSource,"obp-api/src/main/scala/code/api/builder/APIMethods_APIBuilder.scala")
//JsonFactory_APIBuilder.scala
overwriteCurrentFile(jsonFactorySource, "obp-api/src/main/scala/code/api/builder/JsonFactory_APIBuilder.scala")
println("Congratulations! You make the new APIs. Please restart OBP-API server!")
}
val jsonJValueFromFile: JValue = APIUtil.getJValueFromJsonFile("apiBuilder/APIModelSource.json")
//"/templates"
val apiUrl= getApiUrl(jsonJValueFromFile)
//"template"
val modelName = getModelName(jsonJValueFromFile)
//TEMPLATE
val modelNameUpperCase = modelName.toUpperCase
//template
val modelNameLowerCase = modelName.toLowerCase
//Template
val modelNameCapitalized = modelNameLowerCase.capitalize
val modelFieldsJValue: JValue = jsonJValueFromFile \ modelName
//MappedTemplate_6285959801482269169
val modelMappedName = s"Mapped${modelNameCapitalized}_"+Math.abs(scala.util.Random.nextLong())
val modelTypeName: Type.Name = Type.Name(modelMappedName)
val modelTermName = Term.Name(modelMappedName)
val modelInit = Init.apply(Type.Name(modelMappedName), Term.Name(modelMappedName), Nil)
//getApiUrlVal: scala.meta.Lit.StrincreateModelJsonMethodField = "/templates"
val getApiUrlVal: Lit.String = Lit.String(s"$apiUrl")
//getSingleApiUrlVal: scala.meta.Lit.String = "/templates/TEMPLATE_ID"
val getSingleApiUrlVal = Lit.String(s"$apiUrl/${modelNameUpperCase}_ID")
//createSingleApiUrlVal: scala.meta.Lit.String = "/templates"
val createSingleApiUrlVal = Lit.String(s"$apiUrl")
//deleteSingleApiUrlVal: scala.meta.Lit.String = "/templates/TEMPLATE_ID"
val deleteSingleApiUrlVal = Lit.String(s"$apiUrl/${modelNameUpperCase}_ID")
//TODO, escape issue:return the space, I added quotes in the end: allSourceCode.syntax.replaceAll(""" :: ""","""" :: """")
//from "/my/template" --> "my :: template"
val apiUrlLiftFormat = apiUrl.replaceFirst("/", "").split("/").mkString("""""",""" :: ""","""""")
val apiUrlLiftweb: Lit.String = q""" "templates" """.copy(apiUrlLiftFormat)
val getApiSummaryVal: Lit.String = Lit.String(s"Get ${modelNameCapitalized}s")
val getSingleApiSummaryVal = Lit.String(s"Get ${modelNameCapitalized}")
val createSingleApiSummaryVal = Lit.String(s"Create ${modelNameCapitalized}")
val deleteSingleApiSummaryVal = Lit.String(s"Delete ${modelNameCapitalized}")
val getApiDescriptionVal: Lit.String = Lit.String(s"Return All ${modelNameCapitalized}s")
val getSingleApiDescriptionVal = Lit.String(s"Return One ${modelNameCapitalized} By Id")
val createSingleApiDescriptionVal = Lit.String(s"Create One ${modelNameCapitalized}")
val deleteSingleApiDescriptionVal = Lit.String(s"Delete One ${modelNameCapitalized}")
val errorMessageBody: Lit.String = Lit.String(s"OBP-31001: ${modelNameCapitalized} not found. Please specify a valid value for ${modelNameUpperCase}_ID.")
val errorMessageName: Pat.Var = Pat.Var(Term.Name(s"${modelNameCapitalized}NotFound"))
val errorMessageVal: Defn.Val = q"""val TemplateNotFound = $errorMessageBody""".copy(pats = List(errorMessageName))
val errorMessage: Term.Name = Term.Name(errorMessageVal.pats.head.toString())
val getPartialFuncTermName = Term.Name(s"get${modelNameCapitalized}s")
val getPartialFuncName = Pat.Var(getPartialFuncTermName)
val getSinglePartialFuncTermName = Term.Name(s"get${modelNameCapitalized}")
val getSinglePartialFuncName = Pat.Var(getSinglePartialFuncTermName)
val createPartialFuncTermName = Term.Name(s"create${modelNameCapitalized}")
val createPartialFuncName = Pat.Var(createPartialFuncTermName)
val deletePartialFuncTermName = Term.Name(s"delete${modelNameCapitalized}")
val deletePartialFuncName = Pat.Var(deletePartialFuncTermName)
//implementedApiDefBody: scala.meta.Term.Name = `getTemplates :: getTemplate :: createTemplate :: deleteTemplate :: Nil`
val implementedApiDefBody= Term.Name(s"${getPartialFuncTermName.value} :: ${getSinglePartialFuncTermName.value} :: ${createPartialFuncTermName.value} :: ${deletePartialFuncTermName.value} :: Nil")
//implementedApisDef: scala.meta.Defn.Def = def endpointsOfBuilderAPI = `getTemplates :: getTemplate :: createTemplate :: deleteTemplate :: Nil`
val implementedApisDef: Defn.Def = q"""def endpointsOfBuilderAPI = $implementedApiDefBody"""
val getTemplatesResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
$getPartialFuncTermName,
apiVersion,
${getPartialFuncTermName.value},
"GET",
$getApiUrlVal,
$getApiSummaryVal,
$getApiDescriptionVal,
emptyObjectJson,
templatesJson,
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val getTemplateResourceCode: Term.ApplyInfix = q"""
resourceDocs += ResourceDoc(
$getSinglePartialFuncTermName,
apiVersion,
${getSinglePartialFuncTermName.value},
"GET",
$getSingleApiUrlVal,
$getSingleApiSummaryVal,
$getSingleApiDescriptionVal,
emptyObjectJson,
templateJson,
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val createTemplateResourceCode: Term.ApplyInfix = q"""
resourceDocs += ResourceDoc(
$createPartialFuncTermName,
apiVersion,
${createPartialFuncTermName.value},
"POST",
$createSingleApiUrlVal,
$createSingleApiSummaryVal,
$createSingleApiDescriptionVal,
createTemplateJson,
templateJson,
List(UnknownError),
apiTagApiBuilder :: Nil
)"""
val deleteTemplateResourceCode: Term.ApplyInfix = q"""
resourceDocs += ResourceDoc(
$deletePartialFuncTermName,
apiVersion,
${deletePartialFuncTermName.value},
"DELETE",
$deleteSingleApiUrlVal,
$deleteSingleApiSummaryVal,
$deleteSingleApiDescriptionVal,
emptyObjectJson,
emptyObjectJson.copy("true"),
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val authenticationStatement: Term.ApplyInfix = getAuthenticationStatement(true)
val getTemplatesPartialFunction: Defn.Val = q"""
lazy val $getPartialFuncName: OBPEndpoint ={
case ($apiUrlLiftweb:: Nil) JsonGet req =>
cc =>
{
for{
u <- $authenticationStatement
templates <- APIBuilder_Connector.getTemplates
templatesJson = JsonFactory_APIBuilder.createTemplates(templates)
jsonObject:JValue = decompose(templatesJson)
}yield{
successJsonResponse(jsonObject)
}
}
}"""
val getTemplatePartialFunction: Defn.Val = q"""
lazy val $getSinglePartialFuncName: OBPEndpoint ={
case ($apiUrlLiftweb :: templateId :: Nil) JsonGet _ => {
cc =>
{
for{
u <- $authenticationStatement
template <- APIBuilder_Connector.getTemplateById(templateId) ?~! $errorMessage
templateJson = JsonFactory_APIBuilder.createTemplate(template)
jsonObject:JValue = decompose(templateJson)
}yield{
successJsonResponse(jsonObject)
}
}
}
}"""
val createTemplatePartialFunction: Defn.Val = q"""
lazy val $createPartialFuncName: OBPEndpoint ={
case ($apiUrlLiftweb:: Nil) JsonPost json -> _ => {
cc =>
{
for{
createTemplateJson <- tryo(json.extract[CreateTemplateJson]) ?~! InvalidJsonFormat
u <- $authenticationStatement
template <- APIBuilder_Connector.createTemplate(createTemplateJson)
templateJson = JsonFactory_APIBuilder.createTemplate(template)
jsonObject:JValue = decompose(templateJson)
}yield{
successJsonResponse(jsonObject)
}
}
}
}"""
val deleteTemplatePartialFunction: Defn.Val = q"""
lazy val $deletePartialFuncName: OBPEndpoint ={
case ($apiUrlLiftweb :: templateId :: Nil) JsonDelete _ => {
cc =>
{
for{
u <- $authenticationStatement
template <- APIBuilder_Connector.getTemplateById(templateId) ?~! $errorMessage
deleted <- APIBuilder_Connector.deleteTemplate(templateId)
}yield{
if(deleted)
noContentJsonResponse
else
errorJsonResponse("Delete not completed")
}
}
}
}"""
//List(author, pages, points)
val modelFieldsNames: List[String] = getModelFieldsNames(modelFieldsJValue)
//List(String, Int, Double)
val modelFieldsTypes: List[String] = getModelFieldsTypes(modelFieldsNames, modelFieldsJValue)
//List(Chinua Achebe, 209, 1.3)
val modelFieldsDefaultValues: List[Any] = getModelFieldDefaultValues(modelFieldsNames, modelFieldsJValue)
//List(author: String = `Chinua Achebe`, tutor: String = `1123123 1312`, pages: Int = 209, points: Double = 1.3)
val modelCaseClassParams: List[Term.Param] = getModelCaseClassParams(modelFieldsNames, modelFieldsTypes, modelFieldsDefaultValues)
// trait Template { `_` =>
// def author: String
// def tutor: String
// def pages: Int
// def points: Double
// def templateId: String
// }
val modelTrait: Defn.Trait = getModelTrait(modelFieldsNames, modelFieldsTypes)
//class MappedTemplate extends Template with LongKeyedMapper[MappedTemplate] with IdPK {
// object mAuthor extends MappedString(this, 100)
// override def author: String = mAuthor.get
// object mPages extends MappedInt(this)
// override def pages: Int = mPages.get
// object mPoints extends MappedDouble(this)
// override def points: Double = mPoints.get
// def getSingleton = MappedTemplate
// object mTemplateId extends MappedString(this, 100)
// override def templateId: String = mTemplateId.get
//}
val modelClass = getModelClass(modelTypeName, modelTermName, modelFieldsNames, modelFieldsTypes)
val createModelJsonMethod: Defn.Def = generateCreateModelJsonMethod(modelFieldsNames, modelMappedName)
val apiSource: Source = source"""
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.builder
import java.util.UUID
import code.api.builder.JsonFactory_APIBuilder._
import code.api.util.APIUtil._
import code.api.util.ApiTag._
import com.openbankproject.commons.util.ApiVersion
import code.api.util.ErrorMessages._
import net.liftweb.common.Full
import net.liftweb.http.rest.RestHelper
import net.liftweb.json
import net.liftweb.json.Extraction._
import net.liftweb.json._
import net.liftweb.mapper.By
import net.liftweb.util.Helpers.tryo
import scala.collection.immutable.Nil
import scala.collection.mutable.ArrayBuffer
trait APIMethods_APIBuilder
{
self: RestHelper =>
val ImplementationsBuilderAPI = new Object()
{
val apiVersion = ApiVersion.apiBuilder
val resourceDocs = ArrayBuffer[ResourceDoc]()
val apiRelations = ArrayBuffer[ApiRelation]()
val codeContext = CodeContext(resourceDocs, apiRelations)
implicit val formats = code.api.util.CustomJsonFormats.formats
$errorMessageVal
$implementedApisDef
$getTemplatesResourceCode
$getTemplatesPartialFunction
$getTemplateResourceCode
$getTemplatePartialFunction
$createTemplateResourceCode
$createTemplatePartialFunction
$deleteTemplateResourceCode
$deleteTemplatePartialFunction
}
}
object APIBuilder_Connector
{
val allAPIBuilderModels = List($modelTermName)
$createModelJsonMethod;
def getTemplates()= Full($modelTermName.findAll())
def getTemplateById(templateId: String)= $modelTermName.find(By($modelTermName.mTemplateId, templateId))
def deleteTemplate(templateId: String)= $modelTermName.find(By($modelTermName.mTemplateId, templateId)).map(_.delete_!)
}
import net.liftweb.mapper._
$modelClass
object $modelTermName extends $modelInit with LongKeyedMetaMapper[$modelTypeName] {}
$modelTrait
"""
/*
* ######################################JsonFactory_APIBuilder.scala###################################################
*/
//List(id:String = "11231231312" ,author: String = `Chinua Achebe`, tutor: String = `11231231312`, pages: Int = 209, points: Double = 1.3)
//Added the id to `modelCaseClassParams`
val templateIdField: Term.Param = Term.Param(Nil, Term.Name(s"id"), Some(Type.Name("String")), Some(Term.Name("`11231231312`")))
val templateJsonClassParams: List[Term.Param] = List(templateIdField)++ modelCaseClassParams
//case class TemplateJson(templateId: String = """1123123 1312""", author: String = """Chinua Achebe""", tutor: String = """1123123 1312""", pages: Int = 209, points: Double = 1.3)
val TemplateJsonClass: Defn.Class = q"""case class TemplateJson(..$templateJsonClassParams) """
//case class Template(author: String = `Chinua Achebe`, pages: Int = 209, points: Double = 1.3)
//Note: No `templateId` in this class, the bank no need provide it, obp create a uuid for it.
val createTemplateJsonClass: Defn.Class = q"""case class CreateTemplateJson(..$modelCaseClassParams) """
//TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points)
val createTemplateJsonApply: Term.Apply = generateCreateTemplateJsonApply(modelFieldsNames)
//def createTemplate(template: Template) = TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points)
val createTemplateDef: Defn.Def =q"""def createTemplate(template: Template) = $createTemplateJsonApply"""
//def createTemplates(templates: List[Template]) = templates.map(template => TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points))
val createTemplatesDef: Defn.Def = q"""def createTemplates(templates: List[Template])= templates.map(template => $createTemplateJsonApply)"""
val jsonFactorySource: Source =
source"""
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.builder
import code.api.util.APIUtil
$createTemplateJsonClass
$TemplateJsonClass
object JsonFactory_APIBuilder{
val templateJson = TemplateJson()
val templatesJson = List(templateJson)
val createTemplateJson = CreateTemplateJson()
$createTemplateDef;
$createTemplatesDef;
val allFields =
for (
v <- this.getClass.getDeclaredFields
//add guard, ignore the SwaggerJSONsV220.this and allFieldsAndValues fields
if (APIUtil.notExstingBaseClass(v.getName()))
)
yield {
v.setAccessible(true)
v.get(this)
}
}
"""
}

View File

@ -1,452 +0,0 @@
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.APIBuilder
import code.api.APIBuilder.APIBuilderModel._
import code.api.util.APIUtil
import net.liftweb.json.JsonAST.{JObject, JString}
import net.liftweb.json.{JArray, JValue}
import scala.meta._
object APIBuilderSwagger {
// you can modify this json file: OBP-API/obp-api/src/main/resources/apiBuilder/swaggerResource.json
def main(args: Array[String]): Unit = overwriteApiCode(apiSource,jsonFactorySource)
val jsonJValueFromFile: JValue = APIUtil.getJValueFromJsonFile("apiBuilder/swaggerResource.json")
val getSingleApiResponseBody: JValue = jsonJValueFromFile \\("foo")\"foo"\"value"
//"template"
val modelName = getModelName(getSingleApiResponseBody)
//All the fields in the template object.
val modelFieldsJValue: JValue = (getSingleApiResponseBody \modelName).children.head
//TEMPLATE
val modelNameUpperCase = modelName.toUpperCase
//template
val modelNameLowerCase = modelName.toLowerCase
//Template
val modelNameCapitalized = modelNameLowerCase.capitalize
//MappedTemplate_123123
val modelMappedName = s"Mapped${modelNameCapitalized}_"+Math.abs(scala.util.Random.nextLong())
val modelTypeName = Type.Name(modelMappedName)
val modelTermName = Term.Name(modelMappedName)
val modelInit =Init.apply(Type.Name(modelMappedName), Term.Name(modelMappedName), Nil)
val getMultipleApiSummary: String = ((jsonJValueFromFile \\"get"\\ "summary")\("summary")).asInstanceOf[JArray].children(0).asInstanceOf[JString].values
val getSingleApiSummary: String = ((jsonJValueFromFile \\"get"\\ "summary")\("summary")).asInstanceOf[JArray].children(1).asInstanceOf[JString].values
val deleteSingleApiSummary: String = ((jsonJValueFromFile \\"delete"\\ "summary")\("summary")).asInstanceOf[JString].values
val createSingleApiSummary: String = ((jsonJValueFromFile \\"post"\\ "summary")\("summary")).asInstanceOf[JString].values
val getApiDescription: String = ((jsonJValueFromFile \\"get"\\ "description").obj.head.value).asInstanceOf[JString].values
val getSingleDescription: String = ((jsonJValueFromFile \\"get"\\ "description").obj(3).value).asInstanceOf[JString].values
val createApiDescription: String = ((jsonJValueFromFile \\"post"\\ "description").obj.head.value).asInstanceOf[JString].values
val deleteApiDescription: String = ((jsonJValueFromFile \\"delete"\\ "description").obj.head.value).asInstanceOf[JString].values
val getMultipleApiAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(true)
val getSingleApiAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(true)
val deleteSingleApiAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(true)
val createSingleApiAuthenticationStatement: Term.ApplyInfix = getAuthenticationStatement(true)
val getMultipleApiUrl: String = (jsonJValueFromFile \\("paths")\"paths").asInstanceOf[JObject].obj(0).name
val getSingleApiUrl: String = (jsonJValueFromFile \\("paths")\"paths").asInstanceOf[JObject].obj(1).name
val getMultipleApiUrlVal = Lit.String(s"$getMultipleApiUrl")
val createSingleApiUrlVal = getMultipleApiUrl
val getApiUrlLiftFormat = getMultipleApiUrl.replaceFirst("/", "").split("/").mkString("""""",""" :: ""","""""")
val getApiUrlLiftweb: Lit.String = Lit.String(getApiUrlLiftFormat)
val createApiUrlLiftweb: Lit.String = Lit.String(getApiUrlLiftFormat)
val getSingleApiUrlVal = Lit.String(s"$getSingleApiUrl")
val deleteSingleApiUrlVal = Lit.String(s"$getSingleApiUrl")
val getSingleApiUrlLiftFormat = getSingleApiUrl.replaceFirst("/", "").split("/").dropRight(1).mkString("""""",""" :: ""","""""")
val getSingleApiUrlLiftweb: Lit.String = Lit.String(getSingleApiUrlLiftFormat)
val deleteApiUrlLiftweb: Lit.String = Lit.String(getSingleApiUrlLiftFormat)
val getMultipleApiSummaryVal = Lit.String(s"$getMultipleApiSummary")
val getSingleApiSummaryVal = Lit.String(s"$getSingleApiSummary")
val deleteSingleApiSummaryVal = Lit.String(s"$deleteSingleApiSummary")
val createSingleApiSummaryVal = Lit.String(s"$createSingleApiSummary")
val getMultipleApiDescriptionVal = Lit.String(s"$getApiDescription")
val createSingleApiDescriptionVal = Lit.String(s"$createApiDescription")
val getSingleApiDescriptionVal = Lit.String(s"$getSingleDescription")
val deleteSingleApiDescriptionVal = Lit.String(s"$deleteApiDescription")
val errorMessageBody: Lit.String = Lit.String(s"OBP-31001: ${modelNameCapitalized} not found. Please specify a valid value for ${modelNameUpperCase}_ID.")
val errorMessageName: Pat.Var = Pat.Var(Term.Name(s"${modelNameCapitalized}NotFound"))
val errorMessageVal: Defn.Val = q"""val TemplateNotFound = $errorMessageBody""".copy(pats = List(errorMessageName))
val errorMessage: Term.Name = Term.Name(errorMessageVal.pats.head.toString())
val getTemplatesResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
getTemplates,
apiVersion,
"getTemplates",
"GET",
$getMultipleApiUrlVal,
$getMultipleApiSummaryVal,
$getMultipleApiDescriptionVal,
emptyObjectJson,
templatesJson,
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val getTemplatesPartialFunction: Defn.Val = q"""
lazy val getTemplates: OBPEndpoint ={
case ($getApiUrlLiftweb:: Nil) JsonGet req =>
cc =>
{
for{
u <- $getMultipleApiAuthenticationStatement
templates <- APIBuilder_Connector.getTemplates
templatesJson = JsonFactory_APIBuilder.createTemplates(templates)
jsonObject:JValue = decompose(templatesJson)
}yield{
successJsonResponse(jsonObject)
}
}
}"""
val createTemplateResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
createTemplate,
apiVersion,
"createTemplate",
"POST",
$createSingleApiUrlVal,
$createSingleApiSummaryVal,
$createSingleApiDescriptionVal,
createTemplateJson,
templateJson,
List(UnknownError),
apiTagApiBuilder :: Nil
)"""
val createTemplatePartialFunction: Defn.Val = q"""
lazy val createTemplate: OBPEndpoint ={
case ($createApiUrlLiftweb:: Nil) JsonPost json -> _ => {
cc =>
{
for{
createTemplateJson <- tryo(json.extract[CreateTemplateJson]) ?~! InvalidJsonFormat
u <- $createSingleApiAuthenticationStatement
template <- APIBuilder_Connector.createTemplate(createTemplateJson)
templateJson = JsonFactory_APIBuilder.createTemplate(template)
jsonObject:JValue = decompose(templateJson)
}yield{
successJsonResponse(jsonObject)
}
}
}
}
"""
val getTemplateResourceCode: Term.ApplyInfix =q"""
resourceDocs += ResourceDoc(
getTemplate,
apiVersion,
"getTemplate",
"GET",
$getSingleApiUrlVal,
$getSingleApiSummaryVal,
$getSingleApiDescriptionVal,
emptyObjectJson,
templateJson,
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val getTemplatePartialFunction: Defn.Val = q"""
lazy val getTemplate: OBPEndpoint ={
case ($getSingleApiUrlLiftweb :: templateId :: Nil) JsonGet _ => {
cc =>
{
for{
u <- $getSingleApiAuthenticationStatement
template <- APIBuilder_Connector.getTemplateById(templateId) ?~! $errorMessage
templateJson = JsonFactory_APIBuilder.createTemplate(template)
jsonObject:JValue = decompose(templateJson)
}yield{
successJsonResponse(jsonObject)
}
}
}
}"""
val deleteTemplateResourceCode: Term.ApplyInfix = q"""
resourceDocs += ResourceDoc(
deleteTemplate,
apiVersion,
"deleteTemplate",
"DELETE",
$deleteSingleApiUrlVal,
$deleteSingleApiSummaryVal,
$deleteSingleApiDescriptionVal,
emptyObjectJson,
emptyObjectJson.copy("true"),
List(UserNotLoggedIn, UnknownError),
apiTagApiBuilder :: Nil
)"""
val deleteTemplatePartialFunction: Defn.Val = q"""
lazy val deleteTemplate: OBPEndpoint ={
case ($deleteApiUrlLiftweb :: templateId :: Nil) JsonDelete _ => {
cc =>
{
for{
u <- $deleteSingleApiAuthenticationStatement
template <- APIBuilder_Connector.getTemplateById(templateId) ?~! $errorMessage
deleted <- APIBuilder_Connector.deleteTemplate(templateId)
}yield{
if(deleted)
noContentJsonResponse
else
errorJsonResponse("Delete not completed")
}
}
}
}
"""
//List(author, pages, points)
val modelFieldsNames: List[String] = getModelFieldsNames(modelFieldsJValue)
//List(String, Int, Double)
val modelFieldsTypes: List[String] = getModelFieldsTypes(modelFieldsNames, modelFieldsJValue)
//List(Chinua Achebe, 209, 1.3)
val modelFieldsDefaultValues: List[Any] = getModelFieldDefaultValues(modelFieldsNames, modelFieldsJValue)
//List(author: String = `Chinua Achebe`, tutor: String = `1123123 1312`, pages: Int = 209, points: Double = 1.3)
val modelCaseClassParams: List[Term.Param] = getModelCaseClassParams(modelFieldsNames, modelFieldsTypes, modelFieldsDefaultValues)
//def createTemplate(createTemplateJson: CreateTemplateJson) = Full(
// MappedTemplate_6099750036365020434.create
// .mTemplateId(UUID.randomUUID().toString)
// .mAuthor(createTemplateJson.author)
// .mPages(createTemplateJson.pages)
// .mPoints(createTemplateJson.points)
// .saveMe())
val createModelJsonMethod: Defn.Def = generateCreateModelJsonMethod(modelFieldsNames, modelMappedName)
//trait Template { `_` =>
// def author: String
// def tutor: String
// def pages: Int
// def points: Double
// def templateId: String
//}
val modelTrait: Defn.Trait = getModelTrait(modelFieldsNames, modelFieldsTypes)
//class MappedTemplate extends Template with LongKeyedMapper[MappedTemplate] with IdPK {
// object mAuthor extends MappedString(this, 100)
// override def author: String = mAuthor.get
// object mPages extends MappedInt(this)
// override def pages: Int = mPages.get
// object mPoints extends MappedDouble(this)
// override def points: Double = mPoints.get
// def getSingleton = MappedTemplate
// object mTemplateId extends MappedString(this, 100)
// override def templateId: String = mTemplateId.get
//}
val modelClass = getModelClass(modelTypeName, modelTermName, modelFieldsNames, modelFieldsTypes)
val apiSource: Source = source"""
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.builder
import java.util.UUID
import code.api.builder.JsonFactory_APIBuilder._
import code.api.util.APIUtil._
import code.api.util.ApiTag._
import com.openbankproject.commons.util.ApiVersion
import code.api.util.ErrorMessages._
import net.liftweb.common.Full
import net.liftweb.http.rest.RestHelper
import net.liftweb.json
import net.liftweb.json.Extraction._
import net.liftweb.json._
import net.liftweb.mapper.By
import net.liftweb.util.Helpers.tryo
import scala.collection.immutable.Nil
import scala.collection.mutable.ArrayBuffer
trait APIMethods_APIBuilder
{
self: RestHelper =>
val ImplementationsBuilderAPI = new Object()
{
val apiVersion = ApiVersion.apiBuilder
val resourceDocs = ArrayBuffer[ResourceDoc]()
val apiRelations = ArrayBuffer[ApiRelation]()
val codeContext = CodeContext(resourceDocs, apiRelations)
implicit val formats = code.api.util.CustomJsonFormats.formats
$errorMessageVal;
def endpointsOfBuilderAPI = getTemplates :: createTemplate :: getTemplate :: deleteTemplate:: Nil
$getTemplatesResourceCode
$getTemplatesPartialFunction
$createTemplateResourceCode
$createTemplatePartialFunction
$getTemplateResourceCode
$getTemplatePartialFunction
$deleteTemplateResourceCode
$deleteTemplatePartialFunction
}
}
object APIBuilder_Connector
{
val allAPIBuilderModels = List($modelTermName)
$createModelJsonMethod;
def getTemplates()= Full($modelTermName.findAll())
def getTemplateById(templateId: String)= $modelTermName.find(By($modelTermName.mTemplateId, templateId))
def deleteTemplate(templateId: String)= $modelTermName.find(By($modelTermName.mTemplateId, templateId)).map(_.delete_!)
}
import net.liftweb.mapper._
$modelClass
object $modelTermName extends $modelInit with LongKeyedMetaMapper[$modelTypeName] {}
$modelTrait
"""
/*
* ######################################JsonFactory_APIBuilder.scala###################################################
* */
//List(templateId:String = "11231231312" ,author: String = `Chinua Achebe`, tutor: String = `11231231312`, pages: Int = 209, points: Double = 1.3)
//Added the templatedId to `modelCaseClassParams`
val templateJsonClassParams = List(APIBuilderModel.templateIdField)++ modelCaseClassParams
//case class TemplateJson(templateId: String = """1123123 1312""", author: String = """Chinua Achebe""", tutor: String = """1123123 1312""", pages: Int = 209, points: Double = 1.3)
val TemplateJsonClass: Defn.Class = q"""case class TemplateJson(..$templateJsonClassParams) """
//case class Template(author: String = `Chinua Achebe`, pages: Int = 209, points: Double = 1.3)
//Note: No `templateId` in this class, the bank no need provide it, obp create a uuid for it.
val createTemplateJsonClass: Defn.Class = q"""case class CreateTemplateJson(..$modelCaseClassParams) """
//TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points)
val createTemplateJsonApply: Term.Apply = generateCreateTemplateJsonApply(modelFieldsNames)
//def createTemplate(template: Template) = TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points)
val createTemplateDef: Defn.Def =q"""def createTemplate(template: Template) = $createTemplateJsonApply"""
//def createTemplates(templates: List[Template]) = templates.map(template => TemplateJson(template.templateId, template.author, template.tutor, template.pages, template.points))
val createTemplatesDef: Defn.Def = q"""def createTemplates(templates: List[Template])= templates.map(template => $createTemplateJsonApply)"""
val jsonFactorySource: Source =source"""
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.builder
import code.api.util.APIUtil
$TemplateJsonClass
$createTemplateJsonClass
object JsonFactory_APIBuilder{
val templateJson = TemplateJson()
val templatesJson = List(templateJson)
val createTemplateJson = CreateTemplateJson()
$createTemplateDef;
$createTemplatesDef;
val allFields =
for (
v <- this.getClass.getDeclaredFields
//add guard, ignore the SwaggerJSONsV220.this and allFieldsAndValues fields
if (APIUtil.notExstingBaseClass(v.getName()))
)
yield {
v.setAccessible(true)
v.get(this)
}
}
"""
}

View File

@ -5,7 +5,6 @@ import java.util.UUID.randomUUID
import code.api.OBPRestHelper
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.canGetCustomersJson
import code.api.builder.OBP_APIBuilder
import code.api.cache.Caching
import code.api.dynamic.endpoint.helper.{DynamicEndpointHelper, DynamicEndpoints}
import code.api.dynamic.entity.helper.DynamicEntityHelper
@ -125,7 +124,6 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth
logger.debug(s"getResourceDocsList says requestedApiVersion is $requestedApiVersion")
val resourceDocs = requestedApiVersion match {
case ApiVersion.`b1` => OBP_APIBuilder.allResourceDocs
case ApiVersion.v5_1_0 => OBPAPI5_1_0.allResourceDocs
case ApiVersion.v5_0_0 => OBPAPI5_0_0.allResourceDocs
case ApiVersion.v4_0_0 => OBPAPI4_0_0.allResourceDocs
@ -144,7 +142,6 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth
logger.debug(s"There are ${resourceDocs.length} resource docs available to $requestedApiVersion")
val versionRoutes = requestedApiVersion match {
case ApiVersion.`b1` => OBP_APIBuilder.routes
case ApiVersion.v5_1_0 => OBPAPI5_1_0.routes
case ApiVersion.v5_0_0 => OBPAPI5_0_0.routes
case ApiVersion.v4_0_0 => OBPAPI4_0_0.routes

View File

@ -5412,7 +5412,7 @@ object SwaggerDefinitionsJSON {
val allFieldsThisFile = ReflectUtils.getValues(this, List(nameOf(allFields)))
.filter(it => it != null && it.isInstanceOf[AnyRef])
.map(_.asInstanceOf[AnyRef])
allFieldsThisFile ++ JSONFactoryCustom300.allFields ++ SandboxData.allFields //++ JsonFactory_APIBuilder.allFields
allFieldsThisFile ++ JSONFactoryCustom300.allFields ++ SandboxData.allFields
}
}

View File

@ -1,89 +0,0 @@
package code.api.builder
import java.util.UUID
import code.api.builder.JsonFactory_APIBuilder._
import code.api.util.APIUtil._
import code.api.util.ApiTag._
import com.openbankproject.commons.util.ApiVersion
import code.api.util.ErrorMessages._
import net.liftweb.common.Full
import net.liftweb.http.rest.RestHelper
import net.liftweb.json
import net.liftweb.json.Extraction._
import net.liftweb.json._
import net.liftweb.mapper.By
import net.liftweb.util.Helpers.tryo
import scala.collection.immutable.Nil
import scala.collection.mutable.ArrayBuffer
trait APIMethods_APIBuilder { self: RestHelper =>
val ImplementationsBuilderAPI = new Object() {
val apiVersion = ApiVersion.b1
val resourceDocs = ArrayBuffer[ResourceDoc]()
val apiRelations = ArrayBuffer[ApiRelation]()
val codeContext = CodeContext(resourceDocs, apiRelations)
implicit val formats = code.api.util.CustomJsonFormats.formats
val TemplateNotFound = "OBP-31001: Template not found. Please specify a valid value for TEMPLATE_ID."
def endpointsOfBuilderAPI = getTemplates :: getTemplate :: createTemplate :: deleteTemplate :: Nil
resourceDocs += ResourceDoc(getTemplates, apiVersion, "getTemplates", "GET", "/templates", "Get Templates", "Return All Templates", emptyObjectJson, templatesJson, List(UserNotLoggedIn, UnknownError),apiTagApiBuilder :: Nil)
lazy val getTemplates: OBPEndpoint = {
case ("templates" :: Nil) JsonGet req =>
cc => {
for (u <- cc.user ?~ UserNotLoggedIn; templates <- APIBuilder_Connector.getTemplates; templatesJson = JsonFactory_APIBuilder.createTemplates(templates); jsonObject: JValue = decompose(templatesJson)) yield {
successJsonResponse(jsonObject)
}
}
}
resourceDocs += ResourceDoc(getTemplate, apiVersion, "getTemplate", "GET", "/templates/TEMPLATE_ID", "Get Template", "Return One Template By Id", emptyObjectJson, templateJson, List(UserNotLoggedIn, UnknownError),apiTagApiBuilder :: Nil)
lazy val getTemplate: OBPEndpoint = {
case ("templates" :: templateId :: Nil) JsonGet _ =>
cc => {
for (u <- cc.user ?~ UserNotLoggedIn; template <- APIBuilder_Connector.getTemplateById(templateId) ?~! TemplateNotFound; templateJson = JsonFactory_APIBuilder.createTemplate(template); jsonObject: JValue = decompose(templateJson)) yield {
successJsonResponse(jsonObject)
}
}
}
resourceDocs += ResourceDoc(createTemplate, apiVersion, "createTemplate", "POST", "/templates", "Create Template", "Create One Template", createTemplateJson, templateJson, List(UnknownError),apiTagApiBuilder :: Nil)
lazy val createTemplate: OBPEndpoint = {
case ("templates" :: Nil) JsonPost json -> _ =>
cc => {
for (createTemplateJson <- tryo(json.extract[CreateTemplateJson]) ?~! InvalidJsonFormat; u <- cc.user ?~ UserNotLoggedIn; template <- APIBuilder_Connector.createTemplate(createTemplateJson); templateJson = JsonFactory_APIBuilder.createTemplate(template); jsonObject: JValue = decompose(templateJson)) yield {
successJsonResponse(jsonObject)
}
}
}
resourceDocs += ResourceDoc(deleteTemplate, apiVersion, "deleteTemplate", "DELETE", "/templates/TEMPLATE_ID", "Delete Template", "Delete One Template", emptyObjectJson, emptyObjectJson.copy("true"), List(UserNotLoggedIn, UnknownError),apiTagApiBuilder :: Nil)
lazy val deleteTemplate: OBPEndpoint = {
case ("templates" :: templateId :: Nil) JsonDelete _ =>
cc => {
for (u <- cc.user ?~ UserNotLoggedIn; template <- APIBuilder_Connector.getTemplateById(templateId) ?~! TemplateNotFound; deleted <- APIBuilder_Connector.deleteTemplate(templateId)) yield {
if (deleted) noContentJsonResponse else errorJsonResponse("Delete not completed")
}
}
}
}
}
object APIBuilder_Connector {
val allAPIBuilderModels = List(MappedTemplate_2188356573920200339)
def createTemplate(createTemplateJson: CreateTemplateJson) = Full(MappedTemplate_2188356573920200339.create.mTemplateId(UUID.randomUUID().toString).mAuthor(createTemplateJson.author).mPages(createTemplateJson.pages).mPoints(createTemplateJson.points).saveMe())
def getTemplates() = Full(MappedTemplate_2188356573920200339.findAll())
def getTemplateById(templateId: String) = MappedTemplate_2188356573920200339.find(By(MappedTemplate_2188356573920200339.mTemplateId, templateId))
def deleteTemplate(templateId: String) = MappedTemplate_2188356573920200339.find(By(MappedTemplate_2188356573920200339.mTemplateId, templateId)).map(_.delete_!)
}
import net.liftweb.mapper._
class MappedTemplate_2188356573920200339 extends Template with LongKeyedMapper[MappedTemplate_2188356573920200339] with IdPK {
object mAuthor extends MappedString(this, 100)
override def author: String = mAuthor.get
object mPages extends MappedInt(this)
override def pages: Int = mPages.get
object mPoints extends MappedDouble(this)
override def points: Double = mPoints.get
def getSingleton = MappedTemplate_2188356573920200339
object mTemplateId extends MappedString(this, 100)
override def templateId: String = mTemplateId.get
}
object MappedTemplate_2188356573920200339 extends MappedTemplate_2188356573920200339 with LongKeyedMetaMapper[MappedTemplate_2188356573920200339]
trait Template { `_` =>
def author: String
def pages: Int
def points: Double
def templateId: String
}

View File

@ -1,15 +0,0 @@
package code.api.builder
import code.api.util.APIUtil
case class CreateTemplateJson(author: String = """Chinua Achebe""", pages: Int = 209, points: Double = 1.3)
case class TemplateJson(id: String = """11231231312""", author: String = """Chinua Achebe""", pages: Int = 209, points: Double = 1.3)
object JsonFactory_APIBuilder {
val templateJson = TemplateJson()
val templatesJson = List(templateJson)
val createTemplateJson = CreateTemplateJson()
def createTemplate(template: Template) = TemplateJson(template.templateId, template.author, template.pages, template.points)
def createTemplates(templates: List[Template]) = templates.map(template => TemplateJson(template.templateId, template.author, template.pages, template.points))
val allFields = for (v <- this.getClass.getDeclaredFields; if APIUtil.notExstingBaseClass(v.getName())) yield {
v.setAccessible(true)
v.get(this)
}
}

View File

@ -1,26 +0,0 @@
package code.api.builder
import code.api.OBPRestHelper
import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints}
import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus}
import code.util.Helper.MdcLoggable
object OBP_APIBuilder extends OBPRestHelper with APIMethods_APIBuilder with MdcLoggable {
val version = ApiVersion.b1
val versionStatus = ApiVersionStatus.DRAFT.toString
val endpoints = ImplementationsBuilderAPI.endpointsOfBuilderAPI
val allResourceDocs = ImplementationsBuilderAPI.resourceDocs
// Filter the possible endpoints by the disabled / enabled Props settings and add them together
val routes : List[OBPEndpoint] = getAllowedEndpoints(endpoints, ImplementationsBuilderAPI.resourceDocs)
// Make them available for use!
registerRoutes(routes, allResourceDocs, apiPrefix)
logger.info(s"version $version has been run! There are ${routes.length} routes.")
}

View File

@ -42,7 +42,6 @@ import code.api.OAuthHandshake._
import code.api.UKOpenBanking.v2_0_0.OBP_UKOpenBanking_200
import code.api.UKOpenBanking.v3_1_0.OBP_UKOpenBanking_310
import code.api.berlin.group.v1.OBP_BERLIN_GROUP_1
import code.api.builder.OBP_APIBuilder
import code.api.dynamic.endpoint.OBPAPIDynamicEndpoint
import code.api.dynamic.endpoint.helper.{DynamicEndpointHelper, DynamicEndpoints}
import code.api.oauth1a.Arithmetics
@ -2701,7 +2700,6 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
case ApiVersion.v5_1_0 => LiftRules.statelessDispatch.append(v5_1_0.OBPAPI5_1_0)
case ApiVersion.`dynamic-endpoint` => LiftRules.statelessDispatch.append(OBPAPIDynamicEndpoint)
case ApiVersion.`dynamic-entity` => LiftRules.statelessDispatch.append(OBPAPIDynamicEntity)
case ApiVersion.`b1` => LiftRules.statelessDispatch.append(OBP_APIBuilder)
case version: ScannedApiVersion => LiftRules.statelessDispatch.append(ScannedApis.versionMapScannedApis(version))
case _ => logger.info(s"There is no ${version.toString}")
}

View File

@ -64,7 +64,6 @@ object ApiTag {
val apiTagSigningBaskets = ResourceDocTag("Signing Baskets")
val apiTagUKOpenBanking = ResourceDocTag("UKOpenBanking")
val apiTagMXOpenFinance = ResourceDocTag("MXOpenFinance")
val apiTagApiBuilder = ResourceDocTag("API-Builder")
val apiTagAggregateMetrics = ResourceDocTag("Aggregate-Metrics")
val apiTagSystemIntegrity = ResourceDocTag("System-Integrity")
val apiTagWebhook = ResourceDocTag("Webhook")

View File

@ -20,7 +20,6 @@ object ApiVersionUtils {
v5_1_0 ::
`dynamic-endpoint` ::
`dynamic-entity` ::
b1::
scannedApis
def valueOf(value: String): ScannedApiVersion = {
@ -42,7 +41,6 @@ object ApiVersionUtils {
case v5_1_0.fullyQualifiedVersion | v5_1_0.apiShortVersion => v5_1_0
case `dynamic-endpoint`.fullyQualifiedVersion | `dynamic-endpoint`.apiShortVersion => `dynamic-endpoint`
case `dynamic-entity`.fullyQualifiedVersion | `dynamic-entity`.apiShortVersion => `dynamic-entity`
case b1.fullyQualifiedVersion | b1.apiShortVersion => b1
case version if(scannedApis.map(_.fullyQualifiedVersion).contains(version))
=>scannedApis.filter(_.fullyQualifiedVersion==version).head
case version if(scannedApis.map(_.apiShortVersion).contains(version))

View File

@ -1,213 +0,0 @@
/**
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
This product includes software developed at
TESOBE (http://www.tesobe.com/)
*/
package code.api.APIBuilder
import code.util.Helper.MdcLoggable
import org.scalatest.{FlatSpec, Matchers}
import scala.meta.{Defn, Term, Type}
import APIBuilderModel.{modelMappedName, _}
import net.liftweb.json
import net.liftweb.json.JValue
class APIBuilderModelTest extends FlatSpec with Matchers with MdcLoggable {
val jsonStringFromFile: String =
"""{
"request_url": "/templates",
"template": {
"author": "Chinua Achebe",
"pages": 209,
"points": 1.3
}
}"""
val jsonJValueFromFile: JValue = json.parse(jsonStringFromFile)
//"template"
val modelName = getModelName(jsonJValueFromFile)
//TEMPLATE
val modelNameUpperCase = modelName.toUpperCase
//template
val modelNameLowerCase = modelName.toLowerCase
//Template
val modelNameCapitalized = modelNameLowerCase.capitalize
//MappedTemplate_1
val modelMappedName = s"Mapped${modelNameCapitalized}_1"
val modelTypeName: Type.Name = Type.Name(modelMappedName)
val modelTermName = Term.Name(modelMappedName)
val modelFieldsJValue: JValue = jsonJValueFromFile \ modelName
val modelFieldsNames: List[String] = List("author", "pages", "points")
val modelFieldTypes: List[String] = List("String", "Int", "Double")
val modelFieldDefaultValues: List[Any] = List("Chinua Achebe", 209, 1.3)
"getApiUrl" should "work as expected" in {
val apiUrl: String = APIBuilderModel.getApiUrl(jsonJValueFromFile)
apiUrl should be ("/templates")
val jvalueMissingSlash: JValue = json.parse("""{"request_url":"templates/my"}""")
val apiUrl2: String = APIBuilderModel.getApiUrl(jvalueMissingSlash)
apiUrl2 should be ("/templates/my")
val jvalueWrongSlash: JValue = json.parse("""{"request_url":"templates/my/"}""")
val apiUrl3: String = APIBuilderModel.getApiUrl(jvalueMissingSlash)
apiUrl3 should be ("/templates/my")
}
"getModelName" should "work as expected" in {
val apiUrl: String = APIBuilderModel.getModelName(jsonJValueFromFile)
apiUrl should be ("template")
}
"getModelFieldsNames" should "work as expected" in {
val modelFieldsNames: List[String] = APIBuilderModel.getModelFieldsNames(modelFieldsJValue)
modelFieldsNames should be (List("author", "pages", "points"))
}
"getModelFieldsTypes" should "work as expected" in {
val modelFieldsTypes: List[String] = APIBuilderModel.getModelFieldsTypes(modelFieldsNames, modelFieldsJValue)
modelFieldsTypes should be (List("String", "Int", "Double"))
}
"getModelFieldDefaultValues" should "work as expected" in {
val modelFieldsTypes: List[Any] = APIBuilderModel.getModelFieldDefaultValues(modelFieldsNames, modelFieldsJValue)
modelFieldsTypes should be (List("Chinua Achebe", 209, 1.3))
}
"getModelTraitMethods" should "work as expected" in {
val modelTrait: Defn.Trait = APIBuilderModel.getModelTrait(modelFieldsNames, modelFieldTypes)
modelTrait.toString() should be (
"trait Template { `_` =>" +
"\n def author: String" +
"\n def pages: Int" +
"\n def points: Double" +
"\n def templateId: String" +
"\n" +
"}")
}
"getModelCaseClassParams" should "work as expected" in {
val modelCaseClassParams: List[Term.Param] = APIBuilderModel.getModelCaseClassParams(modelFieldsNames, modelFieldTypes, modelFieldDefaultValues)
modelCaseClassParams.toString() should be (
"List(" +
"author: String = `Chinua Achebe`, " +
"pages: Int = 209, " +
"points: Double = 1.3)")
}
"changeStringToMappedObject" should "work as expected" in {
val stringObjectName = "Author"
val stringObjectType = "String"
val stringMappedObject= APIBuilderModel.stringToMappedObject(stringObjectName, stringObjectType)
stringMappedObject.toString() should be ("object Author extends MappedString(this, 100)")
val intObjectName = 123
val intObjectType = "Int"
val intMappedObject= APIBuilderModel.stringToMappedObject(stringObjectName, intObjectType)
intMappedObject.toString() should be ("object Author extends MappedInt(this)")
val doubleObjectName = 123.1231
val doubleObjectType = "Double"
val doubleMappedObject= APIBuilderModel.stringToMappedObject(stringObjectName, doubleObjectType)
doubleMappedObject.toString() should be ("object Author extends MappedDouble(this)")
}
"stringToMappedMethod" should "work as expected" in {
val methodName = "author"
val methodReturnType = "String"
val mappedMethod= APIBuilderModel.stringToMappedMethod(methodName, methodReturnType)
mappedMethod.toString() should be ("override def author: String = mAuthor.get")
}
"getModelClassStatements" should "work as expected" in {
val modelClassStatements= APIBuilderModel.getModelClassStatements(modelFieldsNames, modelFieldTypes)
modelClassStatements.toString() should be (
"List(" +
"object mAuthor extends MappedString(this, 100), " +
"override def author: String = mAuthor.get, " +
"object mPages extends MappedInt(this), " +
"override def pages: Int = mPages.get, " +
"object mPoints extends MappedDouble(this), " +
"override def points: Double = mPoints.get)" +
"")
}
"getModelClass" should "work as expected" in {
val modelClass= APIBuilderModel.getModelClass(modelTypeName, modelTermName, modelFieldsNames, modelFieldTypes)
modelClass.toString() should be (
"class MappedTemplate_1 extends Template with LongKeyedMapper[MappedTemplate_1] with IdPK {" +
"\n object mAuthor extends MappedString(this, 100)" +
"\n override def author: String = mAuthor.get" +
"\n object mPages extends MappedInt(this)" +
"\n override def pages: Int = mPages.get" +
"\n object mPoints extends MappedDouble(this)" +
"\n override def points: Double = mPoints.get" +
"\n def getSingleton = MappedTemplate_1" +
"\n object mTemplateId extends MappedString(this, 100)" +
"\n override def templateId: String = mTemplateId.get" +
"\n" +
"}")
}
"generateCreateModelJsonMethod" should "work as expected" in {
val createModelJsonMethod= APIBuilderModel.generateCreateModelJsonMethod(modelFieldsNames, modelMappedName)
createModelJsonMethod.toString() should be (
"def createTemplate(createTemplateJson: CreateTemplateJson) = " +
"Full(MappedTemplate_1.create" +
".mTemplateId(UUID.randomUUID().toString)" +
".mAuthor(createTemplateJson.author)" +
".mPages(createTemplateJson.pages)" +
".mPoints(createTemplateJson.points)" +
".saveMe())")
}
"generateCreateTemplateJsonApply" should "work as expected" in {
val createTemplateJsonApply= APIBuilderModel.generateCreateTemplateJsonApply(modelFieldsNames)
createTemplateJsonApply.toString() should be ("TemplateJson(template.templateId, template.author, template.pages, template.points)")
}
"getAuthenticationStatement" should "work as expected" in {
val needAuth= APIBuilderModel.getAuthenticationStatement(true)
needAuth.toString() should be ("cc.user ?~ UserNotLoggedIn")
val notNeedAuth= APIBuilderModel.getAuthenticationStatement(false)
notNeedAuth.toString() should be ("Full(1) ?~ UserNotLoggedIn")
}
"createTemplateJsonClass" should "work as expected" in {
val className ="Template"
val templateIdField: Term.Param = Term.Param(Nil, Term.Name(s"template_id"), Some(Type.Name("String")), Some(Term.Name("`11231231312`")))
val templateJsonClassParams = List(templateIdField)
val templateJsonClass: Defn.Class = APIBuilderModel.createTemplateJsonClass(className, templateJsonClassParams)
templateJsonClass.toString() should be ("case class Template(template_id: String = `11231231312`)")
}
}

View File

@ -8,7 +8,6 @@ import net.liftweb.json.{Formats, JField, JObject, JString, JsonAST}
object ApiStandards extends Enumeration {
type ApiStandards = Value
val obp = Value
val `api-builder` = Value("api-builder")
}
object ApiShortVersions extends Enumeration {
@ -24,7 +23,6 @@ object ApiShortVersions extends Enumeration {
val `v4.0.0` = Value("v4.0.0")
val `v5.0.0` = Value("v5.0.0")
val `v5.1.0` = Value("v5.1.0")
val b1 = Value
val `dynamic-endpoint` = Value("dynamic-endpoint")
val `dynamic-entity` = Value("dynamic-entity")
}
@ -118,9 +116,6 @@ object ApiVersion {
val `dynamic-endpoint` = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`dynamic-endpoint`.toString)
val `dynamic-entity` = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`dynamic-entity`.toString)
//This is generated by scala-meta:
val b1 = ScannedApiVersion(urlPrefix,ApiStandards.`api-builder`.toString, ApiShortVersions.b1.toString)
//This is OBP standard version:
val standardVersions =
v1_2_1 ::
@ -134,7 +129,6 @@ object ApiVersion {
v4_0_0 ::
v5_0_0 ::
v5_1_0 ::
b1 ::
`dynamic-endpoint` ::
`dynamic-entity`::
Nil