removed DB module as well (useless)
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
fixing problems occured with ZIO, the app now compilesdrone-setup
parent
1650d472d1
commit
99f182502a
@ -0,0 +1,6 @@
|
|||||||
|
database {
|
||||||
|
dataSourceClassName = org.sqlite.SQLiteDataSource
|
||||||
|
dataSource {
|
||||||
|
url = "jdbc:sqlite:database.sqlite;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:table_init.sql'"
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
#may not be a public url
|
#may not be a public url
|
||||||
emitter.url=localhost:4454
|
emitter.url=<server url here>
|
||||||
eme=dzq=d=qzd=qz=d
|
emitter.cert=<x509 certificate path here>
|
||||||
|
|
||||||
|
endpoint.port=<enter port here>
|
@ -1,8 +1,8 @@
|
|||||||
CREATE TABLE user
|
CREATE TABLE user
|
||||||
(
|
(
|
||||||
id varchar(32) PRIMARY KEY,
|
id varchar(32) PRIMARY KEY,
|
||||||
name varchar(30) NOT NULL,
|
|
||||||
mail_address varchar NOT NULL UNIQUE,
|
mail_address varchar NOT NULL UNIQUE,
|
||||||
|
name varchar(30) NOT NULL,
|
||||||
forename varchar(30) NOT NULL,
|
forename varchar(30) NOT NULL,
|
||||||
password_hash varchar
|
password_hash varchar
|
||||||
);
|
);
|
@ -1,28 +0,0 @@
|
|||||||
package org.tbasket
|
|
||||||
|
|
||||||
import io.getquill.{Literal, SqliteDialect}
|
|
||||||
import io.getquill.context.qzio.ZioContext
|
|
||||||
import org.tbasket.endpoint.Endpoint
|
|
||||||
import org.tbasket.handler.LoginHandler
|
|
||||||
|
|
||||||
import java.util.Properties
|
|
||||||
|
|
||||||
object EndpointSetup:
|
|
||||||
|
|
||||||
private final val EndpointPort = "endpoint.port"
|
|
||||||
private final val EndpointPortDefault = "48485"
|
|
||||||
|
|
||||||
def setupEndpoint(config: Properties): Endpoint =
|
|
||||||
Main.LOG.debug("Initializing API endpoint...")
|
|
||||||
|
|
||||||
createEndpoint(config)
|
|
||||||
|
|
||||||
private def createEndpoint(config: Properties): Endpoint =
|
|
||||||
val port = config
|
|
||||||
.getProperty(EndpointPort, EndpointPortDefault) match
|
|
||||||
case s"$port" if port.toIntOption.isDefined => port.toInt
|
|
||||||
case v =>
|
|
||||||
throw new InternalBasketServerException(
|
|
||||||
s"$EndpointPort property value is wrong: $v must be integer"
|
|
||||||
)
|
|
||||||
new Endpoint(port)
|
|
@ -0,0 +1,83 @@
|
|||||||
|
package org.tbasket
|
||||||
|
|
||||||
|
import org.tbasket.ServerConfig.CertFactory
|
||||||
|
import pdi.jwt.JwtAlgorithm
|
||||||
|
import zio.{Chunk, Task, ZIO, ZIOAppArgs}
|
||||||
|
import zio.http.URL
|
||||||
|
import zio.stream.ZStream
|
||||||
|
import pdi.jwt.algorithms.JwtAsymmetricAlgorithm
|
||||||
|
|
||||||
|
import java.nio.file.{Files, Path}
|
||||||
|
import java.security.cert.{Certificate, CertificateFactory}
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
|
class ServerConfig private(userProperties: Properties, schema: Properties, arguments: Map[String, String]) {
|
||||||
|
|
||||||
|
private def getPropertySafe(name: String) =
|
||||||
|
if (schema.getProperty(name) == null) {
|
||||||
|
throw new ServerConfigException(
|
||||||
|
s"""
|
||||||
|
| current config seems expired : property $name should not be present in your config
|
||||||
|
| (maybe this server has a newer version than the configuration and its was modified)
|
||||||
|
| config schema :
|
||||||
|
|
|
||||||
|
|$schemaString
|
||||||
|
|
|
||||||
|
| You may try to adapt your old config version with new schema
|
||||||
|
|""".stripMargin)
|
||||||
|
}
|
||||||
|
Option(userProperties.getProperty(name)) match
|
||||||
|
case Some(value) => value
|
||||||
|
case None =>
|
||||||
|
arguments.getOrElse(name, throw new ServerConfigException(
|
||||||
|
s"""
|
||||||
|
| could not find property in server configuration : $name
|
||||||
|
| config schema :
|
||||||
|
|
|
||||||
|
|$schemaString
|
||||||
|
|
|
||||||
|
| This property is required.
|
||||||
|
|""".stripMargin))
|
||||||
|
|
||||||
|
val emitterURL: URL = URL.fromString(getPropertySafe("emitter.url")) match
|
||||||
|
case Left(exception) => throw exception
|
||||||
|
case Right(value) => value
|
||||||
|
|
||||||
|
val emitterCertificate: Certificate = {
|
||||||
|
val path = Path.of(getPropertySafe("emitter.cert"))
|
||||||
|
val in = Files.newInputStream(path)
|
||||||
|
CertFactory.generateCertificate(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
val emitterCertificateAlgorithm = JwtAlgorithm.RS256
|
||||||
|
|
||||||
|
val endpointPort: Int =
|
||||||
|
getPropertySafe("endpoint.port")
|
||||||
|
.toIntOption
|
||||||
|
.getOrElse(throw new ServerConfigException("endpoint.port is not an integer"))
|
||||||
|
|
||||||
|
private def schemaString = {
|
||||||
|
schema.stringPropertyNames()
|
||||||
|
.toArray(new Array[String](_))
|
||||||
|
.map(key => s"$key=${schema.getProperty(key)}")
|
||||||
|
.mkString("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object ServerConfig {
|
||||||
|
//TODO make certificate type configurable
|
||||||
|
final val CertFactory = CertificateFactory.getInstance("X509")
|
||||||
|
|
||||||
|
def apply(userProperties: Properties, arguments: Seq[String]): Task[ServerConfig] = ZIO.attempt {
|
||||||
|
val args = arguments.map {
|
||||||
|
case s"$key=$value" => (key, value)
|
||||||
|
case x => throw new ServerConfigException(s"configuration parameter must be of format 'property.name=value' received : ${x}")
|
||||||
|
}.toMap
|
||||||
|
val schemaIn = getClass.getClassLoader.getResourceAsStream("server.properties")
|
||||||
|
val schema = new Properties()
|
||||||
|
schema.load(schemaIn)
|
||||||
|
new ServerConfig(userProperties, schema, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package org.tbasket
|
||||||
|
|
||||||
|
class ServerConfigException(msg: String) extends Exception(msg) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package org.tbasket.data
|
||||||
|
|
||||||
|
import io.getquill.context.ZioJdbc.{DataSourceLayer, QuillZioExt}
|
||||||
|
import io.getquill.context.qzio.ZioContext
|
||||||
|
import io.getquill.idiom.Idiom
|
||||||
|
import io.getquill.jdbczio.Quill
|
||||||
|
import io.getquill.*
|
||||||
|
import org.sqlite.SQLiteDataSource
|
||||||
|
import org.tbasket.ServerConfig
|
||||||
|
import zio.*
|
||||||
|
|
||||||
|
import java.io.Closeable
|
||||||
|
import java.util.Properties
|
||||||
|
import javax.sql
|
||||||
|
|
||||||
|
class Database(config: ServerConfig):
|
||||||
|
|
||||||
|
val contextLayer = ZLayer.succeed(new SqliteZioJdbcContext(SnakeCase))
|
||||||
|
val datasourceLayer = Quill.DataSource.fromPrefix("database")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
package org.tbasket.data
|
||||||
|
|
||||||
|
import io.getquill.*
|
||||||
|
|
||||||
|
case class Member(team: Team, user: User, admin: Boolean)
|
@ -0,0 +1,6 @@
|
|||||||
|
package org.tbasket.data
|
||||||
|
|
||||||
|
import io.getquill.*
|
||||||
|
|
||||||
|
case class Tactic(id: Int, name: String, owner: User, filePath: String)
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
package org.tbasket.data
|
||||||
|
|
||||||
|
import io.getquill.*
|
||||||
|
|
||||||
|
case class Team(id: Int, name: String, clubName: String)
|
@ -1,7 +1,6 @@
|
|||||||
package org.tbasket.db.schemas
|
package org.tbasket.data
|
||||||
|
|
||||||
import io.getquill.*
|
import io.getquill.*
|
||||||
import org.tbasket.db.Database
|
|
||||||
|
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
path=database.sqlite
|
|
@ -1,21 +0,0 @@
|
|||||||
package org.tbasket.db
|
|
||||||
|
|
||||||
import io.getquill.context.ZioJdbc.{DataSourceLayer, QuillZioExt}
|
|
||||||
import io.getquill.context.qzio.ZioContext
|
|
||||||
import io.getquill.{Literal, SnakeCase, SqliteDialect, SqliteZioJdbcContext}
|
|
||||||
import org.sqlite.SQLiteDataSource
|
|
||||||
import zio.*
|
|
||||||
|
|
||||||
import java.io.Closeable
|
|
||||||
import java.util.Properties
|
|
||||||
import javax.sql
|
|
||||||
|
|
||||||
class Database(config: Properties):
|
|
||||||
|
|
||||||
val layer = ZLayer.succeed(new SqliteZioJdbcContext(SnakeCase))
|
|
||||||
|
|
||||||
object Database:
|
|
||||||
val ctx = new SqliteZioJdbcContext(SnakeCase)
|
|
||||||
|
|
||||||
import ctx.*
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
package org.tbasket.db.schemas
|
|
||||||
|
|
||||||
import io.getquill.*
|
|
||||||
import org.tbasket.db.Database
|
|
||||||
|
|
||||||
case class Member(team: Team, user: User, admin: Boolean)
|
|
||||||
|
|
||||||
object Member:
|
|
||||||
|
|
||||||
import Database.ctx.*
|
|
||||||
|
|
||||||
val schema = quote {
|
|
||||||
querySchema[Member](
|
|
||||||
"member",
|
|
||||||
_.team.id -> "team_id",
|
|
||||||
_.user.id -> "user_id",
|
|
||||||
_.admin -> "is_admin"
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package org.tbasket.db.schemas
|
|
||||||
|
|
||||||
import io.getquill.*
|
|
||||||
|
|
||||||
import org.tbasket.db.Database
|
|
||||||
case class Tactic(id: Int, name: String, owner: User, filePath: String)
|
|
||||||
|
|
||||||
object Tactic:
|
|
||||||
import Database.ctx.*
|
|
||||||
|
|
||||||
val schema = quote {
|
|
||||||
querySchema[Tactic](
|
|
||||||
"tactic",
|
|
||||||
_.id -> "id",
|
|
||||||
_.name -> "name",
|
|
||||||
_.owner.id -> "owner_id",
|
|
||||||
_.filePath -> "file_path"
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package org.tbasket.db.schemas
|
|
||||||
|
|
||||||
import io.getquill.*
|
|
||||||
|
|
||||||
case class Team(id: Int, name: String, clubName: String)
|
|
||||||
object Team:
|
|
||||||
|
|
||||||
import org.tbasket.db.Database.ctx.*
|
|
||||||
|
|
||||||
val schema = quote {
|
|
||||||
querySchema[Team](
|
|
||||||
"team",
|
|
||||||
_.id -> "id",
|
|
||||||
_.name -> "name",
|
|
||||||
_.clubName -> "club_name"
|
|
||||||
)
|
|
||||||
}
|
|
Reference in new issue