Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
path = api-registry
url = https://github.com/reportportal/api-registry
branch = feature/organizations
[submodule "migrations"]
path = migrations
url = https://github.com/reportportal/migrations
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
ARG APP_VERSION
WORKDIR /usr/app
COPY . /usr/app
RUN chown -R gradle:gradle /usr/app
USER gradle
RUN if [ "${RELEASE_MODE}" = true ]; then \
gradle build --no-build-cache --exclude-task test \
-PreleaseMode=true \
Expand All @@ -10,7 +12,7 @@
else gradle build --no-build-cache --exclude-task test -Dorg.gradle.project.version=${APP_VERSION}; fi

FROM amazoncorretto:25.0.2
LABEL version=${APP_VERSION} description="EPAM Report portal. Main API Service" maintainer="Andrei Varabyeu <andrei_varabyeu@epam.com>, Hleb Kanonik <hleb_kanonik@epam.com>"

Check warning on line 15 in Dockerfile

View workflow job for this annotation

GitHub Actions / Call feature Docker build / Build and export to AWS ECR

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$APP_VERSION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 15 in Dockerfile

View workflow job for this annotation

GitHub Actions / Call feature Docker build / Build and export to AWS ECR

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$APP_VERSION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 15 in Dockerfile

View workflow job for this annotation

GitHub Actions / Call feature Docker build / Build and export to AWS ECR

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$APP_VERSION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ARG APP_VERSION=${APP_VERSION}
ENV APP_DIR=/usr/app
ENV JAVA_OPTS="-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom "
Expand Down
24 changes: 21 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@
* limitations under the License.
*/

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.testcontainers:testcontainers:1.21.4'
classpath 'org.testcontainers:postgresql:1.21.3'
classpath 'org.postgresql:postgresql:42.7.8'
}
}

plugins {
alias(libs.plugins.java.library)
alias(libs.plugins.owasp.dependencycheck)
Expand All @@ -30,7 +41,7 @@ apply from: "$scriptsUrl/build-commons.gradle"
apply from: "$scriptsUrl/build-info.gradle"
apply from: "$scriptsUrl/release-service.gradle"
apply from: "$scriptsUrl/signing.gradle"
apply from: "$scriptsUrl/copy-database-scripts.gradle"
apply from: 'copy-database-scripts.gradle'

project.hasProperty('sealightsSession') && sealightsSession?.trim() ?
apply(from: 'sealights.gradle') :
Expand Down Expand Up @@ -101,7 +112,6 @@ dependencies {
implementation(libs.opencsv)
implementation(libs.slugify)
implementation(libs.postgresql)
jooqCodegen(libs.postgresql)
implementation(libs.thumbnailator)
implementation(libs.aws.core)
implementation(libs.aws.sts)
Expand Down Expand Up @@ -152,6 +162,8 @@ dependencies {
testAnnotationProcessor(libs.lombok)
}

apply from: 'jooq.gradle'

sourceSets {
main {
java {
Expand All @@ -166,7 +178,7 @@ openApiGenerate {
outputDir.set("${layout.buildDirectory.get()}/generated")
configFile.set("$rootDir/src/main/resources/openapi/config.json")
skipOverwrite.set(false)
cleanupOutput.set(true)
cleanupOutput.set(false)
// verbose.set(true)
}

Expand Down Expand Up @@ -210,6 +222,11 @@ dependencyCheck {
// cveValidForHours = 1
}


tasks.named('sourcesJar').configure {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

bootJar {
duplicatesStrategy = duplicatesStrategy.EXCLUDE
project.hasProperty('gcp') ? getArchiveFileName().set('app.jar') : archiveClassifier.set('' + 'exec')
Expand All @@ -231,6 +248,7 @@ test {
maxHeapSize = '2g'
}

compileJava.dependsOn tasks.named('jooqCodegen')
compileJava.dependsOn tasks.named('openApiGenerate')
compileJava.dependsOn tasks.named('downloadManifestSchema')
publish.dependsOn build
Expand Down
33 changes: 33 additions & 0 deletions copy-database-scripts.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
def migrationsSrcDir = file("${rootDir}/migrations/migrations")
def migrationsDstDir = file("${projectDir}/src/test/resources/db/migration")

tasks.register('copyTestDatabaseScripts') {
inputs.dir(migrationsSrcDir)
doLast {
migrationsDstDir.mkdirs()
(migrationsSrcDir.listFiles() ?: [])
.findAll { it.name.endsWith('.up.sql') }
.each { srcFile ->
def m = (srcFile.name =~ /^(\d+)_(.+)\.up\.sql$/)
if (m) {
def target = new File(migrationsDstDir, "V${String.format('%03d', m[0][1] as int)}__${m[0][2]}.sql")
if (!target.exists()) {
target.text = srcFile.text
}
}
}
}
}

tasks.register('removeScripts') {
doLast {
(migrationsSrcDir.listFiles() ?: [])
.findAll { it.name.endsWith('.up.sql') }
.each { srcFile ->
def m = (srcFile.name =~ /^(\d+)_(.+)\.up\.sql$/)
if (m) {
new File(migrationsDstDir, "V${String.format('%03d', m[0][1] as int)}__${m[0][2]}.sql").delete()
}
}
}
}
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ aws-sdk = "2.41.3"
bouncycastle = "1.82"
commons-validator = "1.10.0"
embedded-postgres = "2.2.0"
testcontainers = "1.21.4"
flyway-spring-test = "10.0.0"
google-api-client = "2.8.1"
guava = "33.5.0-jre"
Expand Down Expand Up @@ -126,6 +127,8 @@ guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
jasypt = { group = "org.jasypt", name = "jasypt", version.ref = "jasypt" }
pf4j = { group = "org.pf4j", name = "pf4j", version.ref = "pf4j" }
embedded-postgres = { group = "io.zonky.test", name = "embedded-postgres", version.ref = "embedded-postgres" }
testcontainers = { group = "org.testcontainers", name = "testcontainers", version.ref = "testcontainers" }
testcontainers-postgresql = { group = "org.testcontainers", name = "postgresql", version.ref = "testcontainers" }
jackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind" }
jackson-jsr310 = { group = "com.fasterxml.jackson.datatype", name = "jackson-datatype-jsr310" }
spring-context = { group = "org.springframework", name = "spring-context" }
Expand Down
105 changes: 105 additions & 0 deletions jooq.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'io.zonky.test:embedded-postgres:2.2.0'
classpath 'io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64:17.6.0'
classpath 'io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64-alpine:17.6.0'
classpath 'io.zonky.test.postgres:embedded-postgres-binaries-darwin-amd64:17.6.0'
classpath 'io.zonky.test.postgres:embedded-postgres-binaries-darwin-arm64v8:17.6.0'
classpath 'org.postgresql:postgresql:42.7.8'
}
}

tasks.named('jooqCodegen').configure { jooqTask ->
def migrationsDir = file("${rootDir}/migrations/migrations")
inputs.dir(migrationsDir)
ext.pgInstance = null

doFirst {
def pg = io.zonky.test.db.postgres.embedded.EmbeddedPostgres.start()
ext.pgInstance = pg

def jdbcUrl = "jdbc:postgresql://localhost:${pg.port}/postgres"
def username = "postgres"
def password = ""
logger.lifecycle("Embedded PostgreSQL started on port: ${pg.port}")

def props = new Properties()
props.setProperty('user', username)
def conn = new org.postgresql.Driver().connect(jdbcUrl, props)
try {
(migrationsDir.listFiles() ?: [])
.findAll { it.name.endsWith('.up.sql') }
.sort { a, b ->
(a.name =~ /^(\d+)/)[0][1].toInteger() <=>
(b.name =~ /^(\d+)/)[0][1].toInteger()
}
.each { script ->
logger.lifecycle(" Applying: ${script.name}")
def stmt = conn.createStatement()
stmt.execute(script.text)
stmt.close()
}
} finally {
conn.close()
}

def field = jooqTask.getClass().getSuperclass().getDeclaredField('configuration')
field.setAccessible(true)
def cfg = field.get(jooqTask).getConfiguration()
cfg.jdbc.url = jdbcUrl
cfg.jdbc.user = username
cfg.jdbc.password = password
cfg.jdbc.driver = 'org.postgresql.Driver'
}

doLast {
if (ext.pgInstance != null) {
ext.pgInstance.close()
ext.pgInstance = null
logger.lifecycle("Embedded PostgreSQL stopped")
}
}
}

jooq {
configuration {
jdbc {
driver = 'org.postgresql.Driver'
// Placeholder — overridden at execution time by the Testcontainers instance
url = 'jdbc:postgresql://localhost:5432/jooq'
user = 'jooq'
password = 'jooq'
}
generator {
strategy {
name = 'org.jooq.codegen.example.JPrefixGeneratorStrategy'
}
database {
name = 'org.jooq.meta.postgres.PostgresDatabase'
inputSchema = (hasProperty('DB_SCHEMA_POSTGRES') ? getProperty('DB_SCHEMA_POSTGRES') : 'public')
excludes = 'batch_.*|schema_migrations'
forcedTypes {
forcedType {
userType = "java.time.Instant"
converter = "com.epam.reportportal.base.infrastructure.persistence.dao.converters.JooqInstantConverter"
types = "TIMESTAMP"
}
}
}
generate {
pojos = false
jpaAnnotations = false
routines = false
deprecationOnUnknownTypes = false
records = true
}
target {
packageName = 'com.epam.reportportal.base.infrastructure.persistence.jooq'
directory = 'build/generated/src/main/java/'
}
}
}
}
1 change: 1 addition & 0 deletions migrations
Submodule migrations added at 2ef0d9
82 changes: 0 additions & 82 deletions project-properties.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
def commonScriptsUrl = 'https://raw.githubusercontent.com/reportportal/gradle-scripts/'
def migrationsScriptsUrl = 'https://raw.githubusercontent.com/reportportal/migrations/'
def schemaUrl = 'https://schema.reportportal.io/'

project.ext {
Expand All @@ -16,88 +15,7 @@ project.ext {
isDebugMode = System.getProperty("DEBUG", "false") == "true"
releaseMode = project.hasProperty("releaseMode") ? project.releaseMode.toBoolean() : false
scriptsUrl = commonScriptsUrl + (releaseMode ? '5.14.0' : 'develop')
migrationsUrl = migrationsScriptsUrl + (releaseMode ? '5.14.0' : 'develop')
manifestSchemaUrl = schemaUrl + ('manifest.schema.json')
//TODO refactor with archive download
testScriptsSrc = [
(migrationsUrl + '/migrations/0_extensions.up.sql') : 'V001__extensions.sql',
(migrationsUrl + '/migrations/1_initialize_schema.up.sql') : 'V002__initialize_schema.sql',
(migrationsUrl + '/migrations/3_default_data.up.sql') : 'V003__default_data.sql',
(migrationsUrl + '/migrations/4_size_limitations.up.sql') : 'V004__size_limitations.sql',
(migrationsUrl + '/migrations/5_test_case_id_type.up.sql') : 'V005__test_case_id_type.sql',
(migrationsUrl + '/migrations/6_retries_handling.up.sql') : 'V006__retries_handling.sql',
(migrationsUrl + '/migrations/7_auth_integration.up.sql') : 'V007__auth_integration.sql',
(migrationsUrl + '/migrations/8_sender_case_enabled_field.up.sql') : 'V008__sender_case_enabled_field.sql',
(migrationsUrl + '/migrations/9_analyzer_params.up.sql') : 'V009__analyzer_params.sql',
(migrationsUrl + '/migrations/10_attachment_size.up.sql') : 'V010__attachment_size.sql',
(migrationsUrl + '/migrations/11_password_encoding.up.sql') : 'V011__password_encoding.sql',
(migrationsUrl + '/migrations/12_remove_ticket_duplicates.up.sql') : 'V012__remove_ticket_duplicates.sql',
(migrationsUrl + '/migrations/13_add_allocated_storage_per_project.up.sql'): 'V013__add_allocated_storage_per_project.sql',
(migrationsUrl + '/migrations/14_test_case_id_size_increase.up.sql') : 'V014__test_case_id_size_increase.sql',
(migrationsUrl + '/migrations/15_statistics_decreasing.up.sql') : 'V015__statistics_decreasing.sql',
(migrationsUrl + '/migrations/16_remove_unused_indexes.up.sql') : 'V016__remove_unused_indexes.sql',
(migrationsUrl + '/migrations/17_status_enum_extension.up.sql') : 'V017__status_enum_extension.sql',
(migrationsUrl + '/migrations/18_job_attributes.up.sql') : 'V018__job_attributes.sql',
(migrationsUrl + '/migrations/19_retries_handling_extension.up.sql') : 'V019__retries_handling_extension.sql',
(migrationsUrl + '/migrations/20_deep_merge_statistics_handling.up.sql') : 'V020__deep_merge_statistics_handling.sql',
(migrationsUrl + '/migrations/21_deep_merge_retries_fix.up.sql') : 'V021__deep_merge_retries_fix.sql',
(migrationsUrl + '/migrations/22_deep_merge_nested_steps_fix.up.sql') : 'V022__deep_merge_nested_steps_fix.sql',
(migrationsUrl + '/migrations/23_rerun_item_statistics_fix.up.sql') : 'V023__rerun_item_statistics_fix.sql',
(migrationsUrl + '/migrations/24_widget_views_cleanup.up.sql') : 'V024__widget_views_cleanup.sql',
(migrationsUrl + '/migrations/25_deep_merge_nested_steps_path_fix.up.sql') : 'V025__deep_merge_nested_steps_path_fix.sql',
(migrationsUrl + '/migrations/26_retries_lock_fix.up.sql') : 'V026__retries_lock_fix.sql',
(migrationsUrl + '/migrations/42_shedlock_table.up.sql') : 'V032__shedlock_table.sql',
(migrationsUrl + '/migrations/43_attachment_for_deletion_table.up.sql') : 'V033__attachment_for_deletion_table.sql',
(migrationsUrl + '/migrations/44_remove_triggers.up.sql') : 'V034__remove_triggers.sql',
(migrationsUrl + '/migrations/48_composite_attribute.up.sql') : 'V048__composite_attribute.sql',
(migrationsUrl + '/migrations/51_cluster.up.sql') : 'V051__cluster.sql',
(migrationsUrl + '/migrations/52_analyzer_search_attribute.up.sql') : 'V052__analyzer_search_attribute.sql',
(migrationsUrl + '/migrations/54_analyzer_unique_error_attribute.up.sql') : 'V054__analyzer_unique_error_attribute.sql',
(migrationsUrl + '/migrations/58_alter_ticket.up.sql') : 'V058__alter_ticket.sql',
(migrationsUrl + '/migrations/59_stale_materialized_view.up.sql') : 'V059__stale_materialized_view.sql',
(migrationsUrl + '/migrations/60_sender_case_operator.up.sql') : 'V060__sender_case_operator.sql',
(migrationsUrl + '/migrations/61_remove_acl.up.sql') : 'V061__remove_acl.sql',
(migrationsUrl + '/migrations/62_remove_dashboard_cascade_drop.up.sql') : 'V062__remove_dashboard_cascade_drop.sql',
(migrationsUrl + '/migrations/65_launch_attribute_rules_length.up.sql') : 'V065__launch_attribute_rules_length.sql',
(migrationsUrl + '/migrations/67_api_keys.up.sql') : 'V067__api_keys.sql',
(migrationsUrl + '/migrations/68_api_key_last_used_at.up.sql') : 'V068__api_key_last_used_at.sql',
(migrationsUrl + '/migrations/69_replace_activity_table.up.sql') : 'V069__replace_activity_table.sql',
(migrationsUrl + '/migrations/71_user_bid_inviting_user_id.up.sql') : 'V071__user_bid_inviting_user_id.sql',
(migrationsUrl + '/migrations/72_add_attachment_name.up.sql') : 'V072__add_attachment_name.sql',
(migrationsUrl + '/migrations/73_sender_case_rule_name.up.sql') : 'V073__sender_case_rule_name.sql',
(migrationsUrl + '/migrations/76_user_bid_extension.up.sql') : 'V076__user_bid_extension.sql',
(migrationsUrl + '/migrations/77_email_server_documentation_link.up.sql') : 'V077__email_server_documentation_link.sql',
(migrationsUrl + '/migrations/78_drop_redundant_index.up.sql') : 'V078__drop_redundant_index.sql',
(migrationsUrl + '/migrations/84_notication_update.up.sql') : 'V084__notication_update.sql',
(migrationsUrl + '/migrations/86_add_retention_policy_launch.up.sql') : 'V086__add_retention_policy_launch.sql',
(migrationsUrl + '/migrations/87_add_group_enam_value.up.sql') : 'V087__add_group_enam_value.sql',
(migrationsUrl + '/migrations/88_analytics_data_table.up.sql') : 'V088__analytics_data_table.sql',
(migrationsUrl + '/migrations/90_add_user_fields.up.sql') : 'V090__scim_user_fields.sql',
(migrationsUrl + '/migrations/91_settings_users_sso.up.sql') : 'V091__settings_users_sso.sql',
(migrationsUrl + '/migrations/93_settings_session_time.up.sql') : 'V093__settings_session_time.sql',
(migrationsUrl + '/migrations/96_create_groups_tables.up.sql') : 'V096__create_groups_tables.sql',
(migrationsUrl + '/migrations/97_add_groups_uuid.up.sql') : 'V097__add_groups_uuid.up.sql',
(migrationsUrl + '/migrations/98_add_plugin_type.up.sql') : 'V098__add_plugin_type.up.sql',
(migrationsUrl + '/migrations/106_create_log_type_table.up.sql') : 'V106__create_log_type_table.sql',
(migrationsUrl + '/migrations/107_add_analysis_owner.up.sql') : 'V107__add_analysis_owner.sql',
(migrationsUrl + '/migrations/110_retention_non_null.up.sql') : 'V110__retention_non_null.up.sql',
(migrationsUrl + '/migrations/111_update_retry_functions.up.sql') : 'V111__update_retry_functions.up.sql',
(migrationsUrl + '/migrations/112_lock_dashboard.up.sql') : 'V112__lock_dashboard.up.sql',
(migrationsUrl + '/migrations/198_add_slugify_function.up.sql') : 'V198__add_slugify_function.sql',
(migrationsUrl + '/migrations/199_organization_tables.up.sql') : 'V199__organization_tables.sql',
(migrationsUrl + '/migrations/200_migrate_org_roles.up.sql') : 'V200__migrate_org_roles.sql',
(migrationsUrl + '/migrations/201_drop_table_onboarding.up.sql') : 'V201__drop_table_onboarding.sql',
(migrationsUrl + '/migrations/202_update_project_table.up.sql') : 'V202__update_project_table.up.sql',
(migrationsUrl + '/migrations/203_user_table_extend.up.sql') : 'V203__user_table_extend.up.sql',
(migrationsUrl + '/migrations/204_bid_extend_metadata.up.sql') : 'V204__bid_extend_metadata.up.sql',
(migrationsUrl + '/migrations/206_add_org_id_to_groups.up.sql') : 'V206__add_org_id_to_groups.sql',
(migrationsUrl + '/migrations/208_unique_group_slug_by_org.up.sql') : 'V208__unique_group_slug_by_org.sql',
(migrationsUrl + '/migrations/209_add_activity_org_id.up.sql') : 'V209__add_activity_org_id.sql',
(migrationsUrl + '/migrations/210_organization_settings_table.up.sql') : 'V210__organization_settings_table.sql',
(migrationsUrl + '/migrations/212_update_default_users.up.sql') : 'V212__update_default_users.sql',
(migrationsUrl + '/migrations/1000_tms_initial.up.sql') : 'V213__tms_initial.up.sql',
(migrationsUrl + '/migrations/1001_migrate_auth_integrations.up.sql') : 'V214__migrate_auth_integrations.up.sql',
]
excludeTests = ['**/entity/**',
'**/aop/**',
'**/jasper/**',
Expand Down
Loading
Loading