diff --git a/acl-engine/src/main/java/javasabr/mqtt/acl/engine/exception/AclConfigurationException.java b/acl-engine/src/main/java/javasabr/mqtt/acl/engine/exception/AclConfigurationException.java index 0c3d6f36..67cfd46e 100644 --- a/acl-engine/src/main/java/javasabr/mqtt/acl/engine/exception/AclConfigurationException.java +++ b/acl-engine/src/main/java/javasabr/mqtt/acl/engine/exception/AclConfigurationException.java @@ -5,4 +5,8 @@ public class AclConfigurationException extends RuntimeException { public AclConfigurationException(String message) { super(message); } + + public AclConfigurationException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/acl-groovy-dsl/src/main/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoader.groovy b/acl-groovy-dsl/src/main/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoader.groovy index e8d7e59d..54584999 100644 --- a/acl-groovy-dsl/src/main/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoader.groovy +++ b/acl-groovy-dsl/src/main/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoader.groovy @@ -1,26 +1,14 @@ package javasabr.mqtt.acl.groovy.dsl.loader import javasabr.mqtt.acl.engine.builder.RuleContainerBuilder -import javasabr.mqtt.acl.engine.exception.AclConfigurationException import javasabr.mqtt.acl.engine.model.rule.AclRule import javasabr.mqtt.acl.groovy.dsl.builder.AclRulesBuilder import javasabr.mqtt.model.acl.Operation import javasabr.rlib.collections.array.Array -import java.nio.file.Files -import java.nio.file.Path - class AclRulesLoader { - static Map> load(String aclConfigPath) { - return load(Path.of(aclConfigPath)) - } - - static Map> load(Path aclConfigPath) { - if (Files.notExists(aclConfigPath)) { - throw new AclConfigurationException("Config file:[%s] doesn't exist".formatted(aclConfigPath)) - } - + static Map> load(InputStream aclConfigPath) { AclRulesBuilder aclRulesBuilder = new AclRulesBuilder() def binding = new Binding() @@ -32,7 +20,7 @@ class AclRulesLoader { } def groovyShell = new GroovyShell(binding) - groovyShell.evaluate(aclConfigPath.toFile()) + groovyShell.evaluate(new InputStreamReader(aclConfigPath)) return RuleContainerBuilder.groupRulesByOperation(aclRulesBuilder.build()) } diff --git a/acl-groovy-dsl/src/test/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoaderTest.groovy b/acl-groovy-dsl/src/test/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoaderTest.groovy index bdfcacca..d843c22b 100644 --- a/acl-groovy-dsl/src/test/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoaderTest.groovy +++ b/acl-groovy-dsl/src/test/groovy/javasabr/mqtt/acl/groovy/dsl/loader/AclRulesLoaderTest.groovy @@ -25,6 +25,9 @@ import javasabr.mqtt.service.acl.TestRulesGenerator import javasabr.mqtt.test.support.UnitSpecification import javasabr.rlib.collections.array.Array +import java.nio.file.Files +import java.nio.file.NoSuchFileException +import java.nio.file.Path import java.util.concurrent.CompletionException import static javasabr.mqtt.acl.engine.model.Action.ALLOW @@ -38,29 +41,29 @@ class AclRulesLoaderTest extends UnitSpecification { given: def ruleFile = TestRulesGenerator.generate(100) when: - def load = AclRulesLoader.load(ruleFile.toString()) + def load = AclRulesLoader.load(new FileInputStream(ruleFile)) then: load.get(SUBSCRIBE).size() == 50 load.get(PUBLISH).size() == 50 ruleFile.delete() } - def "should throw exception if config not exists"(String configPath, String errorMessage) { + def "should throw exception if config not exists"(String configPath) { when: - AclRulesLoader.load(configPath) + AclRulesLoader.load(Files.newInputStream(Path.of(configPath))) then: - def exception = thrown(AclConfigurationException) - exception.message == errorMessage + def exception = thrown(NoSuchFileException) + exception.message == configPath where: - configPath | errorMessage - "not/existed/path" | 'Config file:[not/existed/path] doesn\'t exist' + configPath | _ + "not/existed/path" | _ } def "should work fine with only publish rules"() { given: def onlyPublishRulesAclPath = getAbsolutePath("acl/config/acl-publish-only.gacl") when: - def ruleMap = AclRulesLoader.load(onlyPublishRulesAclPath) + def ruleMap = AclRulesLoader.load(Files.newInputStream(Path.of(onlyPublishRulesAclPath))) then: noExceptionThrown() !ruleMap.get(PUBLISH).isEmpty() @@ -71,7 +74,7 @@ class AclRulesLoaderTest extends UnitSpecification { given: def invalidAclPath = getAbsolutePath("acl/config/invalid/${invalidAclFileName}") when: - AclRulesLoader.load(invalidAclPath) + AclRulesLoader.load(Files.newInputStream(Path.of(invalidAclPath))) then: def exception = thrown CompletionException exceptionClass.isInstance exception.cause @@ -98,7 +101,7 @@ class AclRulesLoaderTest extends UnitSpecification { def "should parse Groovy DSL config"() { when: def absolutePath = getAbsolutePath("acl/config/acl.gacl") - def rules = AclRulesLoader.load(absolutePath) + def rules = AclRulesLoader.load(Files.newInputStream(Path.of(absolutePath))) then: verifyAll(rules.get(PUBLISH)) { size() == 3 diff --git a/acl-service/src/main/java/javasabr/mqtt/acl/service/impl/GroovyDslBasedAuthorizationService.java b/acl-service/src/main/java/javasabr/mqtt/acl/service/impl/GroovyDslBasedAuthorizationService.java index ff439c3d..a4544fec 100644 --- a/acl-service/src/main/java/javasabr/mqtt/acl/service/impl/GroovyDslBasedAuthorizationService.java +++ b/acl-service/src/main/java/javasabr/mqtt/acl/service/impl/GroovyDslBasedAuthorizationService.java @@ -1,14 +1,15 @@ package javasabr.mqtt.acl.service.impl; +import java.io.IOException; +import java.io.InputStream; import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Map; import javasabr.mqtt.acl.engine.AclEngine; import javasabr.mqtt.acl.engine.exception.AclConfigurationException; import javasabr.mqtt.acl.engine.model.rule.AclRule; import javasabr.mqtt.acl.groovy.dsl.loader.AclRulesLoader; import javasabr.mqtt.acl.service.AclEngineBasedAuthorizationService; +import javasabr.mqtt.base.util.ClassPathResourceResolver; import javasabr.mqtt.model.acl.Operation; import javasabr.rlib.collections.array.Array; import lombok.CustomLog; @@ -17,15 +18,13 @@ public class GroovyDslBasedAuthorizationService extends AclEngineBasedAuthorizationService { public void loadFrom(URI resource) { - Path localFile = Path.of(resource); - if (Files.notExists(localFile)) { - throw new AclConfigurationException("ACL configuration:[%s] doesn't exist".formatted(resource)); - } else if (Files.isDirectory(localFile)) { - throw new AclConfigurationException("ACL configuration:[%s] is directory".formatted(resource)); + try (InputStream aclInputStream = ClassPathResourceResolver.newInputStream(resource)) { + Map> loadedAclRulesMap = AclRulesLoader.load(aclInputStream); + switchTo(new AclEngine(loadedAclRulesMap)); + log.info(resource, loadedAclRulesMap, GroovyDslBasedAuthorizationService::buildServiceDescription); + } catch (IOException e) { + throw new AclConfigurationException("ACL configuration issue:[%s]".formatted(resource), e); } - Map> loadedAclRulesMap = AclRulesLoader.load(localFile); - switchTo(new AclEngine(loadedAclRulesMap)); - log.info(resource, loadedAclRulesMap, GroovyDslBasedAuthorizationService::buildServiceDescription); } private static String buildServiceDescription(URI resource, Map> aclRulesMap) { diff --git a/application/build.gradle b/application/build.gradle index 8ec3ebae..5b4b23b1 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -3,6 +3,7 @@ plugins { id("configure-java") id("groovy") id("org.springframework.boot") + id 'org.graalvm.buildtools.native' } description = "Standard configuration of standalone version of MQTT Broker" @@ -16,10 +17,12 @@ dependencies { implementation libs.springboot.starter.core implementation libs.springboot.starter.log4j2 + runtimeOnly projects.credentialsSourceFile + runtimeOnly projects.authenticationProviderBasic + testImplementation projects.testSupport testImplementation testFixtures(projects.network) - testImplementation projects.credentialsSourceFile - testImplementation projects.authenticationProviderBasic + testImplementation libs.junit.platform.testkit } tasks.withType(GroovyCompile).configureEach { @@ -28,10 +31,64 @@ tasks.withType(GroovyCompile).configureEach { } bootRun { - mainClass = "javasabr.mqtt.broker.application.MqttBrokerApplication" jvmArgs += "--enable-preview" } bootJar { mainClass = "javasabr.mqtt.broker.application.MqttBrokerApplication" } + +graalvmNative { + toolchainDetection = true + binaries { + main { + sharedLibrary = false + buildArgs.add("--enable-preview") + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(25) + vendor = JvmVendorSpec.matching("GraalVM Community") + } + } + } +} + +jar { + from(sourceSets.aot.output) +} + +processAot { + jvmArgs([ + '-Dauthentication.credentials-source.database.enabled=true', + '-Dauthentication.credentials-source.file.enabled=true', + '-Dauthentication.provider.basic.enabled=true', + '-Dmqtt.external.tls.network.enabled=true', + ]) +} + +tasks.register('copyNativeImageTestResources', Copy) { + mustRunAfter 'nativeCompile' + from('src/test/resources/application-test.properties') { + rename 'application-test.properties', "application.properties" + } + from('src/test/resources/log4j2-test.xml') { + rename 'log4j2-test.xml', "log4j2.xml" + } + from('src/test/resources/auth/credentials-test') { + into 'auth' + } + from('src/test/resources/test-acl.gacl') + into layout.buildDirectory.dir("native/nativeCompile") +} + +tasks.register('nativeImageTest', Test) { + dependsOn 'nativeCompile', 'copyNativeImageTestResources' + useJUnitPlatform() + + group = 'verification' + testClassesDirs = sourceSets.test.output.classesDirs + classpath = sourceSets.test.runtimeClasspath + + filter { + includeTestsMatching 'javasabr.mqtt.broker.application.NativeImageVerificationTest' + } +} diff --git a/application/src/main/java/javasabr/mqtt/broker/application/MqttBrokerApplication.java b/application/src/main/java/javasabr/mqtt/broker/application/MqttBrokerApplication.java index f5500602..7d9b9ec8 100644 --- a/application/src/main/java/javasabr/mqtt/broker/application/MqttBrokerApplication.java +++ b/application/src/main/java/javasabr/mqtt/broker/application/MqttBrokerApplication.java @@ -1,13 +1,17 @@ package javasabr.mqtt.broker.application; import javasabr.mqtt.broker.application.config.MqttBrokerSpringConfig; +import javasabr.mqtt.broker.application.config.NativeConfigurationHints; import lombok.RequiredArgsConstructor; +import org.springframework.aot.hint.annotation.RegisterReflectionForBinding; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportRuntimeHints; @Import({ MqttBrokerSpringConfig.class }) +@ImportRuntimeHints(NativeConfigurationHints.class) @RequiredArgsConstructor public class MqttBrokerApplication { static void main(String[] args) { diff --git a/application/src/main/java/javasabr/mqtt/broker/application/config/MqttBrokerSpringConfig.java b/application/src/main/java/javasabr/mqtt/broker/application/config/MqttBrokerSpringConfig.java index 9830d9e1..456d3093 100644 --- a/application/src/main/java/javasabr/mqtt/broker/application/config/MqttBrokerSpringConfig.java +++ b/application/src/main/java/javasabr/mqtt/broker/application/config/MqttBrokerSpringConfig.java @@ -59,6 +59,7 @@ import javasabr.mqtt.service.session.MqttSessionService; import javasabr.mqtt.service.session.impl.InMemoryMqttSessionService; import lombok.CustomLog; +import org.springframework.aot.hint.annotation.RegisterReflectionForBinding; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -129,6 +130,7 @@ PublishDataStorage publishDataStorage() { } @Bean + @RegisterReflectionForBinding(java.util.UUID[].class) IncomingPublishStorage incomingPublishStorage( PublishDataStorage publishDataStorage, @Value("${in.memory.incoming.publish.storage.clean.interval.ms:60000}") int cleanInterval) { diff --git a/application/src/main/java/javasabr/mqtt/broker/application/config/MqttExternalPlainNetworkConfig.java b/application/src/main/java/javasabr/mqtt/broker/application/config/MqttExternalPlainNetworkConfig.java index cf6a36a7..34b11a1b 100644 --- a/application/src/main/java/javasabr/mqtt/broker/application/config/MqttExternalPlainNetworkConfig.java +++ b/application/src/main/java/javasabr/mqtt/broker/application/config/MqttExternalPlainNetworkConfig.java @@ -12,6 +12,7 @@ import javasabr.rlib.network.ServerNetworkConfig; import javasabr.rlib.network.server.ServerNetwork; import lombok.CustomLog; +import org.springframework.aot.hint.annotation.RegisterReflectionForBinding; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.event.ApplicationStartedEvent; @@ -62,6 +63,11 @@ InetSocketAddress externalPlainNetworkAddress( } @Bean + @RegisterReflectionForBinding({ + java.util.function.Consumer[].class, + java.util.function.BiConsumer[].class, + reactor.core.publisher.FluxSink[].class + }) ServerNetwork externalPlainNetwork( ServerNetworkConfig externalPlainNetworkConfig, MqttConnectionFactory externalPlainConnectionFactory) { diff --git a/application/src/main/java/javasabr/mqtt/broker/application/config/NativeConfigurationHints.java b/application/src/main/java/javasabr/mqtt/broker/application/config/NativeConfigurationHints.java new file mode 100644 index 00000000..aa012dae --- /dev/null +++ b/application/src/main/java/javasabr/mqtt/broker/application/config/NativeConfigurationHints.java @@ -0,0 +1,66 @@ +package javasabr.mqtt.broker.application.config; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.AssignableTypeFilter; + +public class NativeConfigurationHints implements RuntimeHintsRegistrar { + + private static final String[] REFLECTION_PACKAGES = { + "javasabr.mqtt", + }; + + private static final String[] ARRAY_PACKAGES = { + "javasabr.mqtt", + "javasabr.rlib", + }; + + private static final String[] JDK_ARRAY_TYPES = { +// "java.util.function.Consumer[]", +// "java.util.function.BiConsumer[]", +// "java.nio.ByteBuffer[]", +// "reactor.core.publisher.FluxSink[]", +// "java.lang.String[]", +// "java.util.UUID[]", + }; + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + var scanner = new ClassPathScanningCandidateComponentProvider(false); + scanner.addIncludeFilter(new AssignableTypeFilter(Object.class)); + + for (String pkg : REFLECTION_PACKAGES) { + for (BeanDefinition candidate : scanner.findCandidateComponents(pkg)) { + hints + .reflection() + .registerType( + TypeReference.of(candidate.getBeanClassName()), + MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, + MemberCategory.INVOKE_PUBLIC_METHODS, + MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.ACCESS_DECLARED_FIELDS); + } + } + + var arrayScanner = new ClassPathScanningCandidateComponentProvider(false); + arrayScanner.addIncludeFilter(new AssignableTypeFilter(Object.class)); + + for (String pkg : ARRAY_PACKAGES) { + for (var candidate : arrayScanner.findCandidateComponents(pkg)) { + hints + .reflection() + .registerType(TypeReference.of(candidate.getBeanClassName() + "[]")); + } + } + + for (String arrayType : JDK_ARRAY_TYPES) { + hints + .reflection() + .registerType(TypeReference.of(arrayType)); + } + } +} diff --git a/application/src/main/resources/META-INF/native-image/reachability-metadata.json b/application/src/main/resources/META-INF/native-image/reachability-metadata.json new file mode 100644 index 00000000..ee8643c1 --- /dev/null +++ b/application/src/main/resources/META-INF/native-image/reachability-metadata.json @@ -0,0 +1,4632 @@ +{ + "reflection": [ + { + "type": "boolean[]" + }, + { + "type": "byte[]" + }, + { + "type": "ch.qos.logback.classic.LoggerContext" + }, + { + "type": "com.fasterxml.jackson.annotation.JacksonAnnotation" + }, + { + "type": "com.fasterxml.jackson.annotation.JsonValue" + }, + { + "type": "com.fasterxml.jackson.core.JsonParser" + }, + { + "type": "com.fasterxml.jackson.databind.JsonNode" + }, + { + "type": "com.fasterxml.jackson.databind.ObjectMapper" + }, + { + "type": "com.fasterxml.jackson.databind.ext.Java7SupportImpl", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.fasterxml.jackson.dataformat.yaml.YAMLFactory" + }, + { + "type": "com.sun.crypto.provider.AESCipher$General", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.AESKeyGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.ARCFOURCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.DESCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.DESedeCipher", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.DHParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.GaloisCounterMode$AESGCM", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA384", + "methods": [ + { + "name": "", + "parameterTypes": [ + "javax.crypto.KDFParameters" + ] + } + ] + }, + { + "type": "com.sun.crypto.provider.HmacCore$HmacSHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.HmacCore$HmacSHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBES2Parameters$General", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBKDF2Core$HmacSHA1", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBKDF2Core$HmacSHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBKDF2Core$HmacSHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBKDF2Core$HmacSHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.PBKDF2Core$HmacSHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "groovy.lang.MetaClass" + }, + { + "type": "io.micrometer.context.ContextRegistry" + }, + { + "type": "io.netty.buffer.AbstractByteBufAllocator" + }, + { + "type": "io.netty.util.internal.CleanerJava25$CleanableDirectBufferImpl", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.AutoCloseable", + "java.nio.ByteBuffer", + "long" + ] + } + ] + }, + { + "type": "io.r2dbc.pool.PoolingConnectionFactoryProvider" + }, + { + "type": "io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider" + }, + { + "type": "io.r2dbc.postgresql.codec.BuiltinDynamicCodecs" + }, + { + "type": "jakarta.annotation.PostConstruct" + }, + { + "type": "jakarta.annotation.PreDestroy" + }, + { + "type": "jakarta.annotation.Resource" + }, + { + "type": "jakarta.ejb.EJB" + }, + { + "type": "jakarta.inject.Inject" + }, + { + "type": "jakarta.inject.Named" + }, + { + "type": "jakarta.inject.Provider" + }, + { + "type": "jakarta.inject.Qualifier" + }, + { + "type": "jakarta.persistence.EntityManagerFactory" + }, + { + "type": "jakarta.servlet.Servlet" + }, + { + "type": "java.io.Closeable" + }, + { + "type": "java.io.Console", + "methods": [ + { + "name": "isTerminal", + "parameterTypes": [] + } + ] + }, + { + "type": "java.io.Serializable" + }, + { + "type": "java.lang.AutoCloseable" + }, + { + "type": "java.lang.Boolean", + "jniAccessible": true, + "methods": [ + { + "name": "getBoolean", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "type": "java.lang.Class", + "methods": [ + { + "name": "getModule", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.ClassLoader", + "fields": [ + { + "name": "classLoaderValueMap" + } + ] + }, + { + "type": "java.lang.Class[]" + }, + { + "type": "java.lang.Comparable" + }, + { + "type": "java.lang.Iterable" + }, + { + "type": "java.lang.Module", + "methods": [ + { + "name": "isNativeAccessEnabled", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.Object" + }, + { + "type": "java.lang.Object[]" + }, + { + "type": "java.lang.Record" + }, + { + "type": "java.lang.SecurityManager", + "methods": [ + { + "name": "checkPermission", + "parameterTypes": [ + "java.security.Permission" + ] + } + ] + }, + { + "type": "java.lang.String" + }, + { + "type": "java.lang.String[]" + }, + { + "type": "java.lang.System", + "methods": [ + { + "name": "getSecurityManager", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.Thread", + "methods": [ + { + "name": "isVirtual", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.annotation.Documented" + }, + { + "type": "java.lang.annotation.Repeatable" + }, + { + "type": "java.lang.annotation.Retention" + }, + { + "type": "java.lang.annotation.Target" + }, + { + "type": "java.lang.foreign.Arena", + "methods": [ + { + "name": "allocate", + "parameterTypes": [ + "long" + ] + }, + { + "name": "ofShared", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.foreign.MemorySegment", + "methods": [ + { + "name": "address", + "parameterTypes": [] + }, + { + "name": "asByteBuffer", + "parameterTypes": [] + }, + { + "name": "ofBuffer", + "parameterTypes": [ + "java.nio.Buffer" + ] + } + ] + }, + { + "type": "java.lang.invoke.MethodHandles", + "methods": [ + { + "name": "byteArrayViewVarHandle", + "parameterTypes": [ + "java.lang.Class", + "java.nio.ByteOrder" + ] + }, + { + "name": "byteBufferViewVarHandle", + "parameterTypes": [ + "java.lang.Class", + "java.nio.ByteOrder" + ] + }, + { + "name": "privateLookupIn", + "parameterTypes": [ + "java.lang.Class", + "java.lang.invoke.MethodHandles$Lookup" + ] + } + ] + }, + { + "type": "java.lang.invoke.MethodHandles$Lookup", + "methods": [ + { + "name": "findVarHandle", + "parameterTypes": [ + "java.lang.Class", + "java.lang.String", + "java.lang.Class" + ] + } + ] + }, + { + "type": "java.lang.management.ManagementFactory", + "methods": [ + { + "name": "getRuntimeMXBean", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.management.RuntimeMXBean", + "methods": [ + { + "name": "getInputArguments", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.reflect.ParameterizedType", + "methods": [ + { + "name": "getActualTypeArguments", + "parameterTypes": [] + }, + { + "name": "getRawType", + "parameterTypes": [] + } + ] + }, + { + "type": "java.lang.reflect.WildcardType", + "methods": [ + { + "name": "getUpperBounds", + "parameterTypes": [] + } + ] + }, + { + "type": "java.net.InetSocketAddress" + }, + { + "type": "java.net.URI", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "type": "java.nio.ByteBuffer", + "methods": [ + { + "name": "alignedSlice", + "parameterTypes": [ + "int" + ] + }, + { + "name": "put", + "parameterTypes": [ + "int", + "java.nio.ByteBuffer", + "int", + "int" + ] + }, + { + "name": "put", + "parameterTypes": [ + "int", + "byte[]", + "int", + "int" + ] + }, + { + "name": "slice", + "parameterTypes": [ + "int", + "int" + ] + } + ] + }, + { + "type": "java.security.AccessController", + "methods": [ + { + "name": "doPrivileged", + "parameterTypes": [ + "java.security.PrivilegedExceptionAction" + ] + } + ] + }, + { + "type": "java.security.AlgorithmParametersSpi" + }, + { + "type": "java.security.KeyStoreSpi" + }, + { + "type": "java.security.interfaces.RSAPrivateKey" + }, + { + "type": "java.security.interfaces.RSAPublicKey" + }, + { + "type": "java.sql.Date" + }, + { + "type": "java.sql.Time" + }, + { + "type": "java.util.AbstractCollection" + }, + { + "type": "java.util.AbstractMap" + }, + { + "type": "java.util.Collection" + }, + { + "type": "java.util.EnumMap$Values" + }, + { + "type": "java.util.EventListener" + }, + { + "type": "java.util.ImmutableCollections$AbstractImmutableMap" + }, + { + "type": "java.util.ImmutableCollections$MapN" + }, + { + "type": "java.util.Map" + }, + { + "type": "java.util.UUID[]" + }, + { + "type": "java.util.function.BiConsumer[]" + }, + { + "type": "java.util.function.Consumer[]" + }, + { + "type": "java.util.logging.LogManager" + }, + { + "type": "javasabr.mqtt.acl.engine.model.condition.MqttUserCondition[]" + }, + { + "type": "javasabr.mqtt.acl.engine.model.matcher.AnyTopicMatcher[]" + }, + { + "type": "javasabr.mqtt.acl.engine.model.matcher.TopicMatcher[]" + }, + { + "type": "javasabr.mqtt.acl.engine.model.rule.AclRule[]" + }, + { + "type": "javasabr.mqtt.acl.java.dsl.AclRulesLoader" + }, + { + "type": "javasabr.mqtt.acl.service.AclEngineBasedAuthorizationService" + }, + { + "type": "javasabr.mqtt.acl.service.conifg.AntlrDslBasedAclServiceSpringConfig", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "authorizationService", + "parameterTypes": [ + "java.net.URI" + ] + } + ] + }, + { + "type": "javasabr.mqtt.acl.service.impl.UriLoaderAuthorizationService" + }, + { + "type": "javasabr.mqtt.auth.api.AuthenticationMethod" + }, + { + "type": "javasabr.mqtt.auth.api.AuthenticationProvider" + }, + { + "type": "javasabr.mqtt.auth.api.AuthenticationProvider[]" + }, + { + "type": "javasabr.mqtt.auth.api.AuthenticationService" + }, + { + "type": "javasabr.mqtt.auth.api.CredentialsSource" + }, + { + "type": "javasabr.mqtt.auth.api.CredentialsSourceType" + }, + { + "type": "javasabr.mqtt.auth.api.CredentialsSource[]" + }, + { + "type": "javasabr.mqtt.auth.api.database.DatabaseConnectionProperties" + }, + { + "type": "javasabr.mqtt.auth.api.database.DatabaseCredentials" + }, + { + "type": "javasabr.mqtt.auth.api.database.DatabasePoolProperties" + }, + { + "type": "javasabr.mqtt.auth.api.database.DatabaseTimeoutProperties" + }, + { + "type": "javasabr.mqtt.auth.api.file.FileProperties" + }, + { + "type": "javasabr.mqtt.auth.credentials.source.DatabaseCredentialsSource", + "methods": [ + { + "name": "jsonDebugValue", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.mqtt.auth.credentials.source.FileCredentialsSource", + "methods": [ + { + "name": "jsonDebugValue", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.mqtt.auth.credentials.source.InMemoryCredentialsSource" + }, + { + "type": "javasabr.mqtt.auth.provider.BasicAuthenticationProvider", + "methods": [ + { + "name": "jsonDebugValue", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.mqtt.auth.service.DefaultAuthenticationService" + }, + { + "type": "javasabr.mqtt.auth.service.config.AuthenticationServiceSpringConfig", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "authenticationService", + "parameterTypes": [ + "java.util.List", + "boolean" + ] + }, + { + "name": "basicAuthenticationProvider", + "parameterTypes": [ + "java.util.List" + ] + } + ] + }, + { + "type": "javasabr.mqtt.auth.service.config.DatabaseCredentialsSourceSpringConfig", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "adminDatabaseCredentials", + "parameterTypes": [] + }, + { + "name": "credentialsSourceDatabaseConnectionProperties", + "parameterTypes": [ + "java.lang.String", + "java.lang.String", + "int", + "java.lang.String" + ] + }, + { + "name": "credentialsSourceDatabasePoolProperties", + "parameterTypes": [ + "int", + "int", + "int" + ] + }, + { + "name": "credentialsSourceDatabaseTimeoutsProperties", + "parameterTypes": [ + "int", + "int" + ] + }, + { + "name": "credentialsSourceFlyway", + "parameterTypes": [ + "javasabr.mqtt.auth.api.database.DatabaseConnectionProperties", + "javasabr.mqtt.auth.api.database.DatabaseCredentials", + "java.lang.String" + ] + }, + { + "name": "databaseCredentialsSource", + "parameterTypes": [ + "javasabr.mqtt.auth.api.database.DatabasePoolProperties", + "javasabr.mqtt.auth.api.database.DatabaseTimeoutProperties", + "javasabr.mqtt.auth.api.database.DatabaseConnectionProperties", + "javasabr.mqtt.auth.api.database.DatabaseCredentials" + ] + }, + { + "name": "readerDatabaseCredentials", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.mqtt.auth.service.config.FileCredentialsSourceSpringConfig", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "fileCredentialsSource", + "parameterTypes": [ + "javasabr.mqtt.auth.api.file.FileProperties" + ] + }, + { + "name": "fileCredentialsSourceProperties", + "parameterTypes": [ + "java.net.URI" + ] + } + ] + }, + { + "type": "javasabr.mqtt.base.util.DebugUtils$DebugFieldsFilterMixIn" + }, + { + "type": "javasabr.mqtt.broker.application.MqttBrokerApplication", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "main", + "parameterTypes": [ + "java.lang.String[]" + ] + } + ] + }, + { + "type": "javasabr.mqtt.broker.application.config.MqttBrokerSpringConfig", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "clientIdRegistry", + "parameterTypes": [ + "org.springframework.core.env.Environment" + ] + }, + { + "name": "connectInMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.ClientIdRegistry", + "javasabr.mqtt.auth.api.AuthenticationService", + "javasabr.mqtt.service.session.MqttSessionService", + "javasabr.mqtt.service.SubscriptionService", + "javasabr.mqtt.service.MessageOutFactoryService" + ] + }, + { + "name": "disconnectMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService" + ] + }, + { + "name": "externalClientFactory", + "parameterTypes": [ + "javasabr.mqtt.network.handler.NetworkMqttUserReleaseHandler" + ] + }, + { + "name": "externalConnectionConfig", + "parameterTypes": [ + "org.springframework.core.env.Environment" + ] + }, + { + "name": "externalMqttClientReleaseHandler", + "parameterTypes": [ + "javasabr.mqtt.service.ClientIdRegistry", + "javasabr.mqtt.service.session.MqttSessionService", + "javasabr.mqtt.service.SubscriptionService" + ] + }, + { + "name": "externalMqttConnectionService", + "parameterTypes": [ + "java.util.Collection" + ] + }, + { + "name": "incomingPublishRouter", + "parameterTypes": [ + "java.util.Collection" + ] + }, + { + "name": "incomingPublishStorage", + "parameterTypes": [ + "javasabr.mqtt.service.publish.PublishDataStorage", + "int" + ] + }, + { + "name": "mqtt311MessageOutFactory", + "parameterTypes": [] + }, + { + "name": "mqtt5MessageOutFactory", + "parameterTypes": [] + }, + { + "name": "mqttMessageOutFactoryService", + "parameterTypes": [ + "java.util.Collection" + ] + }, + { + "name": "mqttPacketCodec", + "parameterTypes": [] + }, + { + "name": "mqttSessionService", + "parameterTypes": [ + "int", + "int", + "int", + "int", + "int", + "int" + ] + }, + { + "name": "publishAckMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService" + ] + }, + { + "name": "publishCompleteMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService" + ] + }, + { + "name": "publishDataStorage", + "parameterTypes": [] + }, + { + "name": "publishDispatcher", + "parameterTypes": [ + "java.util.Collection" + ] + }, + { + "name": "publishMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.publish.IncomingPublishRouter", + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.TopicService", + "javasabr.mqtt.service.AuthorizationService", + "javasabr.mqtt.service.publish.PublishDataStorage", + "javasabr.mqtt.service.publish.IncomingPublishStorage" + ] + }, + { + "name": "publishReceiveMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService" + ] + }, + { + "name": "publishReleaseMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService" + ] + }, + { + "name": "qos0IncomingPublishProcessor", + "parameterTypes": [ + "javasabr.mqtt.service.SubscriptionService", + "javasabr.mqtt.service.publish.PublishDispatcher", + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.publish.RetainPublishService", + "javasabr.mqtt.service.publish.IncomingPublishStorage" + ] + }, + { + "name": "qos0SubscriberPublishSender", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.publish.IncomingPublishStorage" + ] + }, + { + "name": "qos1IncomingPublishProcessor", + "parameterTypes": [ + "javasabr.mqtt.service.SubscriptionService", + "javasabr.mqtt.service.publish.PublishDispatcher", + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.publish.RetainPublishService", + "javasabr.mqtt.service.publish.IncomingPublishStorage" + ] + }, + { + "name": "qos1SubscriberPublishSender", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.publish.IncomingPublishStorage" + ] + }, + { + "name": "qos2IncomingPublishProcessor", + "parameterTypes": [ + "javasabr.mqtt.service.SubscriptionService", + "javasabr.mqtt.service.publish.PublishDispatcher", + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.publish.RetainPublishService", + "javasabr.mqtt.service.publish.IncomingPublishStorage" + ] + }, + { + "name": "qos2SubscriberPublishSender", + "parameterTypes": [ + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.publish.IncomingPublishStorage" + ] + }, + { + "name": "retainMessageService", + "parameterTypes": [] + }, + { + "name": "subscribeMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.SubscriptionService", + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.TopicService", + "javasabr.mqtt.service.publish.RetainPublishService", + "javasabr.mqtt.service.publish.PublishDispatcher" + ] + }, + { + "name": "subscriptionService", + "parameterTypes": [ + "javasabr.mqtt.service.AuthorizationService" + ] + }, + { + "name": "topicService", + "parameterTypes": [] + }, + { + "name": "unsubscribeMqttInMessageHandler", + "parameterTypes": [ + "javasabr.mqtt.service.SubscriptionService", + "javasabr.mqtt.service.MessageOutFactoryService", + "javasabr.mqtt.service.TopicService" + ] + } + ] + }, + { + "type": "javasabr.mqtt.broker.application.config.MqttExternalPlainNetworkConfig", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "externalPlainConnectionFactory", + "parameterTypes": [ + "javasabr.mqtt.model.MqttServerConnectionConfig", + "javasabr.mqtt.network.user.NetworkMqttUserFactory", + "int", + "javasabr.mqtt.network.message.MqttPacketCodec" + ] + }, + { + "name": "externalPlainNetwork", + "parameterTypes": [ + "javasabr.rlib.network.ServerNetworkConfig", + "javasabr.mqtt.network.MqttConnectionFactory" + ] + }, + { + "name": "externalPlainNetworkAddress", + "parameterTypes": [ + "java.lang.String", + "int" + ] + }, + { + "name": "externalPlainNetworkConfig", + "parameterTypes": [ + "int", + "int", + "int", + "java.lang.String", + "int" + ] + }, + { + "name": "externalPlainNetworkStarter", + "parameterTypes": [ + "javasabr.rlib.network.server.ServerNetwork", + "javasabr.mqtt.service.ConnectionService", + "java.net.InetSocketAddress" + ] + } + ] + }, + { + "type": "javasabr.mqtt.broker.application.config.MqttExternalTlsNetworkConfig", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "externalNetworkSslContext", + "parameterTypes": [ + "javasabr.mqtt.network.TlsProperties" + ] + }, + { + "name": "externalTlsConnectionFactory", + "parameterTypes": [ + "javasabr.mqtt.model.MqttServerConnectionConfig", + "javasabr.mqtt.network.user.NetworkMqttUserFactory", + "int", + "javax.net.ssl.SSLContext", + "javasabr.mqtt.network.TlsProperties", + "javasabr.rlib.network.ServerNetworkConfig", + "javasabr.mqtt.network.message.MqttPacketCodec" + ] + }, + { + "name": "externalTlsNetwork", + "parameterTypes": [ + "javasabr.rlib.network.ServerNetworkConfig", + "javasabr.mqtt.network.MqttConnectionFactory" + ] + }, + { + "name": "externalTlsNetworkAddress", + "parameterTypes": [ + "java.lang.String", + "int" + ] + }, + { + "name": "externalTlsNetworkConfig", + "parameterTypes": [ + "int", + "int", + "int", + "java.lang.String", + "int" + ] + }, + { + "name": "externalTlsNetworkStarter", + "parameterTypes": [ + "javasabr.rlib.network.server.ServerNetwork", + "javasabr.mqtt.service.ConnectionService", + "java.net.InetSocketAddress" + ] + }, + { + "name": "externalTlsProperties", + "parameterTypes": [ + "java.lang.String", + "java.lang.String", + "java.lang.String", + "java.lang.String", + "java.lang.String", + "java.lang.String", + "boolean", + "java.util.List", + "java.util.List" + ] + } + ] + }, + { + "type": "javasabr.mqtt.model.MqttMessageProperty[]" + }, + { + "type": "javasabr.mqtt.model.MqttServerConnectionConfig" + }, + { + "type": "javasabr.mqtt.model.MqttVersion" + }, + { + "type": "javasabr.mqtt.model.PayloadFormat" + }, + { + "type": "javasabr.mqtt.model.QoS" + }, + { + "type": "javasabr.mqtt.model.QoS[]" + }, + { + "type": "javasabr.mqtt.model.SubscribeRetainHandling" + }, + { + "type": "javasabr.mqtt.model.data.type.StringPair[]" + }, + { + "type": "javasabr.mqtt.model.message.MqttMessage" + }, + { + "type": "javasabr.mqtt.model.message.MqttMessageType[]" + }, + { + "type": "javasabr.mqtt.model.message.ReceivableMqttMessage" + }, + { + "type": "javasabr.mqtt.model.message.SendableMqttMessage" + }, + { + "type": "javasabr.mqtt.model.message.TrackableMqttMessage" + }, + { + "type": "javasabr.mqtt.model.publish.IncomingPublish" + }, + { + "type": "javasabr.mqtt.model.publish.IncomingPublish[]" + }, + { + "type": "javasabr.mqtt.model.publish.Publish" + }, + { + "type": "javasabr.mqtt.model.publish.PublishData" + }, + { + "type": "javasabr.mqtt.model.publish.SimpleIncomingPublish", + "methods": [ + { + "name": "jsonDebugValue", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.mqtt.model.publish.impl.InMemoryPublishData", + "methods": [ + { + "name": "jsonDebugValue", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.mqtt.model.reason.code.ConnectAckReasonCode" + }, + { + "type": "javasabr.mqtt.model.reason.code.ConnectAckReasonCode[]" + }, + { + "type": "javasabr.mqtt.model.reason.code.DisconnectReasonCode" + }, + { + "type": "javasabr.mqtt.model.reason.code.DisconnectReasonCode[]" + }, + { + "type": "javasabr.mqtt.model.reason.code.PublishAckReasonCode" + }, + { + "type": "javasabr.mqtt.model.reason.code.PublishAckReasonCode[]" + }, + { + "type": "javasabr.mqtt.model.reason.code.PublishCompletedReasonCode[]" + }, + { + "type": "javasabr.mqtt.model.reason.code.PublishReceivedReasonCode[]" + }, + { + "type": "javasabr.mqtt.model.reason.code.PublishReleaseReasonCode" + }, + { + "type": "javasabr.mqtt.model.reason.code.PublishReleaseReasonCode[]" + }, + { + "type": "javasabr.mqtt.model.reason.code.ReasonCode" + }, + { + "type": "javasabr.mqtt.model.reason.code.SubscribeAckReasonCode" + }, + { + "type": "javasabr.mqtt.model.reason.code.SubscribeAckReasonCode[]" + }, + { + "type": "javasabr.mqtt.model.subscriber.SingleSubscriber[]" + }, + { + "type": "javasabr.mqtt.model.subscriber.Subscriber[]" + }, + { + "type": "javasabr.mqtt.model.subscription.RequestedSubscription", + "fields": [ + { + "name": "noLocal" + }, + { + "name": "qos" + }, + { + "name": "rawTopicFilter" + }, + { + "name": "retainAsPublished" + }, + { + "name": "retainHandling" + } + ] + }, + { + "type": "javasabr.mqtt.model.subscription.RequestedSubscription[]" + }, + { + "type": "javasabr.mqtt.model.subscription.SubscriptionResult[]" + }, + { + "type": "javasabr.mqtt.model.subscription.Subscription[]" + }, + { + "type": "javasabr.mqtt.model.topic.AbstractTopic", + "methods": [ + { + "name": "jsonDebugValue", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.mqtt.model.topic.TopicName" + }, + { + "type": "javasabr.mqtt.network.MqttConnectionFactory" + }, + { + "type": "javasabr.mqtt.network.TlsProperties" + }, + { + "type": "javasabr.mqtt.network.handler.NetworkMqttUserReleaseHandler" + }, + { + "type": "javasabr.mqtt.network.message.MqttPacketCodec" + }, + { + "type": "javasabr.mqtt.network.message.in.ConnectMqttInMessage", + "fields": [ + { + "name": "cleanStart" + }, + { + "name": "clientId" + }, + { + "name": "keepAlive" + }, + { + "name": "mqttVersion" + }, + { + "name": "sessionExpiryInterval" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.in.DisconnectMqttInMessage", + "fields": [ + { + "name": "reasonCode" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.in.MqttInMessage", + "fields": [ + { + "name": "userProperties" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.in.PublishAckMqttInMessage" + }, + { + "type": "javasabr.mqtt.network.message.in.PublishControlMqttInMessage", + "fields": [ + { + "name": "reasonCode" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.in.PublishMqttInMessage", + "fields": [ + { + "name": "duplicate" + }, + { + "name": "messageExpiryInterval" + }, + { + "name": "payloadFormat" + }, + { + "name": "qos" + }, + { + "name": "rawTopicName" + }, + { + "name": "topicAlias" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.in.PublishReleaseMqttInMessage" + }, + { + "type": "javasabr.mqtt.network.message.in.SubscribeMqttInMessage", + "fields": [ + { + "name": "subscriptions" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.in.TrackableMqttInMessage", + "fields": [ + { + "name": "messageId" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.out.ConnectAckMqtt311OutMessage", + "fields": [ + { + "name": "reasonCode" + }, + { + "name": "sessionPresent" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.out.MqttOutMessage" + }, + { + "type": "javasabr.mqtt.network.message.out.PublishAckMqtt311OutMessage" + }, + { + "type": "javasabr.mqtt.network.message.out.PublishCompleteMqtt311OutMessage" + }, + { + "type": "javasabr.mqtt.network.message.out.PublishMqtt311OutMessage", + "fields": [ + { + "name": "duplicate" + }, + { + "name": "qos" + }, + { + "name": "topicName" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.out.PublishReceivedMqtt311OutMessage" + }, + { + "type": "javasabr.mqtt.network.message.out.SubscribeAckMqtt311OutMessage", + "fields": [ + { + "name": "reasonCodes" + } + ] + }, + { + "type": "javasabr.mqtt.network.message.out.TrackableMqttOutMessage", + "fields": [ + { + "name": "messageId" + } + ] + }, + { + "type": "javasabr.mqtt.network.user.NetworkMqttUserFactory" + }, + { + "type": "javasabr.mqtt.service.AuthorizationService" + }, + { + "type": "javasabr.mqtt.service.ClientIdRegistry" + }, + { + "type": "javasabr.mqtt.service.ConnectionService" + }, + { + "type": "javasabr.mqtt.service.MessageOutFactoryService" + }, + { + "type": "javasabr.mqtt.service.SubscriptionService" + }, + { + "type": "javasabr.mqtt.service.TopicService" + }, + { + "type": "javasabr.mqtt.service.handler.client.AbstractNetworkMqttUserReleaseHandler" + }, + { + "type": "javasabr.mqtt.service.handler.client.ExternalNetworkMqttUserReleaseHandler" + }, + { + "type": "javasabr.mqtt.service.impl.DefaultConnectionService" + }, + { + "type": "javasabr.mqtt.service.impl.DefaultMessageOutFactoryService" + }, + { + "type": "javasabr.mqtt.service.impl.DefaultTopicService" + }, + { + "type": "javasabr.mqtt.service.impl.ExternalNetworkMqttUserFactory" + }, + { + "type": "javasabr.mqtt.service.impl.InMemoryClientIdRegistry" + }, + { + "type": "javasabr.mqtt.service.impl.InMemorySubscriptionService" + }, + { + "type": "javasabr.mqtt.service.impl.PlainMqttConnectionFactory" + }, + { + "type": "javasabr.mqtt.service.impl.TlsMqttConnectionFactory" + }, + { + "type": "javasabr.mqtt.service.message.handler.MqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.AbstractMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.ConnectInMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.DisconnectMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.FieldsValidatedMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.ProcessingOutPublishesMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.PublishAckMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.PublishCompleteMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.PublishMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.PublishReceiveMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.PublishReleaseMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.SubscribeMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.handler.impl.UnsubscribeMqttInMessageHandler" + }, + { + "type": "javasabr.mqtt.service.message.out.factory.Mqtt311MessageOutFactory" + }, + { + "type": "javasabr.mqtt.service.message.out.factory.Mqtt5MessageOutFactory" + }, + { + "type": "javasabr.mqtt.service.message.out.factory.MqttMessageOutFactory" + }, + { + "type": "javasabr.mqtt.service.publish.IncomingPublishRouter" + }, + { + "type": "javasabr.mqtt.service.publish.IncomingPublishStorage" + }, + { + "type": "javasabr.mqtt.service.publish.PublishDataStorage" + }, + { + "type": "javasabr.mqtt.service.publish.PublishDispatcher" + }, + { + "type": "javasabr.mqtt.service.publish.RetainPublishService" + }, + { + "type": "javasabr.mqtt.service.publish.impl.DefaultIncomingPublishRouter" + }, + { + "type": "javasabr.mqtt.service.publish.impl.DefaultPublishDispatcher" + }, + { + "type": "javasabr.mqtt.service.publish.impl.InMemoryIncomingPublishStorage" + }, + { + "type": "javasabr.mqtt.service.publish.impl.InMemoryPublishDataStorage" + }, + { + "type": "javasabr.mqtt.service.publish.impl.InMemoryRetainPublishService" + }, + { + "type": "javasabr.mqtt.service.publish.processor.AbstractIncomingPublishProcessor" + }, + { + "type": "javasabr.mqtt.service.publish.processor.IncomingPublishProcessor" + }, + { + "type": "javasabr.mqtt.service.publish.processor.Qos0IncomingPublishProcessor" + }, + { + "type": "javasabr.mqtt.service.publish.processor.Qos1IncomingPublishProcessor" + }, + { + "type": "javasabr.mqtt.service.publish.processor.Qos2IncomingPublishProcessor" + }, + { + "type": "javasabr.mqtt.service.publish.processor.TrackableIncomingPublishProcessor" + }, + { + "type": "javasabr.mqtt.service.publish.sender.AbstractSubscriberPublishSender" + }, + { + "type": "javasabr.mqtt.service.publish.sender.Qos0SubscriberPublishSender" + }, + { + "type": "javasabr.mqtt.service.publish.sender.Qos1SubscriberPublishSender" + }, + { + "type": "javasabr.mqtt.service.publish.sender.Qos2SubscriberPublishSender" + }, + { + "type": "javasabr.mqtt.service.publish.sender.SubscriberPublishSender" + }, + { + "type": "javasabr.mqtt.service.publish.sender.TrackableSubscriberPublishSender" + }, + { + "type": "javasabr.mqtt.service.session.MqttSessionService" + }, + { + "type": "javasabr.mqtt.service.session.impl.ExpirableSession[]" + }, + { + "type": "javasabr.mqtt.service.session.impl.InMemoryMqttSessionService" + }, + { + "type": "javasabr.mqtt.service.session.impl.InMemoryNetworkMqttSession[]" + }, + { + "type": "javasabr.mqtt.service.session.impl.NotExpirableSession[]" + }, + { + "type": "javasabr.rlib.common.AliasedEnum" + }, + { + "type": "javasabr.rlib.common.util.NumberedEnum" + }, + { + "type": "javasabr.rlib.logger.slf4j.Slf4jLoggerFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "javasabr.rlib.network.Network" + }, + { + "type": "javasabr.rlib.network.NetworkConfig" + }, + { + "type": "javasabr.rlib.network.ServerNetworkConfig" + }, + { + "type": "javasabr.rlib.network.ServerNetworkConfig$SimpleServerNetworkConfig" + }, + { + "type": "javasabr.rlib.network.impl.AbstractNetwork" + }, + { + "type": "javasabr.rlib.network.packet.NetworkPacket" + }, + { + "type": "javasabr.rlib.network.packet.ReadableNetworkPacket" + }, + { + "type": "javasabr.rlib.network.packet.WritableNetworkPacket" + }, + { + "type": "javasabr.rlib.network.packet.WritableNetworkPacket[]" + }, + { + "type": "javasabr.rlib.network.packet.impl.AbstractNetworkPacket" + }, + { + "type": "javasabr.rlib.network.packet.impl.AbstractReadableNetworkPacket" + }, + { + "type": "javasabr.rlib.network.packet.impl.AbstractWritableNetworkPacket" + }, + { + "type": "javasabr.rlib.network.server.ServerNetwork" + }, + { + "type": "javasabr.rlib.network.server.impl.DefaultServerNetwork", + "methods": [ + { + "name": "shutdown", + "parameterTypes": [] + } + ] + }, + { + "type": "javax.money.MonetaryAmount" + }, + { + "type": "javax.naming.InitialContext" + }, + { + "type": "javax.net.ssl.SSLContext" + }, + { + "type": "javax.servlet.Servlet" + }, + { + "type": "jdk.crac.management.CRaCMXBean" + }, + { + "type": "jdk.internal.loader.ClassLoaders$AppClassLoader" + }, + { + "type": "jdk.internal.loader.ClassLoaders$PlatformClassLoader" + }, + { + "type": "jdk.internal.misc.Unsafe" + }, + { + "type": "kotlin.Metadata" + }, + { + "type": "kotlin.reflect.full.KClasses" + }, + { + "type": "kotlinx.coroutines.reactor.MonoKt" + }, + { + "type": "org.apache.commons.logging.LogFactory" + }, + { + "type": "org.apache.commons.logging.impl.Log4jApiLogFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.commons.logging.impl.WeakHashtable", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.Appender[]" + }, + { + "type": "org.apache.logging.log4j.core.appender.AbstractAppender$Builder", + "fields": [ + { + "name": "configuration" + }, + { + "name": "ignoreExceptions" + }, + { + "name": "layout" + }, + { + "name": "name" + } + ] + }, + { + "type": "org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender$Builder", + "fields": [ + { + "name": "bufferSize" + }, + { + "name": "bufferedIo" + }, + { + "name": "immediateFlush" + } + ] + }, + { + "type": "org.apache.logging.log4j.core.appender.AppenderSet" + }, + { + "type": "org.apache.logging.log4j.core.appender.AsyncAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.ConsoleAppender", + "methods": [ + { + "name": "newBuilder", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.appender.ConsoleAppender$Builder", + "fields": [ + { + "name": "direct" + }, + { + "name": "follow" + }, + { + "name": "target" + } + ] + }, + { + "type": "org.apache.logging.log4j.core.appender.CountingNoOpAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.FailoverAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.FailoversPlugin" + }, + { + "type": "org.apache.logging.log4j.core.appender.FileAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.HttpAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.MemoryMappedFileAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.NullAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.OutputStreamAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.RandomAccessFileAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.RollingFileAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.ScriptAppenderSelector" + }, + { + "type": "org.apache.logging.log4j.core.appender.SmtpAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.SocketAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.SyslogAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.WriterAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.db.ColumnMapping" + }, + { + "type": "org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig" + }, + { + "type": "org.apache.logging.log4j.core.appender.db.jdbc.DataSourceConnectionSource" + }, + { + "type": "org.apache.logging.log4j.core.appender.db.jdbc.DriverManagerConnectionSource" + }, + { + "type": "org.apache.logging.log4j.core.appender.db.jdbc.FactoryMethodConnectionSource" + }, + { + "type": "org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.mom.JmsAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.mom.jeromq.JeroMqAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.mom.kafka.KafkaAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.nosql.NoSqlAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.rewrite.LoggerNameLevelRewritePolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rewrite.MapRewritePolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rewrite.PropertiesRewritePolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rewrite.RewriteAppender" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.CronTriggeringPolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.DirectWriteRolloverStrategy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.NoOpTriggeringPolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.OnStartupTriggeringPolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.DeleteAction" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.IfAccumulatedFileCount" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.IfAccumulatedFileSize" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.IfAll" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.IfAny" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.IfFileName" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.IfLastModified" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.IfNot" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.PathSortByModificationTime" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.PosixViewAttributeAction" + }, + { + "type": "org.apache.logging.log4j.core.appender.rolling.action.ScriptCondition" + }, + { + "type": "org.apache.logging.log4j.core.appender.routing.IdlePurgePolicy" + }, + { + "type": "org.apache.logging.log4j.core.appender.routing.Route" + }, + { + "type": "org.apache.logging.log4j.core.appender.routing.Routes" + }, + { + "type": "org.apache.logging.log4j.core.appender.routing.RoutingAppender" + }, + { + "type": "org.apache.logging.log4j.core.async.ArrayBlockingQueueFactory" + }, + { + "type": "org.apache.logging.log4j.core.async.AsyncLoggerConfig" + }, + { + "type": "org.apache.logging.log4j.core.async.AsyncLoggerConfig$RootLogger" + }, + { + "type": "org.apache.logging.log4j.core.async.AsyncWaitStrategyFactoryConfig" + }, + { + "type": "org.apache.logging.log4j.core.async.DisruptorBlockingQueueFactory" + }, + { + "type": "org.apache.logging.log4j.core.async.JCToolsBlockingQueueFactory" + }, + { + "type": "org.apache.logging.log4j.core.async.LinkedTransferQueueFactory" + }, + { + "type": "org.apache.logging.log4j.core.config.AppenderControlArraySet" + }, + { + "type": "org.apache.logging.log4j.core.config.AppenderRef", + "methods": [ + { + "name": "createAppenderRef", + "parameterTypes": [ + "java.lang.String", + "org.apache.logging.log4j.Level", + "org.apache.logging.log4j.core.Filter" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.AppenderRef[]" + }, + { + "type": "org.apache.logging.log4j.core.config.AppendersPlugin", + "methods": [ + { + "name": "createAppenders", + "parameterTypes": [ + "org.apache.logging.log4j.core.Appender[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.CustomLevelConfig" + }, + { + "type": "org.apache.logging.log4j.core.config.CustomLevels" + }, + { + "type": "org.apache.logging.log4j.core.config.DefaultAdvertiser" + }, + { + "type": "org.apache.logging.log4j.core.config.HttpWatcher" + }, + { + "type": "org.apache.logging.log4j.core.config.LoggerConfig", + "methods": [ + { + "name": "newBuilder", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.LoggerConfig$Builder", + "fields": [ + { + "name": "additivity" + }, + { + "name": "config" + }, + { + "name": "filter" + }, + { + "name": "includeLocation" + }, + { + "name": "level" + }, + { + "name": "levelAndRefs" + }, + { + "name": "loggerName" + }, + { + "name": "properties" + }, + { + "name": "refs" + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.LoggerConfig$RootLogger", + "methods": [ + { + "name": "newRootBuilder", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.LoggerConfig$RootLogger$Builder", + "fields": [ + { + "name": "additivity" + }, + { + "name": "config" + }, + { + "name": "filter" + }, + { + "name": "includeLocation" + }, + { + "name": "level" + }, + { + "name": "levelAndRefs" + }, + { + "name": "properties" + }, + { + "name": "refs" + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.LoggerConfig[]" + }, + { + "type": "org.apache.logging.log4j.core.config.LoggersPlugin", + "methods": [ + { + "name": "createLoggers", + "parameterTypes": [ + "org.apache.logging.log4j.core.config.LoggerConfig[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.MonitorResource" + }, + { + "type": "org.apache.logging.log4j.core.config.MonitorResources" + }, + { + "type": "org.apache.logging.log4j.core.config.PropertiesPlugin" + }, + { + "type": "org.apache.logging.log4j.core.config.Property" + }, + { + "type": "org.apache.logging.log4j.core.config.Property[]" + }, + { + "type": "org.apache.logging.log4j.core.config.ScriptsPlugin" + }, + { + "type": "org.apache.logging.log4j.core.config.arbiters.ClassArbiter" + }, + { + "type": "org.apache.logging.log4j.core.config.arbiters.DefaultArbiter" + }, + { + "type": "org.apache.logging.log4j.core.config.arbiters.EnvironmentArbiter" + }, + { + "type": "org.apache.logging.log4j.core.config.arbiters.ScriptArbiter" + }, + { + "type": "org.apache.logging.log4j.core.config.arbiters.SelectArbiter" + }, + { + "type": "org.apache.logging.log4j.core.config.arbiters.SystemPropertyArbiter" + }, + { + "type": "org.apache.logging.log4j.core.config.json.JsonConfigurationFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$BigDecimalConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$BigIntegerConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$BooleanConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$ByteArrayConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$ByteConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$CharArrayConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$CharacterConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$CharsetConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$ClassConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$CronExpressionConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$DoubleConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$DurationConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$FileConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$FloatConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$InetAddressConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$IntegerConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$LevelConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$LongConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$PathConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$PatternConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$SecurityProviderConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$ShortConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$StringConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$UriConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$UrlConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$UuidConverter", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.validation.validators.RequiredValidator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.visitors.PluginAttributeVisitor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.visitors.PluginBuilderAttributeVisitor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.visitors.PluginConfigurationVisitor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.plugins.visitors.PluginElementVisitor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.properties.PropertiesConfigurationFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.config.yaml.YamlConfigurationFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.filter.AbstractFilterable$Builder", + "fields": [ + { + "name": "filter" + }, + { + "name": "propertyArray" + } + ] + }, + { + "type": "org.apache.logging.log4j.core.filter.BurstFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.CompositeFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.DenyAllFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.DynamicThresholdFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.LevelMatchFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.LevelRangeFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.MapFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.MarkerFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.MutableThreadContextMapFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.NoMarkerFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.RegexFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.ScriptFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.StringMatchFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.StructuredDataFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.ThreadContextMapFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.ThresholdFilter" + }, + { + "type": "org.apache.logging.log4j.core.filter.TimeFilter" + }, + { + "type": "org.apache.logging.log4j.core.impl.Log4jContextFactory" + }, + { + "type": "org.apache.logging.log4j.core.impl.Log4jProvider" + }, + { + "type": "org.apache.logging.log4j.core.impl.ThreadContextDataProvider" + }, + { + "type": "org.apache.logging.log4j.core.layout.CsvLogEventLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.CsvParameterLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.GelfLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.HtmlLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.JsonLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.LevelPatternSelector" + }, + { + "type": "org.apache.logging.log4j.core.layout.LoggerFields" + }, + { + "type": "org.apache.logging.log4j.core.layout.MarkerPatternSelector" + }, + { + "type": "org.apache.logging.log4j.core.layout.MessageLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.PatternLayout", + "methods": [ + { + "name": "newBuilder", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.layout.PatternLayout$Builder", + "fields": [ + { + "name": "alwaysWriteExceptions" + }, + { + "name": "charset" + }, + { + "name": "configuration" + }, + { + "name": "disableAnsi" + }, + { + "name": "footer" + }, + { + "name": "header" + }, + { + "name": "noConsoleNoAnsi" + }, + { + "name": "pattern" + }, + { + "name": "patternSelector" + }, + { + "name": "regexReplacement" + } + ] + }, + { + "type": "org.apache.logging.log4j.core.layout.PatternMatch" + }, + { + "type": "org.apache.logging.log4j.core.layout.Rfc5424Layout" + }, + { + "type": "org.apache.logging.log4j.core.layout.ScriptPatternSelector" + }, + { + "type": "org.apache.logging.log4j.core.layout.SerializedLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.SyslogLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.XmlLayout" + }, + { + "type": "org.apache.logging.log4j.core.layout.YamlLayout" + }, + { + "type": "org.apache.logging.log4j.core.lookup.ContextMapLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.DateLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.EnvironmentLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.EventLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.JavaLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.JmxRuntimeInputArgumentsLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.JndiLookup" + }, + { + "type": "org.apache.logging.log4j.core.lookup.Log4jLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.LowerLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.MainMapLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.MapLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.MarkerLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.ResourceBundleLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.StructuredDataLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.SystemPropertiesLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.lookup.UpperLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.net.MulticastDnsAdvertiser" + }, + { + "type": "org.apache.logging.log4j.core.net.SocketAddress" + }, + { + "type": "org.apache.logging.log4j.core.net.SocketOptions" + }, + { + "type": "org.apache.logging.log4j.core.net.SocketPerformancePreferences" + }, + { + "type": "org.apache.logging.log4j.core.net.ssl.KeyStoreConfiguration" + }, + { + "type": "org.apache.logging.log4j.core.net.ssl.SslConfiguration" + }, + { + "type": "org.apache.logging.log4j.core.net.ssl.TrustStoreConfiguration" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$Black" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$Blue" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$Cyan" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$Green" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$Magenta" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$Red" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$White" + }, + { + "type": "org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter$Yellow" + }, + { + "type": "org.apache.logging.log4j.core.pattern.ClassNamePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.DatePatternConverter", + "methods": [ + { + "name": "newInstance", + "parameterTypes": [ + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.pattern.EncodingPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.EndOfBatchPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.EqualsIgnoreCaseReplacementConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.EqualsReplacementConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.FileDatePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.FileLocationPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.FullLocationPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.HighlightConverter", + "methods": [ + { + "name": "newInstance", + "parameterTypes": [ + "org.apache.logging.log4j.core.config.Configuration", + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.pattern.IntegerPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.LevelPatternConverter", + "methods": [ + { + "name": "newInstance", + "parameterTypes": [ + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.pattern.LineLocationPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.LineSeparatorPatternConverter", + "methods": [ + { + "name": "newInstance", + "parameterTypes": [ + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.pattern.LoggerFqcnPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.LoggerPatternConverter", + "methods": [ + { + "name": "newInstance", + "parameterTypes": [ + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.pattern.MapPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.MarkerPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.MarkerSimpleNamePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.MaxLengthConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.MdcPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.MessagePatternConverter", + "methods": [ + { + "name": "newInstance", + "parameterTypes": [ + "org.apache.logging.log4j.core.config.Configuration", + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.pattern.MethodLocationPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.NanoTimePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.NdcPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.ProcessIdPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.RegexReplacement" + }, + { + "type": "org.apache.logging.log4j.core.pattern.RegexReplacementConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.RelativeTimePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.RepeatPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.RootThrowablePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.SequenceNumberPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.StyleConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.ThreadIdPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.ThreadNamePatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.ThreadPriorityPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.ThrowablePatternConverter", + "methods": [ + { + "name": "newInstance", + "parameterTypes": [ + "org.apache.logging.log4j.core.config.Configuration", + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.apache.logging.log4j.core.pattern.UuidPatternConverter" + }, + { + "type": "org.apache.logging.log4j.core.pattern.VariablesNotEmptyReplacementConverter" + }, + { + "type": "org.apache.logging.log4j.core.script.Script" + }, + { + "type": "org.apache.logging.log4j.core.script.ScriptFile" + }, + { + "type": "org.apache.logging.log4j.core.script.ScriptRef" + }, + { + "type": "org.apache.logging.log4j.core.util.KeyValuePair" + }, + { + "type": "org.apache.logging.log4j.jul.Log4jBridgeHandler" + }, + { + "type": "org.apache.logging.log4j.util.EnvironmentPropertySource" + }, + { + "type": "org.apache.logging.log4j.util.SystemPropertiesPropertySource" + }, + { + "type": "org.apache.logging.slf4j.SLF4JProvider" + }, + { + "type": "org.apache.logging.slf4j.SLF4JServiceProvider" + }, + { + "type": "org.crac.Core" + }, + { + "type": "org.eclipse.core.runtime.FileLocator" + }, + { + "type": "org.flywaydb.core.Flyway", + "methods": [ + { + "name": "migrate", + "parameterTypes": [] + } + ] + }, + { + "type": "org.flywaydb.core.api.migration.baseline.BaselineAppliedMigration" + }, + { + "type": "org.flywaydb.core.api.migration.baseline.BaselineMigrationConfigurationExtension", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "getBaselineMigrationPrefix", + "parameterTypes": [] + }, + { + "name": "setBaselineMigrationPrefix", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "type": "org.flywaydb.core.api.migration.baseline.BaselineMigrationResolver" + }, + { + "type": "org.flywaydb.core.api.migration.baseline.BaselineResourceTypeProvider" + }, + { + "type": "org.flywaydb.core.extensibility.ConfigurationExtension" + }, + { + "type": "org.flywaydb.core.extensibility.Plugin" + }, + { + "type": "org.flywaydb.core.internal.NullFlywayTelemetryManager" + }, + { + "type": "org.flywaydb.core.internal.command.clean.CleanModeConfigurationExtension", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "getClean", + "parameterTypes": [] + }, + { + "name": "setClean", + "parameterTypes": [ + "org.flywaydb.core.internal.command.clean.CleanModel" + ] + } + ] + }, + { + "type": "org.flywaydb.core.internal.command.clean.CleanModel" + }, + { + "type": "org.flywaydb.core.internal.command.clean.SchemaModel" + }, + { + "type": "org.flywaydb.core.internal.configuration.resolvers.EnvironmentProvisionerNone" + }, + { + "type": "org.flywaydb.core.internal.configuration.resolvers.EnvironmentVariableResolver" + }, + { + "type": "org.flywaydb.core.internal.configuration.resolvers.PlaceholderPropertyResolver" + }, + { + "type": "org.flywaydb.core.internal.database.base.TestContainersDatabaseType" + }, + { + "type": "org.flywaydb.core.internal.database.h2.H2DatabaseType" + }, + { + "type": "org.flywaydb.core.internal.database.sqlite.SQLiteDatabaseType" + }, + { + "type": "org.flywaydb.core.internal.jdbc.ErrorOverrideInitializerStub" + }, + { + "type": "org.flywaydb.core.internal.logging.slf4j.Slf4jLogCreator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.AuthCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.CheckCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.DeployCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.DiffCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.DiffTextCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.GenerateCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.LicensingConfigurationExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.ModelCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.OfflinePermitConfigurationExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.PATTokenConfigurationExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.PrepareCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.proprietaryStubs.UndoCommandExtensionStub" + }, + { + "type": "org.flywaydb.core.internal.publishing.PublishingConfigurationExtension", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "isCheckDriftOnMigrate", + "parameterTypes": [] + }, + { + "name": "isPublishResult", + "parameterTypes": [] + }, + { + "name": "setCheckDriftOnMigrate", + "parameterTypes": [ + "boolean" + ] + }, + { + "name": "setPublishResult", + "parameterTypes": [ + "boolean" + ] + } + ] + }, + { + "type": "org.flywaydb.core.internal.resource.CoreResourceTypeProvider" + }, + { + "type": "org.flywaydb.core.internal.scanner.classpath.ClasspathLocationHandlerImpl" + }, + { + "type": "org.flywaydb.core.internal.scanner.filesystem.FilesystemLocationHandler" + }, + { + "type": "org.flywaydb.core.internal.schemahistory.BaseAppliedMigration" + }, + { + "type": "org.flywaydb.database.cockroachdb.CockroachDBDatabaseType" + }, + { + "type": "org.flywaydb.database.postgresql.PostgreSQLConfigurationExtension", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "getTransactional", + "parameterTypes": [] + }, + { + "name": "isTransactionalLock", + "parameterTypes": [] + }, + { + "name": "setTransactional", + "parameterTypes": [ + "org.flywaydb.database.postgresql.TransactionalModel" + ] + }, + { + "name": "setTransactionalLock", + "parameterTypes": [ + "boolean" + ] + } + ] + }, + { + "type": "org.flywaydb.database.postgresql.PostgreSQLDatabaseType" + }, + { + "type": "org.flywaydb.database.postgresql.TransactionalModel", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "getLock", + "parameterTypes": [] + }, + { + "name": "setLock", + "parameterTypes": [ + "java.lang.Boolean" + ] + } + ] + }, + { + "type": "org.osgi.framework.FrameworkUtil" + }, + { + "type": "org.postgresql.Driver", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.postgresql.core.QueryExecutorCloseAction" + }, + { + "type": "org.postgresql.jdbc.PgStatement" + }, + { + "type": "org.reactivestreams.Publisher" + }, + { + "type": "org.slf4j.Logger" + }, + { + "type": "org.slf4j.impl.StaticLoggerBinder" + }, + { + "type": "org.slf4j.spi.SLF4JServiceProvider" + }, + { + "type": "org.springframework.beans.factory.Aware" + }, + { + "type": "org.springframework.beans.factory.BeanClassLoaderAware" + }, + { + "type": "org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.beans.factory.annotation.Value" + }, + { + "type": "org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor" + }, + { + "type": "org.springframework.beans.factory.aot.BeanRegistrationAotProcessor" + }, + { + "type": "org.springframework.beans.factory.config.BeanFactoryPostProcessor" + }, + { + "type": "org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor" + }, + { + "type": "org.springframework.boot.ApplicationProperties" + }, + { + "type": "org.springframework.boot.ClearCachesApplicationListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.ansi.AnsiOutput$Enabled" + }, + { + "type": "org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.autoconfigure.condition.ConditionalOnBean" + }, + { + "type": "org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty" + }, + { + "type": "org.springframework.boot.autoconfigure.condition.ConditionalOnClass" + }, + { + "type": "org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean" + }, + { + "type": "org.springframework.boot.autoconfigure.condition.ConditionalOnProperty" + }, + { + "type": "org.springframework.boot.autoconfigure.condition.OnBeanCondition", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.autoconfigure.condition.OnClassCondition", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.autoconfigure.condition.OnPropertyCondition", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializingApplicationListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.autoconfigure.preinitialize.CharsetsBackgroundPreinitializer", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.autoconfigure.preinitialize.ConversionServiceBackgroundPreinitializer", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.builder.ParentContextCloserApplicationListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.springframework.boot.logging.DeferredLogFactory" + ] + } + ] + }, + { + "type": "org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.ContextIdApplicationContextInitializer", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.FileEncodingApplicationListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.springframework.boot.logging.DeferredLogFactory", + "org.springframework.boot.bootstrap.ConfigurableBootstrapContext" + ] + } + ] + }, + { + "type": "org.springframework.boot.context.config.ConfigDataLocation[]" + }, + { + "type": "org.springframework.boot.context.config.ConfigDataNotFoundAction" + }, + { + "type": "org.springframework.boot.context.config.ConfigDataProperties" + }, + { + "type": "org.springframework.boot.context.config.ConfigTreeConfigDataLoader", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.springframework.core.io.ResourceLoader" + ] + } + ] + }, + { + "type": "org.springframework.boot.context.config.StandardConfigDataLoader", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.config.StandardConfigDataLocationResolver", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.springframework.boot.logging.DeferredLogFactory", + "org.springframework.boot.context.properties.bind.Binder", + "org.springframework.core.io.ResourceLoader" + ] + } + ] + }, + { + "type": "org.springframework.boot.context.config.SystemEnvironmentConfigDataLoader", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.config.SystemEnvironmentConfigDataLocationResolver", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.event.EventPublishingRunListener", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.springframework.boot.SpringApplication", + "java.lang.String[]" + ] + } + ] + }, + { + "type": "org.springframework.boot.context.logging.LoggingApplicationListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.context.properties.bind.Name" + }, + { + "type": "org.springframework.boot.env.PropertiesPropertySourceLoader", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.env.YamlPropertySourceLoader", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.io.Base64ProtocolResolver", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.io.ProtocolResolverApplicationContextInitializer", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.loader.launch.LaunchedClassLoader" + }, + { + "type": "org.springframework.boot.logging.java.JavaLoggingSystem$Factory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.logging.log4j2.ColorConverter" + }, + { + "type": "org.springframework.boot.logging.log4j2.CorrelationIdConverter" + }, + { + "type": "org.springframework.boot.logging.log4j2.EnclosedInSquareBracketsConverter" + }, + { + "type": "org.springframework.boot.logging.log4j2.ExtendedWhitespaceThrowablePatternConverter" + }, + { + "type": "org.springframework.boot.logging.log4j2.Log4J2LoggingSystem$Factory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.logging.log4j2.SpringBootConfigurationFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.logging.log4j2.SpringBootPropertySource" + }, + { + "type": "org.springframework.boot.logging.log4j2.SpringEnvironmentLookup", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.logging.log4j2.SpringProfileArbiter" + }, + { + "type": "org.springframework.boot.logging.log4j2.StructuredLogLayout" + }, + { + "type": "org.springframework.boot.logging.log4j2.WhitespaceThrowablePatternConverter" + }, + { + "type": "org.springframework.boot.logging.logback.LogbackLoggingSystem$Factory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.support.AnsiOutputApplicationListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.support.EnvironmentPostProcessorApplicationListener", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.support.RandomValuePropertySourceEnvironmentPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.springframework.boot.logging.DeferredLogFactory" + ] + } + ] + }, + { + "type": "org.springframework.boot.support.SpringApplicationJsonEnvironmentPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.boot.support.SystemEnvironmentPropertySourceEnvironmentPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.context.ApplicationListener" + }, + { + "type": "org.springframework.context.ApplicationStartupAware" + }, + { + "type": "org.springframework.context.EnvironmentAware" + }, + { + "type": "org.springframework.context.ResourceLoaderAware" + }, + { + "type": "org.springframework.context.annotation.Bean" + }, + { + "type": "org.springframework.context.annotation.CommonAnnotationBeanPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.context.annotation.Conditional" + }, + { + "type": "org.springframework.context.annotation.Configuration" + }, + { + "type": "org.springframework.context.annotation.ConfigurationClassPostProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "setMetadataReaderFactory", + "parameterTypes": [ + "org.springframework.core.type.classreading.MetadataReaderFactory" + ] + } + ] + }, + { + "type": "org.springframework.context.annotation.DependsOn" + }, + { + "type": "org.springframework.context.annotation.Import" + }, + { + "type": "org.springframework.context.annotation.ImportRuntimeHints" + }, + { + "type": "org.springframework.context.annotation.PropertySource" + }, + { + "type": "org.springframework.context.annotation.PropertySources" + }, + { + "type": "org.springframework.context.event.DefaultEventListenerFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.context.event.EventListenerMethodProcessor", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "org.springframework.core.Ordered" + }, + { + "type": "org.springframework.core.PriorityOrdered" + }, + { + "type": "org.springframework.core.annotation.AliasFor" + }, + { + "type": "org.springframework.core.annotation.AnnotationAttributes[]" + }, + { + "type": "org.springframework.core.annotation.MergedAnnotation[]" + }, + { + "type": "org.springframework.core.annotation.Order" + }, + { + "type": "org.springframework.core.type.classreading.CachingMetadataReaderFactory" + }, + { + "type": "org.springframework.core.type.classreading.MetadataReaderFactory" + }, + { + "type": "org.springframework.stereotype.Component" + }, + { + "type": "org.springframework.stereotype.Indexed" + }, + { + "type": "org.springframework.util.ConcurrentReferenceHashMap$Segment[]" + }, + { + "type": "reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber" + }, + { + "type": "reactor.core.publisher.FluxIterable$IterableSubscription" + }, + { + "type": "reactor.core.publisher.FluxIterable$IterableSubscriptionConditional" + }, + { + "type": "reactor.core.publisher.FluxSink[]" + }, + { + "type": "reactor.core.publisher.LambdaMonoSubscriber" + }, + { + "type": "reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription" + }, + { + "type": "reactor.core.publisher.MonoFlatMap$FlatMapMain" + }, + { + "type": "reactor.core.publisher.Operators$BaseFluxToMonoOperator" + }, + { + "type": "reactor.core.publisher.Operators$MultiSubscriptionSubscriber" + }, + { + "type": "reactor.core.publisher.Operators$ScalarSubscription" + }, + { + "type": "reactor.core.scheduler.BoundedElasticScheduler" + }, + { + "type": "reactor.core.scheduler.BoundedElasticScheduler$BoundedServices" + }, + { + "type": "reactor.core.scheduler.BoundedElasticScheduler$BoundedState" + }, + { + "type": "reactor.core.scheduler.ParallelScheduler" + }, + { + "type": "reactor.core.scheduler.SchedulerTask" + }, + { + "type": "reactor.core.scheduler.SingleScheduler" + }, + { + "type": "reactor.pool.AllocationStrategies$SizeBasedAllocationStrategy" + }, + { + "type": "reactor.pool.SimpleDequePool" + }, + { + "type": "sun.management.VMManagementImpl", + "jniAccessible": true, + "fields": [ + { + "name": "compTimeMonitoringSupport" + }, + { + "name": "currentThreadCpuTimeSupport" + }, + { + "name": "objectMonitorUsageSupport" + }, + { + "name": "otherThreadCpuTimeSupport" + }, + { + "name": "remoteDiagnosticCommandsSupport" + }, + { + "name": "synchronizerUsageSupport" + }, + { + "name": "threadAllocatedMemorySupport" + }, + { + "name": "threadContentionMonitoringSupport" + } + ] + }, + { + "type": "sun.security.pkcs12.PKCS12KeyStore", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.DSA$SHA224withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.DSA$SHA256withDSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.NativePRNG", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ] + }, + { + "type": "sun.security.provider.SHA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.SHA2$SHA224", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.SHA2$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.SHA5$SHA384", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.SHA5$SHA512", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.X509Factory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.rsa.PSSParameters", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.rsa.RSAKeyFactory$Legacy", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.rsa.RSAPSSSignature", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.rsa.RSASignature$SHA224withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.rsa.RSASignature$SHA384withRSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.ssl.SSLContextImpl$TLS12Context", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.x509.AuthorityInfoAccessExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.AuthorityKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.BasicConstraintsExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.CRLDistributionPointsExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.CertificatePoliciesExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.ExtendedKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.KeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.NetscapeCertTypeExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.PrivateKeyUsageExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.SubjectAlternativeNameExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.security.x509.SubjectKeyIdentifierExtension", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.Boolean", + "java.lang.Object" + ] + } + ] + }, + { + "type": "sun.text.resources.cldr.FormatData" + }, + { + "type": "sun.text.resources.cldr.FormatData_en" + }, + { + "type": "sun.text.resources.cldr.FormatData_en_US" + }, + { + "type": "sun.util.resources.cldr.CalendarData" + }, + { + "type": "tools.jackson.databind.deser.Deserializers[]" + }, + { + "type": "tools.jackson.databind.deser.KeyDeserializers[]" + }, + { + "type": "tools.jackson.databind.deser.ValueInstantiators[]" + }, + { + "type": "tools.jackson.databind.ser.Serializers[]" + }, + { + "type": { + "proxy": [ + "java.lang.reflect.ParameterizedType", + "org.springframework.core.SerializableTypeWrapper$SerializableTypeProxy", + "java.io.Serializable" + ] + } + }, + { + "type": { + "proxy": [ + "java.lang.reflect.TypeVariable", + "org.springframework.core.SerializableTypeWrapper$SerializableTypeProxy", + "java.io.Serializable" + ] + } + }, + { + "type": { + "proxy": [ + "java.lang.reflect.WildcardType", + "org.springframework.core.SerializableTypeWrapper$SerializableTypeProxy", + "java.io.Serializable" + ] + } + }, + { + "type": { + "lambda": { + "declaringClass": "javasabr.mqtt.broker.application.config.MqttExternalPlainNetworkConfig", + "interfaces": [ + "org.springframework.context.ApplicationListener" + ] + } + } + }, + { + "type": { + "lambda": { + "declaringClass": "javasabr.mqtt.broker.application.config.MqttExternalTlsNetworkConfig", + "interfaces": [ + "org.springframework.context.ApplicationListener" + ] + } + } + } + ], + "resources": [ + { + "glob": "META-INF/log4j-provider.properties" + }, + { + "glob": "META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat" + }, + { + "glob": "META-INF/services/io.r2dbc.postgresql.extension.Extension" + }, + { + "glob": "META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider" + }, + { + "glob": "META-INF/services/java.net.spi.InetAddressResolverProvider" + }, + { + "glob": "META-INF/services/java.net.spi.URLStreamHandlerProvider" + }, + { + "glob": "META-INF/services/java.nio.channels.spi.AsynchronousChannelProvider" + }, + { + "glob": "META-INF/services/java.time.zone.ZoneRulesProvider" + }, + { + "glob": "META-INF/services/javasabr.rlib.logger.api.LoggerFactory" + }, + { + "glob": "META-INF/services/javax.xml.parsers.DocumentBuilderFactory" + }, + { + "glob": "META-INF/services/org.apache.commons.logging.LogFactory" + }, + { + "glob": "META-INF/services/org.apache.logging.log4j.core.util.ContextDataProvider" + }, + { + "glob": "META-INF/services/org.apache.logging.log4j.core.util.WatchEventService" + }, + { + "glob": "META-INF/services/org.apache.logging.log4j.spi.Provider" + }, + { + "glob": "META-INF/services/org.apache.logging.log4j.util.PropertySource" + }, + { + "glob": "META-INF/services/org.flywaydb.core.extensibility.Plugin" + }, + { + "glob": "META-INF/services/org.slf4j.spi.SLF4JServiceProvider" + }, + { + "glob": "META-INF/spring.components" + }, + { + "glob": "META-INF/spring.factories" + }, + { + "glob": "application-default.properties" + }, + { + "glob": "application-default.xml" + }, + { + "glob": "application-default.yaml" + }, + { + "glob": "application-default.yml" + }, + { + "glob": "application.properties" + }, + { + "glob": "application.xml" + }, + { + "glob": "application.yaml" + }, + { + "glob": "application.yml" + }, + { + "glob": "banner.txt" + }, + { + "glob": "commons-logging.properties" + }, + { + "glob": "config/application-default.properties" + }, + { + "glob": "config/application-default.xml" + }, + { + "glob": "config/application-default.yaml" + }, + { + "glob": "config/application-default.yml" + }, + { + "glob": "config/application.properties" + }, + { + "glob": "config/application.xml" + }, + { + "glob": "config/application.yaml" + }, + { + "glob": "config/application.yml" + }, + { + "glob": "db/callback" + }, + { + "glob": "db/migration" + }, + { + "glob": "db/migration/V1__Create_User_Credentials_Table.sql" + }, + { + "glob": "javasabr/mqtt/auth/service/config/AuthenticationServiceSpringConfig.class" + }, + { + "glob": "javasabr/mqtt/auth/service/config/DatabaseCredentialsSourceSpringConfig.class" + }, + { + "glob": "javasabr/mqtt/auth/service/config/FileCredentialsSourceSpringConfig.class" + }, + { + "glob": "javasabr/mqtt/broker/application/config/MqttBrokerSpringConfig.class" + }, + { + "glob": "javasabr/mqtt/broker/application/config/MqttExternalPlainNetworkConfig.class" + }, + { + "glob": "javasabr/mqtt/broker/application/config/MqttExternalTlsNetworkConfig.class" + }, + { + "glob": "log4j2-test.jsn" + }, + { + "glob": "log4j2-test.json" + }, + { + "glob": "log4j2-test.properties" + }, + { + "glob": "log4j2-test.springboot" + }, + { + "glob": "log4j2-test.xml" + }, + { + "glob": "log4j2-test.yaml" + }, + { + "glob": "log4j2-test.yml" + }, + { + "glob": "log4j2-test27bc2616.jsn" + }, + { + "glob": "log4j2-test27bc2616.json" + }, + { + "glob": "log4j2-test27bc2616.properties" + }, + { + "glob": "log4j2-test27bc2616.springboot" + }, + { + "glob": "log4j2-test27bc2616.xml" + }, + { + "glob": "log4j2-test27bc2616.yaml" + }, + { + "glob": "log4j2-test27bc2616.yml" + }, + { + "glob": "log4j2.StatusLogger.properties" + }, + { + "glob": "log4j2.component.properties" + }, + { + "glob": "log4j2.jsn" + }, + { + "glob": "log4j2.json" + }, + { + "glob": "log4j2.properties" + }, + { + "glob": "log4j2.system.properties" + }, + { + "glob": "log4j2.xml" + }, + { + "glob": "log4j2.yaml" + }, + { + "glob": "log4j2.yml" + }, + { + "glob": "log4j227bc2616.jsn" + }, + { + "glob": "log4j227bc2616.json" + }, + { + "glob": "log4j227bc2616.properties" + }, + { + "glob": "log4j227bc2616.springboot" + }, + { + "glob": "log4j227bc2616.xml" + }, + { + "glob": "log4j227bc2616.yaml" + }, + { + "glob": "log4j227bc2616.yml" + }, + { + "glob": "org/flywaydb/core/internal/version.txt" + }, + { + "glob": "org/postgresql/driverconfig.properties" + }, + { + "glob": "spring.properties" + }, + { + "module": "java.base", + "glob": "jdk/internal/icu/impl/data/icudt76b/nfkc.nrm" + } + ] +} \ No newline at end of file diff --git a/application/src/test/groovy/javasabr/mqtt/broker/application/NativeImageVerificationTest.groovy b/application/src/test/groovy/javasabr/mqtt/broker/application/NativeImageVerificationTest.groovy new file mode 100644 index 00000000..258d878e --- /dev/null +++ b/application/src/test/groovy/javasabr/mqtt/broker/application/NativeImageVerificationTest.groovy @@ -0,0 +1,171 @@ +package javasabr.mqtt.broker.application + +import groovy.util.logging.Slf4j +import org.junit.platform.engine.TestExecutionResult +import org.junit.platform.testkit.engine.EngineExecutionResults +import org.junit.platform.testkit.engine.EventType +import spock.lang.Requires +import spock.lang.Shared +import spock.lang.Specification +import spock.util.EmbeddedSpecRunner + +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit + +import static javasabr.mqtt.broker.application.NativeImageVerificationTest.ConsoleStyle.color +import static javasabr.mqtt.broker.application.NativeImageVerificationTest.ConsoleStyle.italic +import static spock.util.EmbeddedSpecRunner.XFailure + +@Slf4j +@Requires({ new File(BINARY_DIR, BINARY_NAME).exists() }) +class NativeImageVerificationTest extends Specification { + + private static final String BINARY_DIR = "build/native/nativeCompile" + private static final String BINARY_NAME = "application" + private static final String NETWORK_READY_MARKER = "Started external MQTT network by address" + + @Shared + Process brokerProcess + + @Shared + EmbeddedSpecRunner testRunner + + def setupSpec() { + brokerProcess = new ProcessBuilder() + .command(buildBrokerStartupCommand()) + .directory(new File(BINARY_DIR)) + .redirectErrorStream(true) + .start() + awaitBrokerStartup(brokerProcess, 1, TimeUnit.SECONDS) + testRunner = new EmbeddedSpecRunner(throwFailure: false) + } + + def cleanupSpec() { + try { + if (brokerProcess != null && brokerProcess.isAlive()) { + brokerProcess.destroy() + brokerProcess.waitFor(5, TimeUnit.SECONDS) + } + } finally { + if (brokerProcess.isAlive()) { + brokerProcess.destroyForcibly() + } + } + } + + def "#test should pass without failures"(String test) { + given: + def testSource = new File("src/test/groovy/javasabr/mqtt/broker/application/${test}.groovy") + .text + .replace( + "extends TlsIntegrationSpecification", + "extends javasabr.mqtt.broker.application.NativeImageVerificationTest.TlsStandaloneBrokerRouterSpec" + ) + .replace( + "extends IntegrationSpecification", + "extends javasabr.mqtt.broker.application.NativeImageVerificationTest.StandaloneBrokerRouterSpec" + ) + when: + def testResult = testRunner.run(testSource) + then: + with(testResult.properties) { results -> + printTestResults(results) + results['testsStartedCount'] > 0 + results['testsStartedCount'] == results['testsSucceededCount'] + } + where: + test << ["ConnectSubscribePublishTest", "ExternalConnectionTest", "PublishRetryTest", "TlsCommunicationTest"] + } + + + private static String[] buildBrokerStartupCommand() { + def binaryDir = new File(BINARY_DIR) + def applicationPropertiesPath = new File("src/test/resources/application-test.properties").absolutePath + def binaryPath = new File(binaryDir, BINARY_NAME).absolutePath + + return TestSslPropertiesInitializer.getProps() + .collect { key, value -> "--${key}=${value}" as String } + .plus(0, [ + binaryPath, + "--spring.config.location=file://${applicationPropertiesPath}" as String, + "--mqtt.external.tls.network.enabled=true", + "--mqtt.external.tls.require-client-cert=false" + ]) + .toArray(String[]::new) + } + + private static void awaitBrokerStartup(Process process, long amount, TimeUnit unit) { + def networkReady = new CountDownLatch(1) + Thread.startDaemon("broker-output-drainer") { + def reader = new BufferedReader(new InputStreamReader(process.getInputStream())) + String line + while ((line = reader.readLine()) != null) { + println "[Standalone Broker] ${line}" + if (line.contains(NETWORK_READY_MARKER)) { + networkReady.countDown() + } + } + } + if (!networkReady.await(amount, unit)) { + process.destroyForcibly() + throw new RuntimeException("Broker failed to start within 10 seconds: network not ready") + } + } + + static void printTestResults(Map props) { + (props['results'] as EngineExecutionResults).testEvents() + .stream() + .filter { it.type == EventType.FINISHED } + .each { event -> + def testMethod = event.testDescriptor.displayName + def status = event.payload + .map { it as TestExecutionResult } + .map { it.status } + .orElse(null) + log.info "'${italic(testMethod)}' ${color(status)}" + } + + if (props['failureCount'] > 0) { + props['failures'].each { XFailure f -> f.exception.printStackTrace() } + } + } + + static class StandaloneBrokerRouterSpec extends IntegrationSpecification { + def setup() { + externalPlainNetworkAddress = InetSocketAddress.createUnresolved("localhost", 1883) + } + } + + static class TlsStandaloneBrokerRouterSpec extends TlsIntegrationSpecification { + def setup() { + externalTlsNetworkAddress = InetSocketAddress.createUnresolved("localhost", 8883) + } + } + + enum ConsoleStyle { + RED("\u001B[31m", TestExecutionResult.Status.FAILED), + GREEN("\u001B[32m", TestExecutionResult.Status.SUCCESSFUL), + YELLOW("\u001B[33m", TestExecutionResult.Status.ABORTED); + + static final Map CACHE = values().collectEntries { [it.status, it.anchor] } + + static final String RESET = "\u001B[0m" + static final String ITALIC = "\u001B[3m" + + String anchor; + TestExecutionResult.Status status; + + ConsoleStyle(String anchor, TestExecutionResult.Status status) { + this.anchor = anchor + this.status = status + } + + static String color(TestExecutionResult.Status status) { + return "${CACHE.getOrDefault(status, RESET)}${status}${RESET}" + } + + static String italic(String text) { + return "${ITALIC}${text}${RESET}" + } + } +} diff --git a/application/src/test/groovy/javasabr/mqtt/broker/application/TestSslPropertiesInitializer.groovy b/application/src/test/groovy/javasabr/mqtt/broker/application/TestSslPropertiesInitializer.groovy index 8bf994f7..e32e4f59 100644 --- a/application/src/test/groovy/javasabr/mqtt/broker/application/TestSslPropertiesInitializer.groovy +++ b/application/src/test/groovy/javasabr/mqtt/broker/application/TestSslPropertiesInitializer.groovy @@ -7,16 +7,17 @@ import org.springframework.core.env.MapPropertySource class TestSslPropertiesInitializer implements ApplicationContextInitializer { - TestSslContexts sslContexts = TestSslContexts.getInstance() - @Override void initialize(ConfigurableApplicationContext applicationContext) { - def props = [ - "mqtt.external.tls.keystore-path": sslContexts.serverKeystorePath.toString(), - "mqtt.external.tls.keystore-password": sslContexts.password, - "mqtt.external.tls.truststore-path": sslContexts.truststore.toString(), - "mqtt.external.tls.truststore-password": sslContexts.password + applicationContext.environment.propertySources.addFirst(new MapPropertySource("tlsProps", getProps())) + } + + static Map getProps() { + return [ + "mqtt.external.tls.keystore-path": TestSslContexts.getInstance().serverKeystorePath.toString(), + "mqtt.external.tls.keystore-password": TestSslContexts.getInstance().password, + "mqtt.external.tls.truststore-path": TestSslContexts.getInstance().truststore.toString(), + "mqtt.external.tls.truststore-password": TestSslContexts.getInstance().password ] - applicationContext.environment.propertySources.addFirst(new MapPropertySource("tlsProps", props)) } } diff --git a/base/src/main/java/javasabr/mqtt/base/util/ClassPathResourceResolver.java b/base/src/main/java/javasabr/mqtt/base/util/ClassPathResourceResolver.java new file mode 100644 index 00000000..1d81f62d --- /dev/null +++ b/base/src/main/java/javasabr/mqtt/base/util/ClassPathResourceResolver.java @@ -0,0 +1,47 @@ +package javasabr.mqtt.base.util; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class ClassPathResourceResolver { + + private static final ClassLoader CLASS_LOADER = ClassPathResourceResolver.class.getClassLoader(); + + public static InputStream newInputStream(URI uri) throws IOException { + if (uri == null) { + throw new IllegalArgumentException("URI must not be null"); + } + switch (uri.getScheme()) { + case "classpath": + String sanitizedPath = uri.getSchemeSpecificPart(); + if (sanitizedPath == null || sanitizedPath.isEmpty()) { + throw new IllegalArgumentException("Classpath URI must have a non-empty resource path: %s".formatted(uri)); + } + Path resourcePath = Path.of(sanitizedPath); + if (Files.exists(resourcePath)) { + return Files.newInputStream(resourcePath); + } + if (sanitizedPath.startsWith("/")) { + sanitizedPath = sanitizedPath.substring(1); + } + InputStream resourceAsStream = CLASS_LOADER.getResourceAsStream(sanitizedPath); + if (resourceAsStream != null) { + return resourceAsStream; + } + throw new FileNotFoundException(uri.toString()); + default: + Path localPath = Path.of(uri); + if (Files.exists(localPath)) { + return Files.newInputStream(localPath); + } + throw new FileNotFoundException(uri.toString()); + } + } +} diff --git a/base/src/test/groovy/javasabr/mqtt/base/util/ClassPathResourceResolverTest.groovy b/base/src/test/groovy/javasabr/mqtt/base/util/ClassPathResourceResolverTest.groovy new file mode 100644 index 00000000..c19d39a3 --- /dev/null +++ b/base/src/test/groovy/javasabr/mqtt/base/util/ClassPathResourceResolverTest.groovy @@ -0,0 +1,87 @@ +package javasabr.mqtt.base.util + +import javasabr.mqtt.test.support.UnitSpecification + +import java.nio.charset.StandardCharsets +import java.nio.file.Files +import java.nio.file.Path + +class ClassPathResourceResolverTest extends UnitSpecification { + + def "should resolve file URI to Path"() { + given: + def tempFile = Files.createTempFile("test", ".txt") + Files.writeString(tempFile, "hello") + def uri = tempFile.toUri() + when: + def result = ClassPathResourceResolver.newInputStream(uri) + then: + new String(result.readAllBytes(), StandardCharsets.UTF_8) == "hello" + cleanup: + result.close() + Files.deleteIfExists(tempFile) + } + + def "should resolve classpath URI to existing Path"() { + given: + def uri = URI.create("classpath:javasabr/mqtt/base/util/ClassPathResourceResolver.class") + when: + def result = ClassPathResourceResolver.newInputStream(uri) + then: + result.available() > 0 + cleanup: + result.close() + } + + def "should handle classpath URI with leading slash"() { + given: + def uri = URI.create("classpath:/javasabr/mqtt/base/util/ClassPathResourceResolver.class") + when: + def result = ClassPathResourceResolver.newInputStream(uri) + then: + result.available() > 0 + cleanup: + result.close() + } + + def "should throw NullPointerException for null URI"() { + when: + ClassPathResourceResolver.newInputStream(null) + then: + thrown(IllegalArgumentException) + } + + def "should throw IllegalArgumentException for missing classpath resource"() { + given: + def uri = URI.create("classpath:nonexistent/resource.txt") + when: + ClassPathResourceResolver.newInputStream(uri) + then: + thrown(FileNotFoundException) + } + + def "should throw IllegalArgumentException for classpath URI with blank resource path"() { + given: + def uri = new URI("classpath", " ", null) + when: + ClassPathResourceResolver.newInputStream(uri) + then: + thrown(FileNotFoundException) + } + + def "should resolve classpath URI via filesystem fallback when not on classloader"() { + given: + def testDir = Path.of("build/tmp/classpath-test") + Files.createDirectories(testDir) + def resourceFile = Files.writeString(testDir.resolve("data.txt"), "fallback content") + def uri = URI.create("classpath:build/tmp/classpath-test/data.txt") + when: + def result = ClassPathResourceResolver.newInputStream(uri) + then: + new String(result.readAllBytes(), StandardCharsets.UTF_8) == "fallback content" + cleanup: + result.close() + Files.deleteIfExists(resourceFile) + Files.deleteIfExists(testDir) + } +} diff --git a/build.gradle b/build.gradle index 7fbcfd80..406c2fb0 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { } dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:4.0.2" + classpath "org.graalvm.buildtools:native-gradle-plugin:1.1.1" } } diff --git a/credentials-source-file/src/main/java/javasabr/mqtt/auth/credentials/source/FileCredentialsSource.java b/credentials-source-file/src/main/java/javasabr/mqtt/auth/credentials/source/FileCredentialsSource.java index 385fd3b0..44d535e3 100644 --- a/credentials-source-file/src/main/java/javasabr/mqtt/auth/credentials/source/FileCredentialsSource.java +++ b/credentials-source-file/src/main/java/javasabr/mqtt/auth/credentials/source/FileCredentialsSource.java @@ -2,17 +2,16 @@ import com.fasterxml.jackson.annotation.JsonValue; import java.io.IOException; +import java.io.InputStream; import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Map; import javasabr.mqtt.auth.api.CredentialsSourceType; import javasabr.mqtt.auth.api.exception.CredentialsSourceException; +import javasabr.mqtt.base.util.ClassPathResourceResolver; import javasabr.mqtt.base.util.DebugUtils; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; - @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class FileCredentialsSource extends InMemoryCredentialsSource { @@ -24,12 +23,8 @@ public FileCredentialsSource(URI fileName) { } private void init() { - Path path = Path.of(fileName); - if (!Files.exists(path)) { - throw new CredentialsSourceException("Credentials file:[%s] could not be found".formatted(fileName)); - } - try { - reset(Files.newInputStream(path)); + try (InputStream aclInputStream = ClassPathResourceResolver.newInputStream(fileName)) { + reset(aclInputStream); } catch (IOException e) { throw new CredentialsSourceException("Error during credentials file read", e); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 51806111..2dc9d7ae 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,6 +23,8 @@ flyway="11.19.0" spock = "2.4-M6-groovy-4.0" # https://mvnrepository.com/artifact/org.apache.groovy/groovy-all groovy = "4.0.28" +# https://mvnrepository.com/artifact/org.junit/junit-bom +junit = "6.0.2" # https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web springboot = '4.0.6' # https://mvnrepository.com/artifact/org.springframework/spring-core @@ -87,6 +89,7 @@ spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" } spock-spring = { module = "org.spockframework:spock-spring", version.ref = "spock" } groovy-core = { module = "org.apache.groovy:groovy", version.ref = "groovy" } groovy-all = { module = "org.apache.groovy:groovy-all", version.ref = "groovy" } +junit-platform-testkit = { module = "org.junit.platform:junit-platform-testkit", version.ref = "junit" } byte-buddy-dep = { module = "net.bytebuddy:byte-buddy-dep", version.ref = "byte-buddy" } objenesis = { module = "org.objenesis:objenesis", version.ref = "objenesis" } hivemq-mqtt-client = { module = "com.hivemq:hivemq-mqtt-client", version.ref = "hivemq-mqtt-client" }