diff --git a/tofhir-common/src/main/scala/io/tofhir/common/model/ICachedRepository.scala b/tofhir-common/src/main/scala/io/tofhir/common/model/ICachedRepository.scala index a986abeb..154e8701 100644 --- a/tofhir-common/src/main/scala/io/tofhir/common/model/ICachedRepository.scala +++ b/tofhir-common/src/main/scala/io/tofhir/common/model/ICachedRepository.scala @@ -5,7 +5,7 @@ package io.tofhir.common.model */ trait ICachedRepository { /** - * Invalidate the internal cache and refresh the cache with the FhirMappings directly from their source + * Invalidate the internal cache and refresh the cache content directly from their source */ def invalidate(): Unit } diff --git a/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ReloadEndpoint.scala b/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ReloadEndpoint.scala index 944ee29f..4ceff0fe 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ReloadEndpoint.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ReloadEndpoint.scala @@ -7,32 +7,20 @@ import com.typesafe.scalalogging.LazyLogging import io.tofhir.engine.Execution.actorSystem.dispatcher import io.tofhir.server.common.model.ToFhirRestCall import io.tofhir.server.endpoint.ReloadEndpoint.SEGMENT_RELOAD +import io.tofhir.server.repository.{FolderDBInitializer, IRepositoryManager} import io.tofhir.server.repository.job.JobFolderRepository import io.tofhir.server.repository.mapping.ProjectMappingFolderRepository import io.tofhir.server.repository.mappingContext.MappingContextFolderRepository import io.tofhir.server.repository.schema.SchemaFolderRepository import io.tofhir.server.repository.terminology.TerminologySystemFolderRepository import io.tofhir.server.service.ReloadService -import io.tofhir.server.service.db.FolderDBInitializer /** * Endpoint to reload resources from the file system. * */ -class ReloadEndpoint(mappingRepository: ProjectMappingFolderRepository, - schemaRepository: SchemaFolderRepository, - mappingJobRepository: JobFolderRepository, - mappingContextRepository: MappingContextFolderRepository, - terminologySystemFolderRepository: TerminologySystemFolderRepository, - folderDBInitializer: FolderDBInitializer) extends LazyLogging { +class ReloadEndpoint(repositoryManager: IRepositoryManager) extends LazyLogging { - val reloadService: ReloadService = new ReloadService( - mappingRepository, - schemaRepository, - mappingJobRepository, - mappingContextRepository, - terminologySystemFolderRepository, - folderDBInitializer - ) + val reloadService: ReloadService = new ReloadService(repositoryManager) def route(request: ToFhirRestCall): Route = { pathPrefix(SEGMENT_RELOAD) { diff --git a/tofhir-server/src/main/scala/io/tofhir/server/endpoint/TerminologyServiceManagerEndpoint.scala b/tofhir-server/src/main/scala/io/tofhir/server/endpoint/TerminologyServiceManagerEndpoint.scala index e4faed9d..96a1ec1c 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/endpoint/TerminologyServiceManagerEndpoint.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/endpoint/TerminologyServiceManagerEndpoint.scala @@ -4,21 +4,23 @@ import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import com.typesafe.scalalogging.LazyLogging +import io.onfhir.definitions.common.model.Json4sSupport._ import io.tofhir.engine.Execution.actorSystem.dispatcher import io.tofhir.server.common.model.{ResourceNotFound, ToFhirRestCall} import io.tofhir.server.endpoint.TerminologyServiceManagerEndpoint._ -import io.onfhir.definitions.common.model.Json4sSupport._ import io.tofhir.server.model.TerminologySystem -import io.tofhir.server.repository.job.JobFolderRepository +import io.tofhir.server.repository.job.IJobRepository import io.tofhir.server.repository.terminology.ITerminologySystemRepository -import io.tofhir.server.service.terminology.TerminologySystemService import io.tofhir.server.repository.terminology.codesystem.ICodeSystemRepository import io.tofhir.server.repository.terminology.conceptmap.IConceptMapRepository +import io.tofhir.server.service.terminology.TerminologySystemService import scala.concurrent.Future -class TerminologyServiceManagerEndpoint(terminologySystemRepository: ITerminologySystemRepository, conceptMapRepository: IConceptMapRepository, - codeSystemRepository: ICodeSystemRepository, mappingJobRepository: JobFolderRepository) extends LazyLogging { +class TerminologyServiceManagerEndpoint(terminologySystemRepository: ITerminologySystemRepository, + conceptMapRepository: IConceptMapRepository, + codeSystemRepository: ICodeSystemRepository, + mappingJobRepository: IJobRepository) extends LazyLogging { private val terminologySystemService: TerminologySystemService = new TerminologySystemService(terminologySystemRepository, mappingJobRepository) diff --git a/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ToFhirServerEndpoint.scala b/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ToFhirServerEndpoint.scala index ddd43c08..bcf0bd00 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ToFhirServerEndpoint.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/endpoint/ToFhirServerEndpoint.scala @@ -16,11 +16,11 @@ import io.tofhir.server.repository.mappingContext.MappingContextFolderRepository import io.tofhir.server.repository.project.{IProjectRepository, ProjectFolderRepository} import io.tofhir.server.repository.schema.SchemaFolderRepository import io.tofhir.server.repository.terminology.{ITerminologySystemRepository, TerminologySystemFolderRepository} -import io.tofhir.server.repository.terminology.codesystem.{CodeSystemRepository, ICodeSystemRepository} -import io.tofhir.server.repository.terminology.conceptmap.{ConceptMapRepository, IConceptMapRepository} -import io.tofhir.server.service.db.FolderDBInitializer +import io.tofhir.server.repository.terminology.codesystem.{CodeSystemFolderRepository, ICodeSystemRepository} +import io.tofhir.server.repository.terminology.conceptmap.{ConceptMapFolderRepository, IConceptMapRepository} import io.tofhir.server.util.ToFhirRejectionHandler import io.onfhir.definitions.fhirpath.endpoint.FhirPathFunctionsEndpoint +import io.tofhir.server.repository.{FolderDBInitializer, FolderRepositoryManager, IRepositoryManager} import java.util.UUID @@ -30,27 +30,33 @@ import java.util.UUID */ class ToFhirServerEndpoint(toFhirEngineConfig: ToFhirEngineConfig, webServerConfig: WebServerConfig, fhirDefinitionsConfig: FhirDefinitionsConfig, redCapServiceConfig: Option[RedCapServiceConfig]) extends ICORSHandler with IErrorHandler { - val projectRepository: IProjectRepository = new ProjectFolderRepository(toFhirEngineConfig) // creating the repository instance globally as weed a singleton instance - val mappingRepository: ProjectMappingFolderRepository = new ProjectMappingFolderRepository(toFhirEngineConfig.mappingRepositoryFolderPath, projectRepository) - val schemaRepository: SchemaFolderRepository = new SchemaFolderRepository(toFhirEngineConfig.schemaRepositoryFolderPath, projectRepository) - val mappingJobRepository: JobFolderRepository = new JobFolderRepository(toFhirEngineConfig.jobRepositoryFolderPath, projectRepository) - val mappingContextRepository: MappingContextFolderRepository = new MappingContextFolderRepository(toFhirEngineConfig.mappingContextRepositoryFolderPath, projectRepository) - val terminologySystemRepository: ITerminologySystemRepository = new TerminologySystemFolderRepository(toFhirEngineConfig.terminologySystemFolderPath) - val conceptMapRepository: IConceptMapRepository = new ConceptMapRepository(toFhirEngineConfig.terminologySystemFolderPath) - val codeSystemRepository: ICodeSystemRepository = new CodeSystemRepository(toFhirEngineConfig.terminologySystemFolderPath) + private val repositoryManager: IRepositoryManager = new FolderRepositoryManager(toFhirEngineConfig) + // Initialize repositories by reading the resources available in the file system + repositoryManager.init() - // Initialize the projects by reading the resources available in the file system - val folderDBInitializer = new FolderDBInitializer(schemaRepository, mappingRepository, mappingJobRepository, projectRepository.asInstanceOf[ProjectFolderRepository], mappingContextRepository) - folderDBInitializer.init() + private val projectEndpoint = new ProjectEndpoint( + repositoryManager.schemaRepository, + repositoryManager.mappingRepository, + repositoryManager.mappingJobRepository, + repositoryManager.mappingContextRepository, + repositoryManager.projectRepository + ) + + val terminologyServiceManagerEndpoint = new TerminologyServiceManagerEndpoint( + repositoryManager.terminologySystemRepository, + repositoryManager.conceptMapRepository, + repositoryManager.codeSystemRepository, + repositoryManager.mappingJobRepository + ) - val projectEndpoint = new ProjectEndpoint(schemaRepository, mappingRepository, mappingJobRepository, mappingContextRepository, projectRepository) val fhirDefinitionsEndpoint = new FhirDefinitionsEndpoint(fhirDefinitionsConfig) val fhirPathFunctionsEndpoint = new FhirPathFunctionsEndpoint(Seq("io.onfhir.path", "io.tofhir.engine.mapping")) val redcapEndpoint = redCapServiceConfig.map(config => new RedCapEndpoint(config)) val fileSystemTreeStructureEndpoint = new FileSystemTreeStructureEndpoint() - val terminologyServiceManagerEndpoint = new TerminologyServiceManagerEndpoint(terminologySystemRepository, conceptMapRepository, codeSystemRepository, mappingJobRepository) val metadataEndpoint = new MetadataEndpoint(toFhirEngineConfig, webServerConfig, fhirDefinitionsConfig, redCapServiceConfig) - val reloadEndpoint= new ReloadEndpoint(mappingRepository, schemaRepository, mappingJobRepository, mappingContextRepository, terminologySystemRepository.asInstanceOf[TerminologySystemFolderRepository], folderDBInitializer) + + val reloadEndpoint= new ReloadEndpoint(repositoryManager) + // Custom rejection handler to send proper messages to user val toFhirRejectionHandler: RejectionHandler = ToFhirRejectionHandler.getRejectionHandler() diff --git a/tofhir-server/src/main/scala/io/tofhir/server/service/db/FolderDBInitializer.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/FolderDBInitializer.scala similarity index 92% rename from tofhir-server/src/main/scala/io/tofhir/server/service/db/FolderDBInitializer.scala rename to tofhir-server/src/main/scala/io/tofhir/server/repository/FolderDBInitializer.scala index b69111a6..ec8b3dc8 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/service/db/FolderDBInitializer.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/FolderDBInitializer.scala @@ -1,4 +1,4 @@ -package io.tofhir.server.service.db +package io.tofhir.server.repository import com.typesafe.scalalogging.Logger import io.onfhir.definitions.common.model.Json4sSupport.formats @@ -23,10 +23,10 @@ import scala.language.postfixOps /** * Folder/Directory based database initializer implementation. * */ -class FolderDBInitializer(schemaFolderRepository: SchemaFolderRepository, +class FolderDBInitializer(projectFolderRepository: ProjectFolderRepository, + schemaFolderRepository: SchemaFolderRepository, mappingFolderRepository: ProjectMappingFolderRepository, mappingJobFolderRepository: JobFolderRepository, - projectFolderRepository: ProjectFolderRepository, mappingContextRepository: MappingContextFolderRepository) { private val logger: Logger = Logger(this.getClass) @@ -40,12 +40,10 @@ class FolderDBInitializer(schemaFolderRepository: SchemaFolderRepository, val parsedProjects = if (file.exists()) { val projects: JArray = FileOperations.readFileIntoJson(file).asInstanceOf[JArray] - val projectMap: Map[String, Project] = projects.arr.map(p => { - val project: Project = initProjectFromMetadata(p.asInstanceOf[JObject]) - project.id -> project - }) - .toMap - collection.mutable.Map(projectMap.toSeq: _*) + projects.arr.map(p => { + val project: Project = initProjectFromMetadata(p.asInstanceOf[JObject]) + project.id -> project + }).toMap } else { logger.debug(s"There does not exist a metadata file (${ProjectFolderRepository.PROJECTS_JSON}) for projects. Creating it...") file.createNewFile() @@ -55,7 +53,6 @@ class FolderDBInitializer(schemaFolderRepository: SchemaFolderRepository, } // Inject the parsed projects to the repository projectFolderRepository.setProjects(parsedProjects) - projectFolderRepository.updateProjectsMetadata() // update the metadata file after initialization } /** @@ -127,7 +124,7 @@ class FolderDBInitializer(schemaFolderRepository: SchemaFolderRepository, * * @return */ - private def initProjectsWithResources(): mutable.Map[String, Project] = { + private def initProjectsWithResources(): Map[String, Project] = { // Map keeping the projects. It uses the project name as a key. val projects: mutable.Map[String, Project] = mutable.Map.empty @@ -171,7 +168,7 @@ class FolderDBInitializer(schemaFolderRepository: SchemaFolderRepository, projects.put(projectId, project.copy(mappingContexts = mappingContextIdList)) } - projects + projects.toMap } /** diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/FolderRepositoryManager.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/FolderRepositoryManager.scala new file mode 100644 index 00000000..fb517a5a --- /dev/null +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/FolderRepositoryManager.scala @@ -0,0 +1,53 @@ +package io.tofhir.server.repository + +import io.tofhir.engine.config.ToFhirEngineConfig +import io.tofhir.server.repository.job.JobFolderRepository +import io.tofhir.server.repository.mapping.ProjectMappingFolderRepository +import io.tofhir.server.repository.mappingContext.MappingContextFolderRepository +import io.tofhir.server.repository.project.ProjectFolderRepository +import io.tofhir.server.repository.schema.SchemaFolderRepository +import io.tofhir.server.repository.terminology.TerminologySystemFolderRepository +import io.tofhir.server.repository.terminology.codesystem.CodeSystemFolderRepository +import io.tofhir.server.repository.terminology.conceptmap.ConceptMapFolderRepository + +/** + * Folder/file based implementation of the RepositoryManager where all managed repositories are folder-based. + * + * @param toFhirEngineConfig + */ +class FolderRepositoryManager(toFhirEngineConfig: ToFhirEngineConfig) extends IRepositoryManager { + + override val projectRepository: ProjectFolderRepository = new ProjectFolderRepository(toFhirEngineConfig) + override val mappingRepository: ProjectMappingFolderRepository = new ProjectMappingFolderRepository(toFhirEngineConfig.mappingRepositoryFolderPath, projectRepository) + override val schemaRepository: SchemaFolderRepository = new SchemaFolderRepository(toFhirEngineConfig.schemaRepositoryFolderPath, projectRepository) + override val mappingJobRepository: JobFolderRepository = new JobFolderRepository(toFhirEngineConfig.jobRepositoryFolderPath, projectRepository) + override val mappingContextRepository: MappingContextFolderRepository = new MappingContextFolderRepository(toFhirEngineConfig.mappingContextRepositoryFolderPath, projectRepository) + + override val terminologySystemRepository: TerminologySystemFolderRepository = new TerminologySystemFolderRepository(toFhirEngineConfig.terminologySystemFolderPath) + override val conceptMapRepository: ConceptMapFolderRepository = new ConceptMapFolderRepository(toFhirEngineConfig.terminologySystemFolderPath) + override val codeSystemRepository: CodeSystemFolderRepository = new CodeSystemFolderRepository(toFhirEngineConfig.terminologySystemFolderPath) + + private val folderDBInitializer = new FolderDBInitializer( + projectRepository, + schemaRepository, + mappingRepository, + mappingJobRepository, + mappingContextRepository + ) + + /** + * Initializes the Repository Manager's internal database (the projects.json file) after initialization of + * each individual repository. + */ + override def init(): Unit = { + folderDBInitializer.init() + } + + /** + * Deletes the internal repository database (the projects.json file) for a fresh start (usually after cache invalidate operations) + */ + override def clear(): Unit = { + folderDBInitializer.removeProjectsJsonFile() + } + +} diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/IRepositoryManager.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/IRepositoryManager.scala new file mode 100644 index 00000000..75300829 --- /dev/null +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/IRepositoryManager.scala @@ -0,0 +1,35 @@ +package io.tofhir.server.repository + +import io.tofhir.server.repository.job.IJobRepository +import io.tofhir.server.repository.mapping.IMappingRepository +import io.tofhir.server.repository.mappingContext.IMappingContextRepository +import io.tofhir.server.repository.project.IProjectRepository +import io.tofhir.server.repository.schema.ISchemaRepository +import io.tofhir.server.repository.terminology.ITerminologySystemRepository +import io.tofhir.server.repository.terminology.codesystem.ICodeSystemRepository +import io.tofhir.server.repository.terminology.conceptmap.IConceptMapRepository + +/** + * Manage the repositories throughout toFHIR + */ +trait IRepositoryManager { + val projectRepository: IProjectRepository + val mappingRepository: IMappingRepository + val schemaRepository: ISchemaRepository + val mappingJobRepository: IJobRepository + val mappingContextRepository: IMappingContextRepository + + val terminologySystemRepository: ITerminologySystemRepository + val conceptMapRepository: IConceptMapRepository + val codeSystemRepository: ICodeSystemRepository + + /** + * Initialize the repository + */ + def init(): Unit + + /** + * Clean-up the repository database + */ + def clear(): Unit +} diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/IMappingRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/IMappingRepository.scala index 7c188834..37bce2bc 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/IMappingRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/IMappingRepository.scala @@ -61,7 +61,7 @@ trait IMappingRepository extends IFhirMappingRepository with IProjectList[FhirMa * * @param projectId The unique identifier of the project for which mappings should be deleted. */ - def deleteProjectMappings(projectId: String): Future[Unit] + def deleteAllMappings(projectId: String): Future[Unit] /** * Retrieves the identifiers of mappings referencing the given schema in their definitions. diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/ProjectMappingFolderRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/ProjectMappingFolderRepository.scala index 204dbf1a..a568e744 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/ProjectMappingFolderRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/mapping/ProjectMappingFolderRepository.scala @@ -156,7 +156,7 @@ class ProjectMappingFolderRepository(mappingRepositoryFolderPath: String, projec * * @param projectId The unique identifier of the project for which mappings should be deleted. */ - override def deleteProjectMappings(projectId: String): Future[Unit] = { + override def deleteAllMappings(projectId: String): Future[Unit] = { Future { // delete mapping definitions for the project org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.getPath(mappingRepositoryFolderPath, projectId).toFile) diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/IMappingContextRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/IMappingContextRepository.scala index 39366318..99c4347e 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/IMappingContextRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/IMappingContextRepository.scala @@ -42,7 +42,7 @@ trait IMappingContextRepository extends ICachedRepository with IProjectList[Stri * * @param projectId The unique identifier of the project for which mapping contexts should be deleted. */ - def deleteProjectMappingContexts(projectId: String): Unit + def deleteAllMappingContexts(projectId: String): Unit /** * Update the mapping context header by its id diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/MappingContextFolderRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/MappingContextFolderRepository.scala index 3f4ba15e..806e434e 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/MappingContextFolderRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/mappingContext/MappingContextFolderRepository.scala @@ -89,7 +89,7 @@ class MappingContextFolderRepository(mappingContextRepositoryFolderPath: String, * * @param projectId The unique identifier of the project for which mapping contexts should be deleted. */ - override def deleteProjectMappingContexts(projectId: String): Unit = { + override def deleteAllMappingContexts(projectId: String): Unit = { Future { // delete mapping context definitions for the project org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.getPath(mappingContextRepositoryFolderPath, projectId).toFile) diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/project/IProjectRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/project/IProjectRepository.scala index 2e610230..3c0e0fa8 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/project/IProjectRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/project/IProjectRepository.scala @@ -19,6 +19,8 @@ trait IProjectRepository { */ def getAllProjects: Future[Seq[Project]] + + /** * Save project to the repository. * diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/project/ProjectFolderRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/project/ProjectFolderRepository.scala index 9e68e20c..a16be8f2 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/project/ProjectFolderRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/project/ProjectFolderRepository.scala @@ -27,15 +27,17 @@ class ProjectFolderRepository(config: ToFhirEngineConfig) extends IProjectReposi private val logger: Logger = Logger(this.getClass) // Project cache keeping the up-to-date list of projects - private var projects: mutable.Map[String, Project] = mutable.Map.empty + private val projects: mutable.Map[String, Project] = mutable.Map.empty /** - * Initializes the projects cache + * Initializes the projects cache with the given Map of projects and persist to the file (projects.json) * * @param projects */ - def setProjects(projects: mutable.Map[String, Project]): Unit = { - this.projects = projects + def setProjects(vProjects: Map[String, Project]): Unit = { + this.projects.clear() + this.projects ++= vProjects + this.updateProjectsMetadata() } /** @@ -326,7 +328,7 @@ class ProjectFolderRepository(config: ToFhirEngineConfig) extends IProjectReposi /** * Updates the projects metadata with project included in the cache. */ - def updateProjectsMetadata(): Unit = { + private def updateProjectsMetadata(): Unit = { val file = FileUtils.getPath(ProjectFolderRepository.PROJECTS_JSON).toFile // when projects metadata file does not exist, create it if (!file.exists()) { diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/ISchemaRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/ISchemaRepository.scala index 3cd7b933..e027501a 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/ISchemaRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/ISchemaRepository.scala @@ -71,7 +71,7 @@ trait ISchemaRepository extends IFhirSchemaLoader with ICachedRepository with IP * * @param projectId The unique identifier of the project for which schemas should be deleted. */ - def deleteProjectSchemas(projectId: String): Future[Unit] + def deleteAllSchemas(projectId: String): Future[Unit] /** * Retrieve the Structure Definition of the schema identified by its id. diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/SchemaFolderRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/SchemaFolderRepository.scala index 65a288c1..3cc0015e 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/SchemaFolderRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/schema/SchemaFolderRepository.scala @@ -198,7 +198,7 @@ class SchemaFolderRepository(schemaRepositoryFolderPath: String, projectReposito * * @param projectId The unique identifier of the project for which schemas should be deleted. */ - override def deleteProjectSchemas(projectId: String): Future[Unit] = { + override def deleteAllSchemas(projectId: String): Future[Unit] = { Future { // delete schema definitions for the project org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.getPath(schemaRepositoryFolderPath, projectId).toFile) diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/ITerminologySystemRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/ITerminologySystemRepository.scala index fd82833a..892bb571 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/ITerminologySystemRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/ITerminologySystemRepository.scala @@ -1,5 +1,6 @@ package io.tofhir.server.repository.terminology +import io.tofhir.common.model.ICachedRepository import io.tofhir.server.model.TerminologySystem import scala.concurrent.Future @@ -8,7 +9,7 @@ import scala.concurrent.Future * Interface to save and load TerminologySystem so that the client applications can manage the TerminologySystem * through CRUD operations */ -trait ITerminologySystemRepository { +trait ITerminologySystemRepository extends ICachedRepository{ /** * Retrieve the metadata of all TerminologySystems diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/codesystem/CodeSystemRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/codesystem/CodeSystemFolderRepository.scala similarity index 99% rename from tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/codesystem/CodeSystemRepository.scala rename to tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/codesystem/CodeSystemFolderRepository.scala index 8632af97..2a6c370b 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/codesystem/CodeSystemRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/codesystem/CodeSystemFolderRepository.scala @@ -16,7 +16,7 @@ import org.json4s.jackson.Serialization.writePretty import java.io.FileWriter import scala.concurrent.Future -class CodeSystemRepository(terminologySystemFolderPath: String) extends ICodeSystemRepository { +class CodeSystemFolderRepository(terminologySystemFolderPath: String) extends ICodeSystemRepository { /** * Retrieve the code system within a terminology * diff --git a/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/conceptmap/ConceptMapRepository.scala b/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/conceptmap/ConceptMapFolderRepository.scala similarity index 99% rename from tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/conceptmap/ConceptMapRepository.scala rename to tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/conceptmap/ConceptMapFolderRepository.scala index 14d3b121..c8604da9 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/conceptmap/ConceptMapRepository.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/repository/terminology/conceptmap/ConceptMapFolderRepository.scala @@ -17,7 +17,7 @@ import org.json4s.jackson.Serialization.writePretty import java.io.{File, FileWriter} import scala.concurrent.Future -class ConceptMapRepository(terminologySystemFolderPath: String) extends IConceptMapRepository { +class ConceptMapFolderRepository(terminologySystemFolderPath: String) extends IConceptMapRepository { /** * Retrieve the concept maps within a terminology diff --git a/tofhir-server/src/main/scala/io/tofhir/server/service/ProjectService.scala b/tofhir-server/src/main/scala/io/tofhir/server/service/ProjectService.scala index 2585f2ae..29c52f7d 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/service/ProjectService.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/service/ProjectService.scala @@ -75,9 +75,9 @@ class ProjectService(projectRepository: IProjectRepository, // else delete jobs, mappings, mapping contexts and schemas as well .flatMap { _ => jobRepository.deleteAllJobs(projectId) map { _ => - mappingRepository.deleteProjectMappings(projectId) - mappingContextRepository.deleteProjectMappingContexts(projectId) - schemaRepository.deleteProjectSchemas(projectId) + mappingRepository.deleteAllMappings(projectId) + mappingContextRepository.deleteAllMappingContexts(projectId) + schemaRepository.deleteAllSchemas(projectId) } } } diff --git a/tofhir-server/src/main/scala/io/tofhir/server/service/ReloadService.scala b/tofhir-server/src/main/scala/io/tofhir/server/service/ReloadService.scala index 4602e22d..860e5ed0 100644 --- a/tofhir-server/src/main/scala/io/tofhir/server/service/ReloadService.scala +++ b/tofhir-server/src/main/scala/io/tofhir/server/service/ReloadService.scala @@ -1,24 +1,19 @@ package io.tofhir.server.service import io.tofhir.engine.Execution.actorSystem.dispatcher +import io.tofhir.server.repository.{FolderDBInitializer, IRepositoryManager} import io.tofhir.server.repository.job.JobFolderRepository import io.tofhir.server.repository.mapping.ProjectMappingFolderRepository import io.tofhir.server.repository.mappingContext.MappingContextFolderRepository import io.tofhir.server.repository.schema.SchemaFolderRepository import io.tofhir.server.repository.terminology.TerminologySystemFolderRepository -import io.tofhir.server.service.db.FolderDBInitializer import scala.concurrent.Future /** * Service for reloading resources from the file system. */ -class ReloadService(mappingRepository: ProjectMappingFolderRepository, - schemaRepository: SchemaFolderRepository, - mappingJobRepository: JobFolderRepository, - mappingContextRepository: MappingContextFolderRepository, - terminologySystemFolderRepository: TerminologySystemFolderRepository, - folderDBInitializer: FolderDBInitializer) { +class ReloadService(repositoryManager: IRepositoryManager) { /** * Reload all resources. @@ -27,14 +22,13 @@ class ReloadService(mappingRepository: ProjectMappingFolderRepository, */ def reloadResources(): Future[Unit] = { Future { - mappingRepository.invalidate() - schemaRepository.invalidate() - mappingJobRepository.invalidate() - mappingContextRepository.invalidate() - terminologySystemFolderRepository.invalidate() - // Delete projects.json before reloading the projects - folderDBInitializer.removeProjectsJsonFile() - folderDBInitializer.init() + repositoryManager.mappingRepository.invalidate() + repositoryManager.schemaRepository.invalidate() + repositoryManager.mappingJobRepository.invalidate() + repositoryManager.mappingContextRepository.invalidate() + repositoryManager.terminologySystemRepository.invalidate() + repositoryManager.clear() + repositoryManager.init() } } }