added connection pooling to gbcs-client
All checks were successful
CI / build (push) Successful in 3m55s
All checks were successful
CI / build (push) Successful in 3m55s
This commit is contained in:
@@ -6,9 +6,9 @@ plugins {
|
|||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
}
|
}
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
allprojects { subproject ->
|
allprojects { subproject ->
|
||||||
group = 'net.woggioni'
|
group = 'net.woggioni'
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
package net.woggioni.gbcs.cli.impl
|
package net.woggioni.gbcs.cli.impl
|
||||||
|
|
||||||
import picocli.CommandLine
|
import picocli.CommandLine
|
||||||
import java.net.URL
|
|
||||||
import java.util.Enumeration
|
|
||||||
import java.util.jar.Attributes
|
import java.util.jar.Attributes
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
package net.woggioni.gbcs.cli.impl.commands
|
package net.woggioni.gbcs.cli.impl.commands
|
||||||
|
|
||||||
import net.woggioni.gbcs.client.GbcsClient
|
|
||||||
|
|
||||||
import net.woggioni.gbcs.cli.impl.GbcsCommand
|
import net.woggioni.gbcs.cli.impl.GbcsCommand
|
||||||
|
import net.woggioni.gbcs.client.GbcsClient
|
||||||
import net.woggioni.jwo.Application
|
import net.woggioni.jwo.Application
|
||||||
import picocli.CommandLine
|
import picocli.CommandLine
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
@@ -6,6 +6,7 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':gbcs-base')
|
implementation project(':gbcs-base')
|
||||||
implementation catalog.picocli
|
implementation catalog.picocli
|
||||||
|
implementation catalog.slf4j.api
|
||||||
implementation catalog.netty.buffer
|
implementation catalog.netty.buffer
|
||||||
implementation catalog.netty.codec.http
|
implementation catalog.netty.codec.http
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ module net.woggioni.gbcs.client {
|
|||||||
requires java.xml;
|
requires java.xml;
|
||||||
requires net.woggioni.gbcs.base;
|
requires net.woggioni.gbcs.base;
|
||||||
requires io.netty.codec;
|
requires io.netty.codec;
|
||||||
|
requires org.slf4j;
|
||||||
|
|
||||||
exports net.woggioni.gbcs.client;
|
exports net.woggioni.gbcs.client;
|
||||||
|
|
||||||
|
@@ -5,11 +5,13 @@ import io.netty.buffer.ByteBuf
|
|||||||
import io.netty.buffer.Unpooled
|
import io.netty.buffer.Unpooled
|
||||||
import io.netty.channel.Channel
|
import io.netty.channel.Channel
|
||||||
import io.netty.channel.ChannelHandlerContext
|
import io.netty.channel.ChannelHandlerContext
|
||||||
import io.netty.channel.ChannelInitializer
|
import io.netty.channel.ChannelOption
|
||||||
import io.netty.channel.ChannelPipeline
|
import io.netty.channel.ChannelPipeline
|
||||||
import io.netty.channel.SimpleChannelInboundHandler
|
import io.netty.channel.SimpleChannelInboundHandler
|
||||||
import io.netty.channel.nio.NioEventLoopGroup
|
import io.netty.channel.nio.NioEventLoopGroup
|
||||||
import io.netty.channel.socket.SocketChannel
|
import io.netty.channel.pool.AbstractChannelPoolHandler
|
||||||
|
import io.netty.channel.pool.ChannelPool
|
||||||
|
import io.netty.channel.pool.FixedChannelPool
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel
|
import io.netty.channel.socket.nio.NioSocketChannel
|
||||||
import io.netty.handler.codec.DecoderException
|
import io.netty.handler.codec.DecoderException
|
||||||
import io.netty.handler.codec.http.DefaultFullHttpRequest
|
import io.netty.handler.codec.http.DefaultFullHttpRequest
|
||||||
@@ -26,8 +28,14 @@ import io.netty.handler.codec.http.HttpVersion
|
|||||||
import io.netty.handler.ssl.SslContext
|
import io.netty.handler.ssl.SslContext
|
||||||
import io.netty.handler.ssl.SslContextBuilder
|
import io.netty.handler.ssl.SslContextBuilder
|
||||||
import io.netty.handler.stream.ChunkedWriteHandler
|
import io.netty.handler.stream.ChunkedWriteHandler
|
||||||
|
import io.netty.util.concurrent.Future
|
||||||
|
import io.netty.util.concurrent.GenericFutureListener
|
||||||
import net.woggioni.gbcs.base.Xml
|
import net.woggioni.gbcs.base.Xml
|
||||||
|
import net.woggioni.gbcs.base.contextLogger
|
||||||
|
import net.woggioni.gbcs.base.debug
|
||||||
|
import net.woggioni.gbcs.base.info
|
||||||
import net.woggioni.gbcs.client.impl.Parser
|
import net.woggioni.gbcs.client.impl.Parser
|
||||||
|
import java.net.InetSocketAddress
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@@ -35,29 +43,36 @@ import java.security.PrivateKey
|
|||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import io.netty.util.concurrent.Future as NettyFuture
|
import io.netty.util.concurrent.Future as NettyFuture
|
||||||
|
|
||||||
|
|
||||||
class GbcsClient(private val profile: Configuration.Profile) : AutoCloseable {
|
class GbcsClient(private val profile: Configuration.Profile) : AutoCloseable {
|
||||||
private val group: NioEventLoopGroup
|
private val group: NioEventLoopGroup
|
||||||
private var sslContext: SslContext
|
private var sslContext: SslContext
|
||||||
|
private val log = contextLogger()
|
||||||
|
private val pool: ChannelPool
|
||||||
|
|
||||||
data class Configuration(
|
data class Configuration(
|
||||||
val profiles : Map<String, Profile>
|
val profiles: Map<String, Profile>
|
||||||
) {
|
) {
|
||||||
sealed class Authentication {
|
sealed class Authentication {
|
||||||
data class TlsClientAuthenticationCredentials(val key: PrivateKey, val certificateChain: Array<X509Certificate>) : Authentication()
|
data class TlsClientAuthenticationCredentials(
|
||||||
|
val key: PrivateKey,
|
||||||
|
val certificateChain: Array<X509Certificate>
|
||||||
|
) : Authentication()
|
||||||
|
|
||||||
data class BasicAuthenticationCredentials(val username: String, val password: String) : Authentication()
|
data class BasicAuthenticationCredentials(val username: String, val password: String) : Authentication()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Profile(
|
data class Profile(
|
||||||
val serverURI: URI,
|
val serverURI: URI,
|
||||||
val authentication : Authentication?
|
val authentication: Authentication?,
|
||||||
|
val maxConnections : Int
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun parse(path : Path) : Configuration {
|
fun parse(path: Path): Configuration {
|
||||||
return Files.newInputStream(path).use {
|
return Files.newInputStream(path).use {
|
||||||
Xml.parseXml(path.toUri().toURL(), it)
|
Xml.parseXml(path.toUri().toURL(), it)
|
||||||
}.let(Parser::parse)
|
}.let(Parser::parse)
|
||||||
@@ -67,9 +82,7 @@ class GbcsClient(private val profile: Configuration.Profile) : AutoCloseable {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
group = NioEventLoopGroup()
|
group = NioEventLoopGroup()
|
||||||
|
sslContext = SslContextBuilder.forClient().also { builder ->
|
||||||
this.sslContext = SslContextBuilder.forClient().also { builder ->
|
|
||||||
|
|
||||||
(profile.authentication as? Configuration.Authentication.TlsClientAuthenticationCredentials)?.let { tlsClientAuthenticationCredentials ->
|
(profile.authentication as? Configuration.Authentication.TlsClientAuthenticationCredentials)?.let { tlsClientAuthenticationCredentials ->
|
||||||
builder.keyManager(
|
builder.keyManager(
|
||||||
tlsClientAuthenticationCredentials.key,
|
tlsClientAuthenticationCredentials.key,
|
||||||
@@ -77,6 +90,61 @@ class GbcsClient(private val profile: Configuration.Profile) : AutoCloseable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
|
val (scheme, host, port) = profile.serverURI.run {
|
||||||
|
Triple(
|
||||||
|
if (scheme == null) "http" else profile.serverURI.scheme,
|
||||||
|
host,
|
||||||
|
port.takeIf { it > 0 } ?: if ("https" == scheme.lowercase()) 443 else 80
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bootstrap = Bootstrap().apply {
|
||||||
|
group(group)
|
||||||
|
channel(NioSocketChannel::class.java)
|
||||||
|
option(ChannelOption.TCP_NODELAY, true)
|
||||||
|
option(ChannelOption.SO_KEEPALIVE, true)
|
||||||
|
remoteAddress(InetSocketAddress(host, port))
|
||||||
|
}
|
||||||
|
val channelPoolHandler = object : AbstractChannelPoolHandler() {
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var connectionCount = AtomicInteger()
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var leaseCount = AtomicInteger()
|
||||||
|
|
||||||
|
override fun channelReleased(ch: Channel) {
|
||||||
|
log.debug {
|
||||||
|
"Released lease ${leaseCount.decrementAndGet()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun channelAcquired(ch: Channel?) {
|
||||||
|
log.debug {
|
||||||
|
"Acquired lease ${leaseCount.getAndIncrement()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun channelCreated(ch: Channel) {
|
||||||
|
log.debug {
|
||||||
|
"Created connection ${connectionCount.getAndIncrement()}"
|
||||||
|
}
|
||||||
|
val pipeline: ChannelPipeline = ch.pipeline()
|
||||||
|
|
||||||
|
// Add SSL handler if needed
|
||||||
|
if ("https".equals(scheme, ignoreCase = true)) {
|
||||||
|
pipeline.addLast("ssl", sslContext.newHandler(ch.alloc(), host, port))
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP handlers
|
||||||
|
pipeline.addLast("codec", HttpClientCodec())
|
||||||
|
pipeline.addLast("decompressor", HttpContentDecompressor())
|
||||||
|
pipeline.addLast("aggregator", HttpObjectAggregator(1048576))
|
||||||
|
pipeline.addLast("chunked", ChunkedWriteHandler())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pool = FixedChannelPool(bootstrap, channelPoolHandler, profile.maxConnections)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun get(key: String): CompletableFuture<ByteArray?> {
|
fun get(key: String): CompletableFuture<ByteArray?> {
|
||||||
@@ -110,92 +178,69 @@ class GbcsClient(private val profile: Configuration.Profile) : AutoCloseable {
|
|||||||
|
|
||||||
private fun sendRequest(uri: URI, method: HttpMethod, body: ByteArray?): CompletableFuture<FullHttpResponse> {
|
private fun sendRequest(uri: URI, method: HttpMethod, body: ByteArray?): CompletableFuture<FullHttpResponse> {
|
||||||
val responseFuture = CompletableFuture<FullHttpResponse>()
|
val responseFuture = CompletableFuture<FullHttpResponse>()
|
||||||
|
// Custom handler for processing responses
|
||||||
try {
|
pool.acquire().addListener(object : GenericFutureListener<NettyFuture<Channel>> {
|
||||||
val scheme = if (uri.scheme == null) "http" else uri.scheme
|
override fun operationComplete(channelFuture: Future<Channel>) {
|
||||||
val host = uri.host
|
if (channelFuture.isSuccess) {
|
||||||
var port = uri.port
|
val channel = channelFuture.now
|
||||||
if (port == -1) {
|
val pipeline = channel.pipeline()
|
||||||
port = if ("https".equals(scheme, ignoreCase = true)) 443 else 80
|
channel.pipeline().addLast("handler", object : SimpleChannelInboundHandler<FullHttpResponse>() {
|
||||||
}
|
override fun channelRead0(
|
||||||
|
ctx: ChannelHandlerContext,
|
||||||
val bootstrap = Bootstrap()
|
response: FullHttpResponse
|
||||||
bootstrap.group(group)
|
) {
|
||||||
.channel(NioSocketChannel::class.java)
|
responseFuture.complete(response)
|
||||||
.handler(object : ChannelInitializer<SocketChannel>() {
|
pipeline.removeLast()
|
||||||
override fun initChannel(ch: SocketChannel) {
|
pool.release(channel)
|
||||||
val pipeline: ChannelPipeline = ch.pipeline()
|
|
||||||
|
|
||||||
|
|
||||||
// Add SSL handler if needed
|
|
||||||
if ("https".equals(scheme, ignoreCase = true)) {
|
|
||||||
pipeline.addLast("ssl", sslContext.newHandler(ch.alloc(), host, port))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP handlers
|
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
|
||||||
pipeline.addLast("codec", HttpClientCodec())
|
val ex = when (cause) {
|
||||||
pipeline.addLast("decompressor", HttpContentDecompressor())
|
is DecoderException -> cause.cause
|
||||||
pipeline.addLast("aggregator", HttpObjectAggregator(1048576))
|
else -> cause
|
||||||
pipeline.addLast("chunked", ChunkedWriteHandler())
|
|
||||||
|
|
||||||
|
|
||||||
// Custom handler for processing responses
|
|
||||||
pipeline.addLast("handler", object : SimpleChannelInboundHandler<FullHttpResponse>() {
|
|
||||||
override fun channelRead0(
|
|
||||||
ctx: ChannelHandlerContext,
|
|
||||||
response: FullHttpResponse
|
|
||||||
) {
|
|
||||||
responseFuture.complete(response)
|
|
||||||
ctx.close()
|
|
||||||
}
|
}
|
||||||
|
responseFuture.completeExceptionally(ex)
|
||||||
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
|
ctx.close()
|
||||||
val ex = when (cause) {
|
pipeline.removeLast()
|
||||||
is DecoderException -> cause.cause
|
pool.release(channel)
|
||||||
else -> cause
|
}
|
||||||
|
})
|
||||||
|
// Prepare the HTTP request
|
||||||
|
val request: FullHttpRequest = let {
|
||||||
|
val content: ByteBuf? = body?.takeIf(ByteArray::isNotEmpty)?.let(Unpooled::wrappedBuffer)
|
||||||
|
DefaultFullHttpRequest(
|
||||||
|
HttpVersion.HTTP_1_1,
|
||||||
|
method,
|
||||||
|
uri.rawPath,
|
||||||
|
content ?: Unpooled.buffer(0)
|
||||||
|
).apply {
|
||||||
|
headers().apply {
|
||||||
|
if (content != null) {
|
||||||
|
set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_OCTET_STREAM)
|
||||||
|
set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes())
|
||||||
|
}
|
||||||
|
set(HttpHeaderNames.HOST, profile.serverURI.host)
|
||||||
|
set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
|
||||||
|
set(
|
||||||
|
HttpHeaderNames.ACCEPT_ENCODING,
|
||||||
|
HttpHeaderValues.GZIP.toString() + "," + HttpHeaderValues.DEFLATE.toString()
|
||||||
|
)
|
||||||
|
// Add basic auth if configured
|
||||||
|
(profile.authentication as? Configuration.Authentication.BasicAuthenticationCredentials)?.let { credentials ->
|
||||||
|
val auth = "${credentials.username}:${credentials.password}"
|
||||||
|
val encodedAuth = Base64.getEncoder().encodeToString(auth.toByteArray())
|
||||||
|
set(HttpHeaderNames.AUTHORIZATION, "Basic $encodedAuth")
|
||||||
}
|
}
|
||||||
responseFuture.completeExceptionally(ex)
|
|
||||||
ctx.close()
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Connect to host
|
|
||||||
val channel: Channel = bootstrap.connect(host, port).sync().channel()
|
|
||||||
|
|
||||||
// Prepare the HTTP request
|
|
||||||
val request: FullHttpRequest = let {
|
|
||||||
val content: ByteBuf? = body?.takeIf(ByteArray::isNotEmpty)?.let(Unpooled::wrappedBuffer)
|
|
||||||
DefaultFullHttpRequest(HttpVersion.HTTP_1_1, method, uri.rawPath, content ?: Unpooled.buffer(0)).apply {
|
|
||||||
headers().apply {
|
|
||||||
if (content != null) {
|
|
||||||
set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_OCTET_STREAM)
|
|
||||||
set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes())
|
|
||||||
}
|
|
||||||
set(HttpHeaderNames.HOST, host)
|
|
||||||
set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
|
|
||||||
set(
|
|
||||||
HttpHeaderNames.ACCEPT_ENCODING,
|
|
||||||
HttpHeaderValues.GZIP.toString() + "," + HttpHeaderValues.DEFLATE.toString()
|
|
||||||
)
|
|
||||||
// Add basic auth if configured
|
|
||||||
(profile.authentication as? Configuration.Authentication.BasicAuthenticationCredentials)?.let { credentials ->
|
|
||||||
val auth = "${credentials.username}:${credentials.password}"
|
|
||||||
val encodedAuth = Base64.getEncoder().encodeToString(auth.toByteArray())
|
|
||||||
set(HttpHeaderNames.AUTHORIZATION, "Basic $encodedAuth")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set headers
|
||||||
|
// Send the request
|
||||||
|
channel.writeAndFlush(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
// Set headers
|
|
||||||
// Send the request
|
|
||||||
channel.writeAndFlush(request)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
responseFuture.completeExceptionally(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseFuture
|
return responseFuture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,38 +0,0 @@
|
|||||||
package net.woggioni.gbcs.client
|
|
||||||
import java.net.URI
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.security.KeyStore
|
|
||||||
import java.security.PrivateKey
|
|
||||||
import java.security.cert.X509Certificate
|
|
||||||
import kotlin.random.Random
|
|
||||||
|
|
||||||
|
|
||||||
//object Main {
|
|
||||||
// @JvmStatic
|
|
||||||
// fun main(vararg args : String) {
|
|
||||||
// val pwd = "PO%!*bW9p'Zp#=uu\$fl{Ij`Ad.8}x#ho".toCharArray()
|
|
||||||
// val keystore = KeyStore.getInstance("PKCS12").apply{
|
|
||||||
// Files.newInputStream(Path.of("/home/woggioni/ssl/woggioni@c962475fa38.pfx")).use {
|
|
||||||
// load(it, pwd)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// val key = keystore.getKey("woggioni@c962475fa38", pwd) as PrivateKey
|
|
||||||
// val certChain = keystore.getCertificateChain("woggioni@c962475fa38").asSequence()
|
|
||||||
// .map { it as X509Certificate }
|
|
||||||
// .toList()
|
|
||||||
// .toTypedArray()
|
|
||||||
// GbcsClient.Configuration(
|
|
||||||
// serverURI = URI("https://gbcs.woggioni.net/"),
|
|
||||||
// GbcsClient.TlsClientAuthenticationCredentials(
|
|
||||||
// key, certChain
|
|
||||||
// )
|
|
||||||
// ).let(::GbcsClient).use { client ->
|
|
||||||
// val random = Random(101325)
|
|
||||||
// val entry = "something" to ByteArray(0x1000).also(random::nextBytes)
|
|
||||||
// client.put(entry.first, entry.second)
|
|
||||||
// val retrieved = client.get(entry.first).get()
|
|
||||||
// println(retrieved.contentEquals(entry.second))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
@@ -55,7 +55,11 @@ object Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profiles[name] = GbcsClient.Configuration.Profile(uri, authentication)
|
val maxConnections = child.getAttribute("max-connections")
|
||||||
|
.takeIf(String::isNotEmpty)
|
||||||
|
?.let(String::toInt)
|
||||||
|
?: 50
|
||||||
|
profiles[name] = GbcsClient.Configuration.Profile(uri, authentication, maxConnections)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
</xs:choice>
|
</xs:choice>
|
||||||
<xs:attribute name="name" type="xs:token" use="required"/>
|
<xs:attribute name="name" type="xs:token" use="required"/>
|
||||||
<xs:attribute name="base-url" type="xs:anyURI" use="required"/>
|
<xs:attribute name="base-url" type="xs:anyURI" use="required"/>
|
||||||
|
<xs:attribute name="max-connections" type="xs:positiveInteger" default="50"/>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
<xs:complexType name="basicAuthType">
|
<xs:complexType name="basicAuthType">
|
||||||
|
@@ -1,6 +1,3 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'java-library'
|
id 'java-library'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package net.woggioni.gbcs.memcached
|
package net.woggioni.gbcs.memcached
|
||||||
|
|
||||||
import net.rubyeye.xmemcached.MemcachedClient
|
|
||||||
import net.rubyeye.xmemcached.XMemcachedClientBuilder
|
import net.rubyeye.xmemcached.XMemcachedClientBuilder
|
||||||
import net.rubyeye.xmemcached.command.BinaryCommandFactory
|
import net.rubyeye.xmemcached.command.BinaryCommandFactory
|
||||||
import net.rubyeye.xmemcached.transcoders.CompressionMode
|
import net.rubyeye.xmemcached.transcoders.CompressionMode
|
||||||
|
@@ -16,7 +16,6 @@ import net.woggioni.gbcs.base.Xml.Companion.asIterable
|
|||||||
import org.w3c.dom.Document
|
import org.w3c.dom.Document
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.TypeInfo
|
import org.w3c.dom.TypeInfo
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
object Parser {
|
object Parser {
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package net.woggioni.gbcs.test
|
package net.woggioni.gbcs.test
|
||||||
|
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
|
||||||
import net.woggioni.gbcs.api.Configuration
|
import net.woggioni.gbcs.api.Configuration
|
||||||
import net.woggioni.gbcs.api.Role
|
import net.woggioni.gbcs.api.Role
|
||||||
import net.woggioni.gbcs.base.Xml
|
import net.woggioni.gbcs.base.Xml
|
||||||
@@ -10,13 +9,9 @@ import net.woggioni.gbcs.utils.CertificateUtils
|
|||||||
import net.woggioni.gbcs.utils.CertificateUtils.X509Credentials
|
import net.woggioni.gbcs.utils.CertificateUtils.X509Credentials
|
||||||
import net.woggioni.gbcs.utils.NetworkUtils
|
import net.woggioni.gbcs.utils.NetworkUtils
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.junit.jupiter.api.Assertions
|
|
||||||
import org.junit.jupiter.api.Order
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.http.HttpClient
|
import java.net.http.HttpClient
|
||||||
import java.net.http.HttpRequest
|
import java.net.http.HttpRequest
|
||||||
import java.net.http.HttpResponse
|
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
@@ -2,7 +2,6 @@ package net.woggioni.gbcs.test
|
|||||||
|
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
import io.netty.handler.codec.http.HttpResponseStatus
|
||||||
import net.woggioni.gbcs.api.Configuration
|
import net.woggioni.gbcs.api.Configuration
|
||||||
import net.woggioni.gbcs.api.Role
|
|
||||||
import net.woggioni.gbcs.base.PasswordSecurity.hashPassword
|
import net.woggioni.gbcs.base.PasswordSecurity.hashPassword
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Order
|
import org.junit.jupiter.api.Order
|
||||||
|
@@ -1,15 +1,14 @@
|
|||||||
package net.woggioni.gbcs.test
|
package net.woggioni.gbcs.test
|
||||||
|
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
import io.netty.handler.codec.http.HttpResponseStatus
|
||||||
import net.woggioni.gbcs.base.Xml
|
|
||||||
import net.woggioni.gbcs.api.Configuration
|
import net.woggioni.gbcs.api.Configuration
|
||||||
|
import net.woggioni.gbcs.base.Xml
|
||||||
import net.woggioni.gbcs.cache.FileSystemCacheConfiguration
|
import net.woggioni.gbcs.cache.FileSystemCacheConfiguration
|
||||||
import net.woggioni.gbcs.configuration.Serializer
|
import net.woggioni.gbcs.configuration.Serializer
|
||||||
import net.woggioni.gbcs.utils.NetworkUtils
|
import net.woggioni.gbcs.utils.NetworkUtils
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Order
|
import org.junit.jupiter.api.Order
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import java.net.ServerSocket
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.http.HttpClient
|
import java.net.http.HttpClient
|
||||||
import java.net.http.HttpRequest
|
import java.net.http.HttpRequest
|
||||||
|
@@ -3,33 +3,13 @@ package net.woggioni.gbcs.test
|
|||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
import io.netty.handler.codec.http.HttpResponseStatus
|
||||||
import net.woggioni.gbcs.api.Configuration
|
import net.woggioni.gbcs.api.Configuration
|
||||||
import net.woggioni.gbcs.api.Role
|
import net.woggioni.gbcs.api.Role
|
||||||
import net.woggioni.gbcs.base.Xml
|
|
||||||
import net.woggioni.gbcs.cache.FileSystemCacheConfiguration
|
|
||||||
import net.woggioni.gbcs.configuration.Serializer
|
|
||||||
import net.woggioni.gbcs.utils.CertificateUtils
|
|
||||||
import net.woggioni.gbcs.utils.CertificateUtils.X509Credentials
|
|
||||||
import net.woggioni.gbcs.utils.NetworkUtils
|
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Order
|
import org.junit.jupiter.api.Order
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import java.net.ServerSocket
|
|
||||||
import java.net.URI
|
|
||||||
import java.net.http.HttpClient
|
import java.net.http.HttpClient
|
||||||
import java.net.http.HttpRequest
|
import java.net.http.HttpRequest
|
||||||
import java.net.http.HttpResponse
|
import java.net.http.HttpResponse
|
||||||
import java.nio.charset.StandardCharsets
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.security.KeyStore
|
|
||||||
import java.security.KeyStore.PasswordProtection
|
|
||||||
import java.time.Duration
|
|
||||||
import java.util.Base64
|
|
||||||
import java.util.zip.Deflater
|
|
||||||
import javax.net.ssl.KeyManagerFactory
|
|
||||||
import javax.net.ssl.SSLContext
|
|
||||||
import javax.net.ssl.TrustManagerFactory
|
|
||||||
import kotlin.random.Random
|
|
||||||
|
|
||||||
|
|
||||||
class TlsServerTest : AbstractTlsServerTest() {
|
class TlsServerTest : AbstractTlsServerTest() {
|
||||||
|
Reference in New Issue
Block a user