From 26d696d66b87243cac1eca48eae5947f971558f2 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Sat, 1 Jan 2022 18:01:59 -0500 Subject: [PATCH] #18 Add logging to cache --- build.gradle.kts | 2 +- .../initializers/MaterialTypeInitializer.kt | 2 +- .../service/MaterialTypeService.kt | 31 ++++++++++++------- .../service/files/FileExistCache.kt | 15 ++++++--- .../service/files/FileService.kt | 22 +++++++++++-- .../fyloz/colorrecipesexplorer/utils/Files.kt | 18 +++++------ src/main/resources/logback.xml | 6 ++-- .../service/files/FileServiceTest.kt | 4 +-- 8 files changed, 64 insertions(+), 36 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4922681..3b1bfaf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -102,7 +102,7 @@ tasks.withType() { } tasks.withType().all { kotlinOptions { - jvmTarget = JavaVersion.VERSION_11.toString() + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = listOf( "-Xopt-in=kotlin.contracts.ExperimentalContracts", "-Xinline-classes" diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/initializers/MaterialTypeInitializer.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/initializers/MaterialTypeInitializer.kt index 1bb99d2..d9ea14f 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/initializers/MaterialTypeInitializer.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/initializers/MaterialTypeInitializer.kt @@ -51,7 +51,7 @@ class MaterialTypeInitializer( // Remove old system types oldSystemTypes.forEach { logger.info("Material type '${it.name}' is not a system type anymore") - materialTypeService.update(materialType(it, newSystemType = false)) + materialTypeService.updateSystemType(it.copy(systemType = false)) } } } \ No newline at end of file diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt index 92a3445..9890fa8 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialTypeService.kt @@ -7,7 +7,7 @@ import org.springframework.context.annotation.Profile import org.springframework.stereotype.Service interface MaterialTypeService : - ExternalNamedModelService { + ExternalNamedModelService { /** Checks if a material type with the given [prefix] exists. */ fun existsByPrefix(prefix: String): Boolean @@ -19,14 +19,17 @@ interface MaterialTypeService : /** Gets all material types who are not a system type. */ fun getAllNonSystemType(): Collection + + /** Allows to update the given system [materialType], should not be exposed to users. */ + fun updateSystemType(materialType: MaterialType): MaterialType } @Service @Profile("!emergency") class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val materialService: MaterialService) : - AbstractExternalNamedModelService( - repository - ), MaterialTypeService { + AbstractExternalNamedModelService( + repository + ), MaterialTypeService { override fun idNotFoundException(id: Long) = materialTypeIdNotFoundException(id) override fun idAlreadyExistsException(id: Long) = materialIdAlreadyExistsException(id) override fun nameNotFoundException(name: String) = materialTypeNameNotFoundException(name) @@ -36,7 +39,7 @@ class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val ma override fun existsByPrefix(prefix: String): Boolean = repository.existsByPrefix(prefix) override fun isUsedByMaterial(materialType: MaterialType): Boolean = - materialService.existsByMaterialType(materialType) + materialService.existsByMaterialType(materialType) override fun getAllSystemTypes(): Collection = repository.findAllBySystemTypeIs(true) override fun getAllNonSystemType(): Collection = repository.findAllBySystemTypeIs(false) @@ -52,16 +55,22 @@ class MaterialTypeServiceImpl(repository: MaterialTypeRepository, private val ma return update(with(entity) { MaterialType( - id = id, - name = if (isNotNullAndNotBlank(name)) name else persistedMaterialType.name, - prefix = if (isNotNullAndNotBlank(prefix)) prefix else persistedMaterialType.prefix, - systemType = false + id = id, + name = if (isNotNullAndNotBlank(name)) name else persistedMaterialType.name, + prefix = if (isNotNullAndNotBlank(prefix)) prefix else persistedMaterialType.prefix, + systemType = false ) }) } - override fun update(entity: MaterialType): MaterialType { - if (repository.existsByIdAndSystemTypeIsTrue(entity.id!!)) { + override fun updateSystemType(materialType: MaterialType) = + update(materialType, true) + + override fun update(entity: MaterialType) = + update(entity, false) + + private fun update(entity: MaterialType, allowSystemTypes: Boolean): MaterialType { + if (!allowSystemTypes && repository.existsByIdAndSystemTypeIsTrue(entity.id!!)) { throw cannotUpdateSystemMaterialTypeException(entity) } diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileExistCache.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileExistCache.kt index bbeccb8..783262b 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileExistCache.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileExistCache.kt @@ -1,17 +1,19 @@ package dev.fyloz.colorrecipesexplorer.service.files import dev.fyloz.colorrecipesexplorer.utils.FilePath +import mu.KotlinLogging object FileExistCache { - private val map = hashMapOf() + private val logger = KotlinLogging.logger {} + private val map = hashMapOf() /** Checks if the given [path] is in the cache. */ operator fun contains(path: FilePath) = - path in map + path.path in map /** Checks if the file at the given [path] exists. */ fun exists(path: FilePath) = - map[path] ?: false + map[path.path] ?: false /** Sets the file at the given [path] as existing. */ fun setExists(path: FilePath) = @@ -21,7 +23,10 @@ object FileExistCache { fun setDoesNotExists(path: FilePath) = set(path, false) - private fun set(path: FilePath, exists: Boolean) { - map[path] = exists + /** Sets if the file at the given [path] [exists]. */ + fun set(path: FilePath, exists: Boolean) { + map[path.path] = exists + + logger.debug("Updated FileExistCache state: ${path.path} -> $exists") } } \ No newline at end of file diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileService.kt index d3a7615..0179a47 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileService.kt @@ -5,6 +5,7 @@ import dev.fyloz.colorrecipesexplorer.exception.RestException import dev.fyloz.colorrecipesexplorer.utils.File import dev.fyloz.colorrecipesexplorer.utils.FilePath import dev.fyloz.colorrecipesexplorer.utils.withFileAt +import mu.KotlinLogging import org.slf4j.Logger import org.springframework.core.io.ByteArrayResource import org.springframework.core.io.Resource @@ -47,16 +48,19 @@ interface WriteableFileService : FileService { @Service class FileServiceImpl( - private val creProperties: CreProperties, - private val logger: Logger + private val creProperties: CreProperties ) : WriteableFileService { + private val logger = KotlinLogging.logger {} + override fun exists(path: String): Boolean { val fullPath = path.fullPath() return if (fullPath in FileExistCache) { FileExistCache.exists(fullPath) } else { withFileAt(fullPath) { - this.exists() && this.isFile + (this.exists() && this.isFile).also { + FileExistCache.set(fullPath, it) + } } } } @@ -79,6 +83,8 @@ class FileServiceImpl( withFileAt(fullPath) { this.create() FileExistCache.setExists(fullPath) + + logger.info("Created file at '${fullPath.path}'") } } catch (ex: IOException) { FileCreateException(path).logAndThrow(ex, logger) @@ -88,11 +94,13 @@ class FileServiceImpl( override fun write(file: MultipartFile, path: String, overwrite: Boolean) = prepareWrite(path, overwrite) { + logWrittenDataSize(file.size) file.transferTo(this.toPath()) } override fun write(data: ByteArrayResource, path: String, overwrite: Boolean) = prepareWrite(path, overwrite) { + logWrittenDataSize(data.contentLength()) this.writeBytes(data.byteArray) } @@ -104,6 +112,8 @@ class FileServiceImpl( this.delete() FileExistCache.setDoesNotExists(fullPath) + + logger.info("Deleted file at '${fullPath.path}'") } } catch (ex: IOException) { FileDeleteException(path).logAndThrow(ex, logger) @@ -130,11 +140,17 @@ class FileServiceImpl( try { withFileAt(fullPath) { this.op() + + logger.info("Wrote data to file at '${fullPath.path}'") } } catch (ex: IOException) { FileWriteException(path).logAndThrow(ex, logger) } } + + private fun logWrittenDataSize(size: Long) { + logger.debug("Writing $size bytes to file system...") + } } private const val FILE_IO_EXCEPTION_TITLE = "File IO error" diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/utils/Files.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/utils/Files.kt index 7f3f2b3..6efb4fb 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/utils/Files.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/utils/Files.kt @@ -10,29 +10,29 @@ class File(val file: JavaFile) { get() = file.isFile fun toPath(): Path = - file.toPath() + file.toPath() fun exists() = - file.exists() + file.exists() fun readBytes() = - file.readBytes() + file.readBytes() fun writeBytes(array: ByteArray) = - file.writeBytes(array) + file.writeBytes(array) fun create() = - file.create() + file.create() fun delete(): Boolean = - file.delete() + file.delete() companion object { fun from(path: String) = - File(JavaFile(path)) + File(JavaFile(path)) fun from(path: FilePath) = - from(path.path) + from(path.path) } } @@ -41,7 +41,7 @@ class FilePath(val path: String) /** Runs the given [block] in the context of a file with the given [fullPath]. */ fun withFileAt(fullPath: FilePath, block: File.() -> T) = - File.from(fullPath).block() + File.from(fullPath).block() /** Shortcut to create a file and its parent directories. */ fun JavaFile.create() { diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 1ecd253..a338b2c 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -8,9 +8,9 @@ %green(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{36}): %msg%n%throwable - - INFO - + + + diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt index 491257c..355e949 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/files/FileServiceTest.kt @@ -22,9 +22,7 @@ private val mockFilePathPath = Path.of(mockFilePath) private val mockFileData = byteArrayOf(0x1, 0x8, 0xa, 0xf) class FileServiceTest { - private val fileService = spyk(FileServiceImpl(creProperties, mockk { - every { error(any(), any()) } just Runs - })) + private val fileService = spyk(FileServiceImpl(creProperties)) private val mockFile = mockk { every { file } returns mockk() every { exists() } returns true