diff --git a/core/config-kryo/build.gradle b/core/config-kryo/build.gradle new file mode 100644 index 000000000..06fd4198b --- /dev/null +++ b/core/config-kryo/build.gradle @@ -0,0 +1,70 @@ +apply plugin: 'java-library' +apply plugin: 'kotlin' +apply plugin: 'maven-publish' + +ext { + version_kryo = '5.6.0' +} + +compileJava { + sourceCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + implementation project(':core:imposter-api') + implementation project(':core:config') + + api "com.esotericsoftware:kryo:$version_kryo" + + // test + testImplementation "junit:junit:$version_junit" + testImplementation group: 'org.hamcrest', name: 'hamcrest', version: version_hamcrest + testImplementation "org.apache.logging.log4j:log4j-core:$version_log4j" + testImplementation "org.apache.logging.log4j:log4j-slf4j-impl:$version_log4j" +} + +task sourcesJar(type: Jar, dependsOn: classes) { + archiveClassifier = 'sources' + from sourceSets.main.allSource +} + +artifacts { + archives sourcesJar +} + +publishing { + publications { + maven(MavenPublication) { + from components.java + artifact sourcesJar + + repositories { + maven { + url = version.endsWith('SNAPSHOT') ? mavenSnapshotRepository : mavenReleaseRepository + credentials(AwsCredentials) { + accessKey awsAccessKey + secretKey awsSecretKey + } + } + } + } + } +} + +compileKotlin { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11 + + // see https://kotlinlang.org/docs/java-to-kotlin-interop.html#default-methods-in-interfaces + freeCompilerArgs = ["-Xjvm-default=all"] + } +} + +compileTestKotlin { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11 + + // see https://kotlinlang.org/docs/java-to-kotlin-interop.html#default-methods-in-interfaces + freeCompilerArgs = ["-Xjvm-default=all"] + } +} diff --git a/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/BinarySerialiser.kt b/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/BinarySerialiser.kt new file mode 100644 index 000000000..2b8fc799d --- /dev/null +++ b/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/BinarySerialiser.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024. + * + * This file is part of Imposter. + * + * "Commons Clause" License Condition v1.0 + * + * The Software is provided to you by the Licensor under the License, as + * defined below, subject to the following condition. + * + * Without limiting other conditions in the License, the grant of rights + * under the License will not include, and the License does not grant to + * you, the right to Sell the Software. + * + * For purposes of the foregoing, "Sell" means practicing any or all of + * the rights granted to you under the License to provide to third parties, + * for a fee or other consideration (including without limitation fees for + * hosting or consulting/support services related to the Software), a + * product or service whose value derives, entirely or substantially, from + * the functionality of the Software. Any license notice or attribution + * required by the License must also include this Commons Clause License + * Condition notice. + * + * Software: Imposter + * + * License: GNU Lesser General Public License version 3 + * + * Licensor: Peter Cornish + * + * Imposter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Imposter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Imposter. If not, see . + */ + +package io.gatehill.imposter.config.loader.kryo + +import com.esotericsoftware.kryo.Kryo +import com.esotericsoftware.kryo.io.Input +import com.esotericsoftware.kryo.io.Output +import org.apache.logging.log4j.LogManager +import java.io.File + +/** + * + * @author pete + */ +object BinarySerialiser { + private val logger = LogManager.getLogger(BinarySerialiser::class.java) + + private val kryo = Kryo().apply { + isRegistrationRequired = false + references = true + } + + fun buildKryoPath(file: File): String { + return file.absolutePath + ".bin" + } + + fun serialise(obj: Any, filePath: String) { + File(filePath).outputStream().use { + val output = Output(it) + kryo.writeClassAndObject(output, obj) + output.close() + } + logger.debug("Serialised to $filePath") + } + + fun deserialise(filePath: String): T { + logger.debug("Deserialising from $filePath") + return File(filePath).inputStream().use { + val input = Input(it) + @Suppress("UNCHECKED_CAST") + val obj = kryo.readClassAndObject(input) as T + input.close() + obj + } + } +} diff --git a/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/KryoConfigLoaderImpl.kt b/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/KryoConfigLoaderImpl.kt new file mode 100644 index 000000000..2266a2421 --- /dev/null +++ b/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/KryoConfigLoaderImpl.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024. + * + * This file is part of Imposter. + * + * "Commons Clause" License Condition v1.0 + * + * The Software is provided to you by the Licensor under the License, as + * defined below, subject to the following condition. + * + * Without limiting other conditions in the License, the grant of rights + * under the License will not include, and the License does not grant to + * you, the right to Sell the Software. + * + * For purposes of the foregoing, "Sell" means practicing any or all of + * the rights granted to you under the License to provide to third parties, + * for a fee or other consideration (including without limitation fees for + * hosting or consulting/support services related to the Software), a + * product or service whose value derives, entirely or substantially, from + * the functionality of the Software. Any license notice or attribution + * required by the License must also include this Commons Clause License + * Condition notice. + * + * Software: Imposter + * + * License: GNU Lesser General Public License version 3 + * + * Licensor: Peter Cornish + * + * Imposter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Imposter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Imposter. If not, see . + */ + +package io.gatehill.imposter.config.loader.kryo + +import io.gatehill.imposter.config.ConfigReference +import io.gatehill.imposter.config.loader.ConfigLoader +import io.gatehill.imposter.plugin.config.BasicPluginConfig +import io.gatehill.imposter.plugin.config.PluginConfigImpl +import java.io.File + +/** + * Kryo implementation of a configuration loader. + * + * @author Pete Cornish + */ +class KryoConfigLoaderImpl : ConfigLoader { + override fun readPluginConfig(configRef: ConfigReference): KryoLoadedConfigImpl { + val kryoFile = BinarySerialiser.buildKryoPath(configRef.file) + val config: PluginConfigImpl = BinarySerialiser.deserialise(kryoFile) + return KryoLoadedConfigImpl( + ref = configRef, + plugin = config.plugin!!, + serialised = "", + deserialised = config + ) + } + + override fun loadConfig(configFile: File, loadedConfig: KryoLoadedConfigImpl, configClass: Class): T { + @Suppress("UNCHECKED_CAST") + return loadedConfig.deserialised as T + } +} diff --git a/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/KryoLoadedConfigImpl.kt b/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/KryoLoadedConfigImpl.kt new file mode 100644 index 000000000..ebf314bfb --- /dev/null +++ b/core/config-kryo/src/main/java/io/gatehill/imposter/config/loader/kryo/KryoLoadedConfigImpl.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024. + * + * This file is part of Imposter. + * + * "Commons Clause" License Condition v1.0 + * + * The Software is provided to you by the Licensor under the License, as + * defined below, subject to the following condition. + * + * Without limiting other conditions in the License, the grant of rights + * under the License will not include, and the License does not grant to + * you, the right to Sell the Software. + * + * For purposes of the foregoing, "Sell" means practicing any or all of + * the rights granted to you under the License to provide to third parties, + * for a fee or other consideration (including without limitation fees for + * hosting or consulting/support services related to the Software), a + * product or service whose value derives, entirely or substantially, from + * the functionality of the Software. Any license notice or attribution + * required by the License must also include this Commons Clause License + * Condition notice. + * + * Software: Imposter + * + * License: GNU Lesser General Public License version 3 + * + * Licensor: Peter Cornish + * + * Imposter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Imposter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Imposter. If not, see . + */ + +package io.gatehill.imposter.config.loader.kryo + +import io.gatehill.imposter.config.ConfigReference +import io.gatehill.imposter.config.LoadedConfig +import io.gatehill.imposter.plugin.config.BasicPluginConfig + +/** + * + * @author pete + */ +data class KryoLoadedConfigImpl( + override val ref: ConfigReference, + override val serialised: String, + override val plugin: String, + val deserialised: BasicPluginConfig +) : LoadedConfig diff --git a/settings.gradle b/settings.gradle index d97eb5cf0..c092b8549 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,6 +8,7 @@ project(':core:api').name = 'imposter-api' include ':core:config' include ':core:config-dynamic' +include ':core:config-kryo' include ':core:config-resolver-s3' include ':core:engine' @@ -108,3 +109,6 @@ include ':lib:fake-data' // observability include ':tools:perf-monitor' + +// utils +include ':tools:kryo-util'