Skip to content

Commit

Permalink
myndla-api: Add initial database setup
Browse files Browse the repository at this point in the history
  • Loading branch information
jnatten committed Nov 30, 2023
1 parent 63b6813 commit 0898522
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE my_ndla_users (
id BIGSERIAL PRIMARY KEY,
feide_id text,
document jsonb
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
CREATE TABLE resources (
id uuid NOT NULL DEFAULT gen_random_uuid(),
feide_id text NULL,
"path" text NULL,
resource_type text NULL,
created timestamp NULL,
"document" jsonb NULL,
CONSTRAINT resources_pkey PRIMARY KEY (id)
);

CREATE TABLE folders (
id uuid NOT NULL DEFAULT gen_random_uuid(),
parent_id uuid NULL,
feide_id text NULL,
"rank" int4 NULL,
"name" text NOT NULL,
status text NOT NULL,
created timestamp NOT NULL DEFAULT now(),
updated timestamp NOT NULL DEFAULT now(),
shared timestamp NULL,
description text NULL,
CONSTRAINT folders_pkey PRIMARY KEY (id),
CONSTRAINT fk_parent_id FOREIGN KEY (parent_id) REFERENCES folders(id)
);
CREATE INDEX folders_feide_id_idx ON folders USING btree (feide_id);
CREATE INDEX folders_parent_id_idx ON folders USING btree (parent_id);

CREATE TABLE folder_resources (
folder_id uuid NOT NULL,
resource_id uuid NOT NULL,
"rank" int4 NULL,
CONSTRAINT folder_resource_pkey PRIMARY KEY (folder_id, resource_id),
CONSTRAINT folder_resources_folder_id_fkey FOREIGN KEY (folder_id) REFERENCES folders(id) ON DELETE CASCADE,
CONSTRAINT folder_resources_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES resources(id) ON DELETE CASCADE
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
CREATE TABLE categories (
id BIGSERIAL PRIMARY KEY,
title text,
description text
);

CREATE TABLE topics (
id BIGSERIAL PRIMARY KEY,
title text,
content text,
category_id BIGINT REFERENCES categories(id)
);

CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
title text,
content text,
topic_id BIGINT REFERENCES topics(id)
);

CREATE TABLE topic_follows (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES my_ndla_users(id),
topic_id BIGINT REFERENCES topics(id)
);

CREATE TABLE notifications (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES my_ndla_users(id),
post_id BIGINT REFERENCES posts(id),
topic_id BIGINT REFERENCES topics(id),
is_read BOOLEAN DEFAULT FALSE
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

package no.ndla.myndlaapi

import com.zaxxer.hikari.HikariDataSource
import no.ndla.common.Clock
import no.ndla.common.configuration.BaseComponentRegistry
import no.ndla.myndlaapi.controller.{ErrorHelpers, SwaggerDocControllerConfig}
import no.ndla.myndlaapi.integration.DataSource
import no.ndla.network.tapir.{
NdlaMiddleware,
Routes,
Expand All @@ -29,12 +31,19 @@ class ComponentRegistry(properties: MyNdlaApiProperties)
with Clock
with TapirHealthController
with SwaggerControllerConfig
with SwaggerDocControllerConfig {
with SwaggerDocControllerConfig
with DataSource
with DBMigrator {
override val props: MyNdlaApiProperties = properties

override val dataSource: HikariDataSource = DataSource.getHikariDataSource
DataSource.connectToDatabase()

lazy val healthController = new TapirHealthController[Eff]
lazy val clock: SystemClock = new SystemClock

override val migrator = new DBMigrator

private val swagger = new SwaggerController[Eff](
List(
healthController
Expand Down
36 changes: 36 additions & 0 deletions myndla-api/src/main/scala/no/ndla/myndlaapi/DBMigrator.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Part of NDLA article-api.
* Copyright (C) 2016 NDLA
*
* See LICENSE
*
*/

package no.ndla.myndlaapi

import no.ndla.myndlaapi.integration.DataSource
import org.flywaydb.core.Flyway

trait DBMigrator {
this: Props with DataSource =>
val migrator: DBMigrator

class DBMigrator {

def migrate(): Unit = {
val flyway = Flyway
.configure()
.javaMigrations(
)
.locations("no/ndla/myndlaapi/db/migration")
.dataSource(dataSource)
// Seems like flyway uses datasource.getConnection().getScheme() which is null if the scheme does not exist.
// Therefore we simply override it with dataSource.getScheme.
// https://github.com/flyway/flyway/issues/2182
.schemas(dataSource.getSchema)
.load()
flyway.migrate(): Unit
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MainClass(override val props: MyNdlaApiProperties) extends NdlaTapirMain[E
override def beforeStart(): Unit = {
logger.info("Starting the db migration...")
val startDBMillis = System.currentTimeMillis()
// TODO: componentRegistry.migrator.migrate()
componentRegistry.migrator.migrate()
logger.info(s"Done db migration, took ${System.currentTimeMillis() - startDBMillis}ms")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

package no.ndla.myndlaapi

import no.ndla.common.Environment.prop
import no.ndla.common.configuration.{BaseProps, HasBaseProps}
import no.ndla.common.secrets.PropertyKeys
import no.ndla.network.AuthUser

import scala.util.Properties._
Expand All @@ -21,4 +23,15 @@ class MyNdlaApiProperties extends BaseProps {
override def ApplicationName: String = "myndla-api"

def Auth0LoginEndpoint = s"https://${AuthUser.getAuth0HostForEnv(Environment)}/authorize"

def MetaUserName: String = prop(PropertyKeys.MetaUserNameKey)
def MetaPassword: String = prop(PropertyKeys.MetaPasswordKey)
def MetaResource: String = prop(PropertyKeys.MetaResourceKey)
def MetaServer: String = prop(PropertyKeys.MetaServerKey)
def MetaPort: Int = prop(PropertyKeys.MetaPortKey).toInt
def MetaSchema: String = prop(PropertyKeys.MetaSchemaKey)
def MetaMaxConnections: Int = propOrElse(PropertyKeys.MetaMaxConnections, "10").toInt

def RedisHost: String = propOrElse("REDIS_HOST", "redis")
def RedisPort: Int = propOrElse("REDIS_PORT", "6379").toInt
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Part of NDLA article-api.
* Copyright (C) 2016 NDLA
*
* See LICENSE
*
*/

package no.ndla.myndlaapi.integration

import com.zaxxer.hikari.{HikariConfig, HikariDataSource}
import no.ndla.myndlaapi.Props
import scalikejdbc.{ConnectionPool, DataSourceConnectionPool}

trait DataSource {
this: Props =>
val dataSource: HikariDataSource

object DataSource {
import props._

def getHikariDataSource: HikariDataSource = {
val dataSourceConfig = new HikariConfig()
dataSourceConfig.setUsername(MetaUserName)
dataSourceConfig.setPassword(MetaPassword)
dataSourceConfig.setJdbcUrl(s"jdbc:postgresql://$MetaServer:$MetaPort/$MetaResource")
dataSourceConfig.setDriverClassName("org.postgresql.Driver")
dataSourceConfig.setSchema(MetaSchema)
dataSourceConfig.setMaximumPoolSize(MetaMaxConnections)
new HikariDataSource(dataSourceConfig)
}

def connectToDatabase(): Unit = ConnectionPool.singleton(new DataSourceConnectionPool(dataSource))
}
}
5 changes: 3 additions & 2 deletions network/src/main/scala/no/ndla/network/tapir/Routes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -192,17 +192,18 @@ trait Routes[F[_]] {

val endpoints = services.asInstanceOf[List[Service[Id]]].flatMap(_.builtEndpoints)

val serv = JdkHttpServer()
JdkHttpServer()
.options(options)
.executor(executor)
.addEndpoints(endpoints)
.port(port)
.start()
.start(): Unit

logger.info(s"Starting $name on port $port")

warmupFunc

// NOTE: Since JdkHttpServer does not block, we need to block the main thread to keep the application alive
synchronized { wait() }
}
}
Expand Down

0 comments on commit 0898522

Please sign in to comment.