diff --git a/Dockerfile b/Dockerfile index ec1a9fb2..59274584 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,5 +26,7 @@ USER spring:spring WORKDIR /fdp COPY --from=builder /builder/target/fdp-spring-boot.jar /fdp/app.jar +COPY --from=builder /builder/fixtures /fdp/fixtures +# TODO: copy the (rdf) "data" dir as well, or move that into the fixtures dir, e.g. fixtures/rdf and fixtures/db ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/src/main/resources/fixtures/0010_settings.json b/fixtures/0010_settings.json similarity index 100% rename from src/main/resources/fixtures/0010_settings.json rename to fixtures/0010_settings.json diff --git a/src/main/resources/fixtures/0100_user-accounts.json b/fixtures/0100_user-accounts.json similarity index 100% rename from src/main/resources/fixtures/0100_user-accounts.json rename to fixtures/0100_user-accounts.json diff --git a/src/main/resources/fixtures/0110_api-keys.json b/fixtures/0110_api-keys.json similarity index 100% rename from src/main/resources/fixtures/0110_api-keys.json rename to fixtures/0110_api-keys.json diff --git a/src/main/resources/fixtures/0120_saved-queries.json b/fixtures/0120_saved-queries.json similarity index 100% rename from src/main/resources/fixtures/0120_saved-queries.json rename to fixtures/0120_saved-queries.json diff --git a/src/main/resources/fixtures/0200_metadata-schemas_resource.json b/fixtures/0200_metadata-schemas_resource.json similarity index 100% rename from src/main/resources/fixtures/0200_metadata-schemas_resource.json rename to fixtures/0200_metadata-schemas_resource.json diff --git a/src/main/resources/fixtures/0210_metadata-schemas_data-service.json b/fixtures/0210_metadata-schemas_data-service.json similarity index 100% rename from src/main/resources/fixtures/0210_metadata-schemas_data-service.json rename to fixtures/0210_metadata-schemas_data-service.json diff --git a/src/main/resources/fixtures/0220_metadata-schemas_metadata-service.json b/fixtures/0220_metadata-schemas_metadata-service.json similarity index 100% rename from src/main/resources/fixtures/0220_metadata-schemas_metadata-service.json rename to fixtures/0220_metadata-schemas_metadata-service.json diff --git a/src/main/resources/fixtures/0230_metadata-schemas_fdp.json b/fixtures/0230_metadata-schemas_fdp.json similarity index 100% rename from src/main/resources/fixtures/0230_metadata-schemas_fdp.json rename to fixtures/0230_metadata-schemas_fdp.json diff --git a/src/main/resources/fixtures/0240_metadata-schemas_catalog.json b/fixtures/0240_metadata-schemas_catalog.json similarity index 100% rename from src/main/resources/fixtures/0240_metadata-schemas_catalog.json rename to fixtures/0240_metadata-schemas_catalog.json diff --git a/src/main/resources/fixtures/0250_metadata-schemas_dataset.json b/fixtures/0250_metadata-schemas_dataset.json similarity index 100% rename from src/main/resources/fixtures/0250_metadata-schemas_dataset.json rename to fixtures/0250_metadata-schemas_dataset.json diff --git a/src/main/resources/fixtures/0260_metadata-schemas_distribution.json b/fixtures/0260_metadata-schemas_distribution.json similarity index 100% rename from src/main/resources/fixtures/0260_metadata-schemas_distribution.json rename to fixtures/0260_metadata-schemas_distribution.json diff --git a/src/main/resources/fixtures/0300_resource-definitions_distribution.json b/fixtures/0300_resource-definitions_distribution.json similarity index 100% rename from src/main/resources/fixtures/0300_resource-definitions_distribution.json rename to fixtures/0300_resource-definitions_distribution.json diff --git a/src/main/resources/fixtures/0310_resource-definitions_dataset.json b/fixtures/0310_resource-definitions_dataset.json similarity index 100% rename from src/main/resources/fixtures/0310_resource-definitions_dataset.json rename to fixtures/0310_resource-definitions_dataset.json diff --git a/src/main/resources/fixtures/0320_resource-definitions_catalog.json b/fixtures/0320_resource-definitions_catalog.json similarity index 100% rename from src/main/resources/fixtures/0320_resource-definitions_catalog.json rename to fixtures/0320_resource-definitions_catalog.json diff --git a/src/main/resources/fixtures/0330_resource-definitions_repository.json b/fixtures/0330_resource-definitions_repository.json similarity index 100% rename from src/main/resources/fixtures/0330_resource-definitions_repository.json rename to fixtures/0330_resource-definitions_repository.json diff --git a/src/main/resources/fixtures/0400_memberships_owner.json b/fixtures/0400_memberships_owner.json similarity index 100% rename from src/main/resources/fixtures/0400_memberships_owner.json rename to fixtures/0400_memberships_owner.json diff --git a/src/main/resources/fixtures/0410_memberships_data-provider.json b/fixtures/0410_memberships_data-provider.json similarity index 100% rename from src/main/resources/fixtures/0410_memberships_data-provider.json rename to fixtures/0410_memberships_data-provider.json diff --git a/src/main/java/org/fairdatapoint/config/BootstrapConfig.java b/src/main/java/org/fairdatapoint/config/BootstrapConfig.java index d6659a0b..4c05478a 100644 --- a/src/main/java/org/fairdatapoint/config/BootstrapConfig.java +++ b/src/main/java/org/fairdatapoint/config/BootstrapConfig.java @@ -22,6 +22,8 @@ */ package org.fairdatapoint.config; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; @@ -30,32 +32,67 @@ import org.springframework.data.repository.init.Jackson2RepositoryPopulatorFactoryBean; import java.io.IOException; +import java.nio.file.Path; import java.util.Arrays; import java.util.Comparator; +/** + * The {@code BootstrapConfig} class configures a repository populator to load initial data into the relational + * database, based on JSON fixture files. + * Bootstrapping is disabled by default, and should only be enabled once, on the very first run of the application. + * It can also be enabled on subsequent runs, but then it will overwrite any changes that may have been made by users. + * To enable on the first run, set the env variable {@code BOOTSTRAP_ENABLED=true} on the command line, before running + * the app. + * When using e.g. docker compose, you can define {@code BOOTSTRAP_ENABLED: ${BOOTSTRAP_ENABLED:-false}} in the + * {@code environment} section and then set up the stack by running {@code BOOTSTRAP_ENABLED=true docker compose up -d}. + * The default fixtures are located in the {@code /fixtures} directory. + * To add custom fixtures and/or override any of the default fixtures in a docker compose setup, we can bind-mount + * individual fixture files. + * For example: {@code ./my-fixtures/0100_user-accounts.json:/fdp/fixtures/0100_user-accounts.json:ro} + * Note that bind-mounting the entire directory, instead of individual files, would hide all default files. + */ @Configuration +@Slf4j public class BootstrapConfig { private final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + private final boolean bootstrapEnabled; + private final Path dbFixturesPath; + + public BootstrapConfig( + @Value("${bootstrap.enabled:false}") boolean bootstrapEnabled, + @Value("${bootstrap.db-fixtures-dir}") String dbFixturesDir + ) { + this.bootstrapEnabled = bootstrapEnabled; + this.dbFixturesPath = Path.of(dbFixturesDir); + } @Bean public Jackson2RepositoryPopulatorFactoryBean repositoryPopulator() { final Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean(); - // load all json resources from the fixtures dir - try { - final Resource[] resources = resourceResolver.getResources("classpath:fixtures/*.json"); - // sort resources to guarantee lexicographic order - Arrays.sort( - resources, - Comparator.comparing( - Resource::getFilename, - Comparator.nullsLast(String::compareTo) - ) - ); - factory.setResources(resources); + if (bootstrapEnabled) { + log.info("Bootstrap repository populator enabled"); + try { + // collect fixture resources + final Path fixturesPath = dbFixturesPath.resolve("*.json"); + final Resource[] resources = resourceResolver.getResources("file:" + fixturesPath); + // sort resources to guarantee lexicographic order + Arrays.sort( + resources, + Comparator.comparing( + Resource::getFilename, + Comparator.nullsLast(String::compareTo) + ) + ); + factory.setResources(resources); + } + catch (IOException exception) { + exception.printStackTrace(); + } } - catch (IOException exception) { - exception.printStackTrace(); + else { + log.info("Bootstrap repository populator disabled"); } + return factory; } } diff --git a/src/main/java/org/fairdatapoint/config/properties/BootstrapProperties.java b/src/main/java/org/fairdatapoint/config/properties/BootstrapProperties.java index a7180009..bb5a1909 100644 --- a/src/main/java/org/fairdatapoint/config/properties/BootstrapProperties.java +++ b/src/main/java/org/fairdatapoint/config/properties/BootstrapProperties.java @@ -36,4 +36,6 @@ public class BootstrapProperties { private boolean enabled; private String dataPath; + // directories relative to project root + private String dbFixturesDir; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 32b61c87..191da5a7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -113,5 +113,6 @@ server: forward-headers-strategy: framework bootstrap: - enabled: true + # TODO: consistent naming for rdf data path and db fixtures dir data-path: '/data' + db-fixtures-dir: "fixtures"