simple api model

This commit is contained in:
gowthaman.b
2023-11-05 12:57:11 +05:30
commit f54509cfa4
25 changed files with 847 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
package com.readymixerp
import com.readymixerp.domain.DataModel
import com.readymixerp.domain.Session
import com.readymixerp.domain.Session.database
import io.ebean.DuplicateKeyException
import io.ebean.RawSql
import io.ebean.RawSqlBuilder
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.before
import io.javalin.apibuilder.ApiBuilder.get
import io.javalin.apibuilder.ApiBuilder.post
import io.javalin.apibuilder.ApiBuilder.delete
import io.javalin.apibuilder.ApiBuilder.path
import io.javalin.apibuilder.ApiBuilder.put
import io.javalin.apibuilder.ApiBuilder.patch
import io.javalin.http.*
import io.javalin.json.JavalinJackson
import io.javalin.plugin.bundled.CorsContainer
import java.time.LocalDateTime
fun main(args: Array<String>) {
Javalin
.create { cfg ->
cfg.http.generateEtags = true
cfg.plugins.enableCors { container ->
container.add {
it.allowHost(
"http://localhost:5173",
"https://www.readymixerp.com",
"https://app.readymixerp.com"
)
}
}
cfg.http.defaultContentType = ContentType.JSON
cfg.compression.gzipOnly()
cfg.jsonMapper(JavalinJackson(Session.objectMapper))
}
.routes {
before("/*") {
//validate, auth token
}
path("/api") {
get("/{entity}/{id}") {
it.json(
database.find(DataModel::class.java, it.pathParam("id")) ?: throw NotFoundResponse()
)
}
post("/{entity}/query") {
val sql = it.bodyAsClass<Query>()
it.json(
database.find(DataModel::class.java)
.setRawSql(
RawSqlBuilder.parse(sql.sql).create()
).apply {
sql.params.forEach { (t, u) ->
setParameter(t, u)
}
}
.findList()
)
}
post("/{entity}") {
database.save(
it.bodyAsClass<DataModel>()
)
}
put("/{entity}/{id}") {
val e = database.find(DataModel::class.java, it.pathParam("id")) ?: throw NotFoundResponse()
val newData = it.bodyAsClass<Map<String,Any>>()
e.data.putAll(newData)
e.update()
}
patch("/{entity}/{id}") {
val e = database.find(DataModel::class.java, it.pathParam("id")) ?: throw NotFoundResponse()
val pv = it.bodyAsClass<PatchValue>()
e.data[pv.key] = pv.value;
e.update()
}
delete("/{entity}/{id}") {
val id = it.pathParam("id")
val e = database.find(DataModel::class.java, id) ?: throw NotFoundResponse()
e.deletedBy = Session.currentUser()
e.deletedOn = LocalDateTime.now()
e.update()
e.delete()
}
}
}
.exception(DuplicateKeyException::class.java) { _, ctx ->
ctx.json(
mapOf(
"error" to "Duplicate Data"
)
).status(HttpStatus.CONFLICT)
}
.start(9001)
}
data class Query(
val sql: String,
val params: Map<String, Any>
)
data class PatchValue(val key: String, val value: Any)

View File

@@ -0,0 +1,39 @@
package com.readymixerp.domain
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import io.ebean.Database
import io.ebean.DatabaseFactory
import io.ebean.config.CurrentTenantProvider
import io.ebean.config.CurrentUserProvider
import io.ebean.config.DatabaseConfig
import io.ebean.config.TenantMode
data class CurrentUser(
val anon: Boolean = true,
val userId:Long = 0,
val tenantId: Long = 0
)
object Session {
private val currentUser = object: ThreadLocal<CurrentUser>() {
override fun initialValue(): CurrentUser {
return CurrentUser()
}
}
private val sc = DatabaseConfig().apply {
loadFromProperties()
tenantMode = TenantMode.PARTITION
currentTenantProvider = CurrentTenantProvider { currentUser.get().tenantId }
currentUserProvider = CurrentUserProvider { currentUser.get().userId }
}
val database: Database = DatabaseFactory.create(sc)
val objectMapper = jacksonObjectMapper().apply {
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
findAndRegisterModules()
}
fun currentUser() = currentUser.get().userId
}

View File

@@ -0,0 +1,19 @@
package com.readymixerp.domain
import io.ebean.annotation.Platform
import io.ebean.dbmigration.DbMigration
object DBMigration {
fun create(){
val dbMigration: DbMigration = DbMigration.create()
dbMigration.setPlatform(Platform.POSTGRES)
dbMigration.generateMigration()
}
@JvmStatic
fun main(args: Array<String>) {
create()
}
}

View File

@@ -0,0 +1,69 @@
package com.readymixerp.domain
import io.ebean.Model
import io.ebean.annotation.DbArray
import io.ebean.annotation.DbJsonB
import io.ebean.annotation.SoftDelete
import io.ebean.annotation.TenantId
import io.ebean.annotation.WhenCreated
import io.ebean.annotation.WhenModified
import io.ebean.annotation.WhoCreated
import io.ebean.annotation.WhoModified
import java.time.LocalDateTime
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.MappedSuperclass
import javax.persistence.Version
data class Comments(val text: String = "", val by: String = "", val at: LocalDateTime = LocalDateTime.now())
@MappedSuperclass
abstract class BaseModel : Model() {
@Id
@GeneratedValue
var id: Long = 0
@SoftDelete
var deleted: Boolean = false
@Version
var version: Int = 0
@WhenCreated
var createdAt: LocalDateTime = LocalDateTime.now()
@WhenModified
var modifiedAt: LocalDateTime? = null
@TenantId
var tenantId: Long = 0L
@WhoCreated
var createdBy: Long = 0L
@WhoModified
var modifiedBy: Long? = null
var deletedOn: LocalDateTime? = null
var deletedBy: Long? = null
@DbJsonB
var data: MutableMap<String, Any> = hashMapOf()
@DbArray
var tags: MutableList<String> = arrayListOf()
@DbJsonB
var comments: MutableList<Comments> = arrayListOf()
}
@Entity
open class DataModel : BaseModel() {
var uniqueIdentifier: String = ""
var entityName: String = ""
}