Skip to content
Merged
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
65 changes: 51 additions & 14 deletions src/main/java/org/fairdatapoint/config/BootstrapConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 <project-root>/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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@
public class BootstrapProperties {
private boolean enabled;
private String dataPath;
// directories relative to project root
private String dbFixturesDir;
}
3 changes: 2 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"