-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #214 from NIAEFEUP/base-seeders
Base seeders
- Loading branch information
Showing
18 changed files
with
849 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
src/main/kotlin/pt/up/fe/ni/website/backend/hooks/ApplicationStartupHook.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package pt.up.fe.ni.website.backend.hooks | ||
|
||
import org.springframework.beans.factory.annotation.Value | ||
import org.springframework.boot.ApplicationArguments | ||
import org.springframework.boot.ApplicationRunner | ||
import org.springframework.stereotype.Component | ||
import pt.up.fe.ni.website.backend.config.Logging | ||
import pt.up.fe.ni.website.backend.model.seeders.ApplicationSeeder | ||
|
||
@Component | ||
class ApplicationStartupHook( | ||
val applicationSeeder: ApplicationSeeder | ||
) : ApplicationRunner, Logging { | ||
|
||
@Value("\${app.debug}") | ||
val debug: Boolean = true // false | ||
|
||
var seed: Boolean = true // false | ||
|
||
fun checkSeedArgument() { | ||
try { | ||
val seedProperty = System.getProperty("seed") | ||
if (seedProperty == "true") { | ||
seed = true | ||
} | ||
} catch (_: NullPointerException) { } catch (_: IllegalArgumentException) {} | ||
} | ||
|
||
override fun run(args: ApplicationArguments?) { | ||
logger.info("Running Startup hook...") | ||
// checkSeedArgument() | ||
if (debug && seed) { | ||
logger.info("Running application seeder...") | ||
applicationSeeder.seedDatabase() | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/kotlin/pt/up/fe/ni/website/backend/model/seeders/AbstractSeeder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package pt.up.fe.ni.website.backend.model.seeders | ||
|
||
import net.datafaker.Faker | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.data.repository.CrudRepository | ||
|
||
@Suppress("SpringJavaInjectionPointsAutowiringInspection") | ||
abstract class AbstractSeeder<T, U, P> where T : CrudRepository<U, P> { | ||
|
||
protected val faker = Faker() | ||
|
||
@Autowired | ||
protected lateinit var repository: T | ||
|
||
abstract fun createObjects() | ||
} |
153 changes: 153 additions & 0 deletions
153
src/main/kotlin/pt/up/fe/ni/website/backend/model/seeders/AccountSeeder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package pt.up.fe.ni.website.backend.model.seeders | ||
|
||
import jakarta.persistence.EntityManager | ||
import jakarta.transaction.Transactional | ||
import java.util.* | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.security.crypto.password.PasswordEncoder | ||
import org.springframework.stereotype.Component | ||
import pt.up.fe.ni.website.backend.config.Logging | ||
import pt.up.fe.ni.website.backend.model.Account | ||
import pt.up.fe.ni.website.backend.repository.AccountRepository | ||
import pt.up.fe.ni.website.backend.repository.CustomWebsiteRepository | ||
import pt.up.fe.ni.website.backend.repository.RoleRepository | ||
|
||
@Component @Transactional | ||
class AccountSeeder( | ||
private val encoder: PasswordEncoder, | ||
@Autowired val roleRepository: RoleRepository, | ||
@Autowired val customWebsiteRepository: CustomWebsiteRepository, | ||
@Autowired val entityManager: EntityManager // Inject EntityManager | ||
) : AbstractSeeder<AccountRepository, Account, Long>(), Logging { | ||
|
||
override fun createObjects() { | ||
logger.info("Running account seeder...") | ||
|
||
// Fetch all roles from the database | ||
val roles = roleRepository.findAll().toList() | ||
if (roles.isEmpty()) { | ||
logger.warn("No roles found in the database. Accounts will be created without roles.") | ||
} | ||
|
||
val websites = customWebsiteRepository.findAll().toList() | ||
.map { entityManager.merge(it) }.toMutableList() | ||
if (websites.isEmpty()) { | ||
logger.warn("No Custom websites in database. Accounts will be created without websites") | ||
} | ||
|
||
val accounts = listOf( | ||
Account( | ||
name = faker.name().fullName(), | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("password123"), | ||
bio = faker.lorem().paragraph(1), | ||
birthDate = Date.from(faker.date().birthday(25, 35).toInstant()), | ||
photo = faker.internet().image(), | ||
github = faker.internet().url(), | ||
websites = websites.shuffled().take(1).toMutableList(), | ||
linkedin = faker.internet().url(), | ||
roles = roles.shuffled().take(2).toMutableList() | ||
), | ||
// Account Without Photo | ||
Account( | ||
name = faker.name().fullName(), | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("password123"), | ||
bio = faker.lorem().sentence(), | ||
birthDate = Date.from(faker.date().birthday(30, 40).toInstant()), | ||
photo = null, | ||
github = faker.internet().url(), | ||
linkedin = faker.internet().url(), | ||
roles = roles.shuffled().take(1).toMutableList() | ||
), | ||
// Account Without Bio | ||
Account( | ||
name = faker.name().fullName(), | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("password123"), | ||
bio = null, | ||
birthDate = Date.from(faker.date().birthday(18, 28).toInstant()), | ||
photo = faker.internet().image(), | ||
github = faker.internet().url(), | ||
linkedin = faker.internet().url(), | ||
websites = websites.shuffled().take(3).toMutableList(), | ||
roles = roles.shuffled().take(1).toMutableList() | ||
), | ||
// Account Without Bio or Photo | ||
Account( | ||
name = faker.name().fullName(), | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("password123"), | ||
bio = null, | ||
birthDate = Date.from(faker.date().birthday(20, 30).toInstant()), | ||
photo = null, | ||
github = null, | ||
linkedin = faker.internet().url(), | ||
websites = websites.shuffled().take(5).toMutableList(), | ||
roles = roles.shuffled().take(1).toMutableList() | ||
), | ||
// Account with Long Bio | ||
Account( | ||
name = faker.name().fullName(), | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("password123"), | ||
bio = faker.lorem().paragraph(5), | ||
birthDate = Date.from(faker.date().birthday(35, 45).toInstant()), | ||
photo = faker.internet().image(), | ||
github = faker.internet().url(), | ||
linkedin = faker.internet().url(), | ||
roles = roles.shuffled().take(3).toMutableList() | ||
), | ||
// Account with Single Role | ||
Account( | ||
name = faker.name().fullName(), | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("password123"), | ||
bio = "User with only one role.", | ||
birthDate = Date.from(faker.date().birthday(22, 32).toInstant()), | ||
photo = faker.internet().image(), | ||
github = faker.internet().url(), | ||
linkedin = faker.internet().url(), | ||
websites = websites.shuffled().take(2).toMutableList(), | ||
roles = roles.shuffled().take(1).toMutableList() | ||
), | ||
// Account with All Optional Fields Null | ||
Account( | ||
name = faker.name().fullName(), | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("password123"), | ||
bio = null, | ||
birthDate = null, | ||
photo = null, | ||
github = null, | ||
linkedin = null, | ||
roles = mutableListOf() | ||
) | ||
) | ||
|
||
val repeatedAccounts = mutableListOf<Account>() | ||
for (i in 1..5) { | ||
repeatedAccounts.addAll(accounts) | ||
} | ||
|
||
val staticAccounts = listOf( // edge cases | ||
Account( | ||
name = "Zoë Löwe Dinis Canas", // Special characters in name | ||
email = faker.internet().emailAddress(), | ||
password = encoder.encode("specialpass"), | ||
bio = faker.lorem().sentence(), | ||
birthDate = Date.from(faker.date().birthday(20, 40).toInstant()), | ||
photo = faker.internet().image(), | ||
github = faker.internet().url(), | ||
linkedin = faker.internet().url(), | ||
roles = roles.shuffled().take(2).toMutableList() | ||
) | ||
) | ||
|
||
val allAccounts = repeatedAccounts + staticAccounts | ||
|
||
repository.saveAll(allAccounts) | ||
|
||
logger.info("Account data seeded successfully.") | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/kotlin/pt/up/fe/ni/website/backend/model/seeders/ActivitySeeder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package pt.up.fe.ni.website.backend.model.seeders | ||
|
||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.stereotype.Component | ||
import pt.up.fe.ni.website.backend.config.Logging | ||
import pt.up.fe.ni.website.backend.model.Event | ||
import pt.up.fe.ni.website.backend.repository.ActivityRepository | ||
|
||
@Component | ||
class ActivitySeeder( | ||
@Autowired val eventSeeder: EventSeeder, | ||
@Autowired val projectSeeder: ProjectSeeder, | ||
@Autowired val perActivityRoleSeeder: PerActivityRoleSeeder | ||
) : AbstractSeeder<ActivityRepository<Event>, Event, Long>(), Logging { | ||
|
||
override fun createObjects() { | ||
// Delegate seeding to the EventSeeder and ProjectSeeder | ||
logger.info("Running Activity Seeder") | ||
|
||
// Seed Roles per Activity | ||
perActivityRoleSeeder.createObjects() | ||
// Seed Projects | ||
projectSeeder.createObjects() | ||
// Seed Events | ||
eventSeeder.createObjects() | ||
|
||
logger.info("Finished seeding activities (events and projects)") | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/kotlin/pt/up/fe/ni/website/backend/model/seeders/ApplicationSeeder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package pt.up.fe.ni.website.backend.model.seeders | ||
|
||
import jakarta.persistence.EntityManager | ||
import javax.sql.DataSource | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.context.ApplicationContext | ||
import org.springframework.stereotype.Component | ||
import pt.up.fe.ni.website.backend.service.database.DatabaseService | ||
|
||
@Component | ||
class ApplicationSeeder( | ||
private val accountSeeder: AccountSeeder, | ||
private val activitySeeder: ActivitySeeder, | ||
private val postSeeder: PostSeeder, | ||
private val generationSeeder: GenerationSeeder, | ||
private val roleSeeder: RoleSeeder, | ||
private val customWebsiteSeeder: CustomWebsiteSeeder, | ||
@Autowired | ||
private val appContext: ApplicationContext, | ||
private val databaseService: DatabaseService | ||
) { | ||
fun seedDatabase() { | ||
val dataSource = appContext.getBean(DataSource::class.java) | ||
databaseService.cleanDataSource(dataSource) | ||
|
||
val entityManager = appContext.getBean(EntityManager::class.java) | ||
databaseService.cleanEntityManager(entityManager) | ||
|
||
roleSeeder.createObjects() | ||
customWebsiteSeeder.createObjects() | ||
accountSeeder.createObjects() | ||
activitySeeder.createObjects() | ||
postSeeder.createObjects() | ||
generationSeeder.createObjects() | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/kotlin/pt/up/fe/ni/website/backend/model/seeders/CustomWebsiteSeeder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package pt.up.fe.ni.website.backend.model.seeders | ||
|
||
import org.springframework.stereotype.Component | ||
import pt.up.fe.ni.website.backend.config.Logging | ||
import pt.up.fe.ni.website.backend.model.CustomWebsite | ||
import pt.up.fe.ni.website.backend.repository.CustomWebsiteRepository | ||
|
||
@Component | ||
class CustomWebsiteSeeder() : AbstractSeeder<CustomWebsiteRepository, CustomWebsite, Long>(), Logging { | ||
|
||
override fun createObjects() { | ||
if (repository.count() == 0L) { | ||
logger.info("Running CustomWebsite seeder...") | ||
|
||
val customWebsites = (1..15).map { | ||
CustomWebsite( | ||
url = faker.internet().url(), | ||
iconPath = faker.internet().image(), | ||
label = faker.lorem().sentence(3, 5) | ||
) | ||
} | ||
|
||
repository.saveAll(customWebsites) | ||
logger.info("CustomWebsite data seeded successfully.") | ||
} else { | ||
logger.info("CustomWebsite data already exists, skipping seeding.") | ||
} | ||
} | ||
} |
Oops, something went wrong.