added healthcheck role
improved documentation client configuration promoted to standalone class
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package net.woggioni.rbcs.client
|
||||
|
||||
import net.woggioni.rbcs.client.impl.Parser
|
||||
import net.woggioni.rbcs.common.Xml
|
||||
import java.net.URI
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.security.PrivateKey
|
||||
import java.security.cert.X509Certificate
|
||||
import java.time.Duration
|
||||
|
||||
data class Configuration(
|
||||
val profiles: Map<String, Profile>
|
||||
) {
|
||||
sealed class Authentication {
|
||||
data class TlsClientAuthenticationCredentials(
|
||||
val key: PrivateKey,
|
||||
val certificateChain: Array<X509Certificate>
|
||||
) : Authentication()
|
||||
|
||||
data class BasicAuthenticationCredentials(val username: String, val password: String) : Authentication()
|
||||
}
|
||||
|
||||
class TrustStore (
|
||||
var file: Path?,
|
||||
var password: String?,
|
||||
var checkCertificateStatus: Boolean = false,
|
||||
var verifyServerCertificate: Boolean = true,
|
||||
)
|
||||
|
||||
class RetryPolicy(
|
||||
val maxAttempts: Int,
|
||||
val initialDelayMillis: Long,
|
||||
val exp: Double
|
||||
)
|
||||
|
||||
class Connection(
|
||||
val readIdleTimeout: Duration,
|
||||
val writeIdleTimeout: Duration,
|
||||
val idleTimeout: Duration,
|
||||
)
|
||||
|
||||
data class Profile(
|
||||
val serverURI: URI,
|
||||
val connection: Connection?,
|
||||
val authentication: Authentication?,
|
||||
val connectionTimeout: Duration?,
|
||||
val maxConnections: Int,
|
||||
val compressionEnabled: Boolean,
|
||||
val retryPolicy: RetryPolicy?,
|
||||
val tlsTruststore : TrustStore?
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun parse(path: Path): Configuration {
|
||||
return Files.newInputStream(path).use {
|
||||
Xml.parseXml(path.toUri().toURL(), it)
|
||||
}.let(Parser::parse)
|
||||
}
|
||||
}
|
||||
}
|
@@ -36,20 +36,14 @@ import io.netty.handler.timeout.IdleStateHandler
|
||||
import io.netty.util.concurrent.Future
|
||||
import io.netty.util.concurrent.GenericFutureListener
|
||||
import net.woggioni.rbcs.api.CacheValueMetadata
|
||||
import net.woggioni.rbcs.client.impl.Parser
|
||||
import net.woggioni.rbcs.common.RBCS.loadKeystore
|
||||
import net.woggioni.rbcs.common.Xml
|
||||
import net.woggioni.rbcs.common.createLogger
|
||||
import net.woggioni.rbcs.common.debug
|
||||
import net.woggioni.rbcs.common.trace
|
||||
import java.io.IOException
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.URI
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.security.PrivateKey
|
||||
import java.security.cert.X509Certificate
|
||||
import java.time.Duration
|
||||
import java.util.Base64
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -69,59 +63,6 @@ class RemoteBuildCacheClient(private val profile: Configuration.Profile) : AutoC
|
||||
private val sslContext: SslContext
|
||||
private val pool: ChannelPool
|
||||
|
||||
data class Configuration(
|
||||
val profiles: Map<String, Profile>
|
||||
) {
|
||||
sealed class Authentication {
|
||||
data class TlsClientAuthenticationCredentials(
|
||||
val key: PrivateKey,
|
||||
val certificateChain: Array<X509Certificate>
|
||||
) : Authentication()
|
||||
|
||||
data class BasicAuthenticationCredentials(val username: String, val password: String) : Authentication()
|
||||
}
|
||||
|
||||
class TrustStore (
|
||||
var file: Path?,
|
||||
var password: String?,
|
||||
var checkCertificateStatus: Boolean = false,
|
||||
var verifyServerCertificate: Boolean = true,
|
||||
)
|
||||
|
||||
class RetryPolicy(
|
||||
val maxAttempts: Int,
|
||||
val initialDelayMillis: Long,
|
||||
val exp: Double
|
||||
)
|
||||
|
||||
class Connection(
|
||||
val readTimeout: Duration,
|
||||
val writeTimeout: Duration,
|
||||
val idleTimeout: Duration,
|
||||
val readIdleTimeout: Duration,
|
||||
val writeIdleTimeout: Duration
|
||||
)
|
||||
|
||||
data class Profile(
|
||||
val serverURI: URI,
|
||||
val connection: Connection?,
|
||||
val authentication: Authentication?,
|
||||
val connectionTimeout: Duration?,
|
||||
val maxConnections: Int,
|
||||
val compressionEnabled: Boolean,
|
||||
val retryPolicy: RetryPolicy?,
|
||||
val tlsTruststore : TrustStore?
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun parse(path: Path): Configuration {
|
||||
return Files.newInputStream(path).use {
|
||||
Xml.parseXml(path.toUri().toURL(), it)
|
||||
}.let(Parser::parse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
group = NioEventLoopGroup()
|
||||
sslContext = SslContextBuilder.forClient().also { builder ->
|
||||
@@ -212,19 +153,6 @@ class RemoteBuildCacheClient(private val profile: Configuration.Profile) : AutoC
|
||||
val pipeline: ChannelPipeline = ch.pipeline()
|
||||
|
||||
profile.connection?.also { conn ->
|
||||
val readTimeout = conn.readTimeout.toMillis()
|
||||
val writeTimeout = conn.writeTimeout.toMillis()
|
||||
if (readTimeout > 0 || writeTimeout > 0) {
|
||||
pipeline.addLast(
|
||||
IdleStateHandler(
|
||||
false,
|
||||
readTimeout,
|
||||
writeTimeout,
|
||||
0,
|
||||
TimeUnit.MILLISECONDS
|
||||
)
|
||||
)
|
||||
}
|
||||
val readIdleTimeout = conn.readIdleTimeout.toMillis()
|
||||
val writeIdleTimeout = conn.writeIdleTimeout.toMillis()
|
||||
val idleTimeout = conn.idleTimeout.toMillis()
|
@@ -1,7 +1,7 @@
|
||||
package net.woggioni.rbcs.client.impl
|
||||
|
||||
import net.woggioni.rbcs.api.exception.ConfigurationException
|
||||
import net.woggioni.rbcs.client.RemoteBuildCacheClient
|
||||
import net.woggioni.rbcs.client.Configuration
|
||||
import net.woggioni.rbcs.common.Xml.Companion.asIterable
|
||||
import net.woggioni.rbcs.common.Xml.Companion.renderAttribute
|
||||
import org.w3c.dom.Document
|
||||
@@ -16,9 +16,9 @@ import java.time.temporal.ChronoUnit
|
||||
|
||||
object Parser {
|
||||
|
||||
fun parse(document: Document): RemoteBuildCacheClient.Configuration {
|
||||
fun parse(document: Document): Configuration {
|
||||
val root = document.documentElement
|
||||
val profiles = mutableMapOf<String, RemoteBuildCacheClient.Configuration.Profile>()
|
||||
val profiles = mutableMapOf<String, Configuration.Profile>()
|
||||
|
||||
for (child in root.asIterable()) {
|
||||
val tagName = child.localName
|
||||
@@ -28,10 +28,10 @@ object Parser {
|
||||
child.renderAttribute("name") ?: throw ConfigurationException("name attribute is required")
|
||||
val uri = child.renderAttribute("base-url")?.let(::URI)
|
||||
?: throw ConfigurationException("base-url attribute is required")
|
||||
var authentication: RemoteBuildCacheClient.Configuration.Authentication? = null
|
||||
var retryPolicy: RemoteBuildCacheClient.Configuration.RetryPolicy? = null
|
||||
var connection : RemoteBuildCacheClient.Configuration.Connection? = null
|
||||
var trustStore : RemoteBuildCacheClient.Configuration.TrustStore? = null
|
||||
var authentication: Configuration.Authentication? = null
|
||||
var retryPolicy: Configuration.RetryPolicy? = null
|
||||
var connection : Configuration.Connection? = null
|
||||
var trustStore : Configuration.TrustStore? = null
|
||||
for (gchild in child.asIterable()) {
|
||||
when (gchild.localName) {
|
||||
"tls-client-auth" -> {
|
||||
@@ -52,7 +52,7 @@ object Parser {
|
||||
.toList()
|
||||
.toTypedArray()
|
||||
authentication =
|
||||
RemoteBuildCacheClient.Configuration.Authentication.TlsClientAuthenticationCredentials(
|
||||
Configuration.Authentication.TlsClientAuthenticationCredentials(
|
||||
key,
|
||||
certChain
|
||||
)
|
||||
@@ -64,7 +64,7 @@ object Parser {
|
||||
val password = gchild.renderAttribute("password")
|
||||
?: throw ConfigurationException("password attribute is required")
|
||||
authentication =
|
||||
RemoteBuildCacheClient.Configuration.Authentication.BasicAuthenticationCredentials(
|
||||
Configuration.Authentication.BasicAuthenticationCredentials(
|
||||
username,
|
||||
password
|
||||
)
|
||||
@@ -83,7 +83,7 @@ object Parser {
|
||||
gchild.renderAttribute("exp")
|
||||
?.let(String::toDouble)
|
||||
?: 2.0f
|
||||
retryPolicy = RemoteBuildCacheClient.Configuration.RetryPolicy(
|
||||
retryPolicy = Configuration.RetryPolicy(
|
||||
maxAttempts,
|
||||
initialDelay.toMillis(),
|
||||
exp.toDouble()
|
||||
@@ -91,22 +91,16 @@ object Parser {
|
||||
}
|
||||
|
||||
"connection" -> {
|
||||
val writeTimeout = gchild.renderAttribute("write-timeout")
|
||||
?.let(Duration::parse) ?: Duration.of(0, ChronoUnit.SECONDS)
|
||||
val readTimeout = gchild.renderAttribute("read-timeout")
|
||||
?.let(Duration::parse) ?: Duration.of(0, ChronoUnit.SECONDS)
|
||||
val idleTimeout = gchild.renderAttribute("idle-timeout")
|
||||
?.let(Duration::parse) ?: Duration.of(30, ChronoUnit.SECONDS)
|
||||
val readIdleTimeout = gchild.renderAttribute("read-idle-timeout")
|
||||
?.let(Duration::parse) ?: Duration.of(60, ChronoUnit.SECONDS)
|
||||
val writeIdleTimeout = gchild.renderAttribute("write-idle-timeout")
|
||||
?.let(Duration::parse) ?: Duration.of(60, ChronoUnit.SECONDS)
|
||||
connection = RemoteBuildCacheClient.Configuration.Connection(
|
||||
readTimeout,
|
||||
writeTimeout,
|
||||
idleTimeout,
|
||||
connection = Configuration.Connection(
|
||||
readIdleTimeout,
|
||||
writeIdleTimeout,
|
||||
idleTimeout,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -118,7 +112,7 @@ object Parser {
|
||||
?.let(String::toBoolean) ?: false
|
||||
val verifyServerCertificate = gchild.renderAttribute("verify-server-certificate")
|
||||
?.let(String::toBoolean) ?: true
|
||||
trustStore = RemoteBuildCacheClient.Configuration.TrustStore(file, password, checkCertificateStatus, verifyServerCertificate)
|
||||
trustStore = Configuration.TrustStore(file, password, checkCertificateStatus, verifyServerCertificate)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,7 +125,7 @@ object Parser {
|
||||
?.let(String::toBoolean)
|
||||
?: true
|
||||
|
||||
profiles[name] = RemoteBuildCacheClient.Configuration.Profile(
|
||||
profiles[name] = Configuration.Profile(
|
||||
uri,
|
||||
connection,
|
||||
authentication,
|
||||
@@ -144,6 +138,6 @@ object Parser {
|
||||
}
|
||||
}
|
||||
}
|
||||
return RemoteBuildCacheClient.Configuration(profiles)
|
||||
return Configuration(profiles)
|
||||
}
|
||||
}
|
@@ -15,75 +15,237 @@
|
||||
<xs:complexType name="profileType">
|
||||
<xs:sequence>
|
||||
<xs:choice>
|
||||
<xs:element name="no-auth" type="rbcs-client:noAuthType"/>
|
||||
<xs:element name="basic-auth" type="rbcs-client:basicAuthType"/>
|
||||
<xs:element name="tls-client-auth" type="rbcs-client:tlsClientAuthType"/>
|
||||
<xs:element name="no-auth" type="rbcs-client:noAuthType">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Disable authentication.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="basic-auth" type="rbcs-client:basicAuthType">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Enable HTTP basic authentication.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="tls-client-auth" type="rbcs-client:tlsClientAuthType">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Enable TLS certificate authentication.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:choice>
|
||||
<xs:element name="connection" type="rbcs-client:connectionType" minOccurs="0" />
|
||||
<xs:element name="retry-policy" type="rbcs-client:retryType" minOccurs="0"/>
|
||||
<xs:element name="tls-trust-store" type="rbcs-client:trustStoreType" minOccurs="0"/>
|
||||
<xs:element name="connection" type="rbcs-client:connectionType" minOccurs="0" >
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Set inactivity timeouts for connections to this server,
|
||||
if not present, connections are only closed on network errors.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="retry-policy" type="rbcs-client:retryType" minOccurs="0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Set a retry policy for this server, if not present requests won't be retried
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="tls-trust-store" type="rbcs-client:trustStoreType" minOccurs="0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
If set, specify an alternative truststore to validate the server certificate.
|
||||
If not present the system truststore is used.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="name" type="xs:token" use="required"/>
|
||||
<xs:attribute name="base-url" type="xs:anyURI" use="required"/>
|
||||
<xs:attribute name="max-connections" type="xs:positiveInteger" default="50"/>
|
||||
<xs:attribute name="connection-timeout" type="xs:duration"/>
|
||||
<xs:attribute name="enable-compression" type="xs:boolean" default="true"/>
|
||||
<xs:attribute name="name" type="xs:token" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Name of this server profile, to be referred to from rbcs-cli with the '-p' parameter
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="base-url" type="xs:anyURI" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
RBCs server URL
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="max-connections" type="xs:positiveInteger" default="50">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Maximum number of concurrent TCP connection to open with this server
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="connection-timeout" type="xs:duration">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Enable HTTP compression when communicating to this server
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="enable-compression" type="xs:boolean" default="true">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Enable HTTP compression when communicating to this server
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="connectionType">
|
||||
<xs:attribute name="read-timeout" type="xs:duration" use="optional" default="PT0S"/>
|
||||
<xs:attribute name="write-timeout" type="xs:duration" use="optional" default="PT0S"/>
|
||||
<xs:attribute name="idle-timeout" type="xs:duration" use="optional" default="PT30S"/>
|
||||
<xs:attribute name="read-idle-timeout" type="xs:duration" use="optional" default="PT60S"/>
|
||||
<xs:attribute name="write-idle-timeout" type="xs:duration" use="optional" default="PT60S"/>
|
||||
<xs:attribute name="idle-timeout" type="xs:duration" use="optional" default="PT30S">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The client will close the connection with the server
|
||||
when neither a read nor a write was performed for the specified period of time.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="read-idle-timeout" type="xs:duration" use="optional" default="PT60S">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The client will close the connection with the server
|
||||
when no read was performed for the specified period of time.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="write-idle-timeout" type="xs:duration" use="optional" default="PT60S">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The client will close the connection with the server
|
||||
when no write was performed for the specified period of time.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="noAuthType"/>
|
||||
<xs:complexType name="noAuthType">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Add this tag to not use any type of authentication when talking to the RBCS server
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="basicAuthType">
|
||||
<xs:attribute name="user" type="xs:token" use="required"/>
|
||||
<xs:attribute name="password" type="xs:string" use="required"/>
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Add this tag to enable HTTP basic authentication for the communication to this server,
|
||||
mind that HTTP basic authentication sends credentials directly over the network, so make sure
|
||||
your communication is protected by TLS (i.e. your server's URL starts with "https")
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:attribute name="user" type="xs:token" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Username for HTTP basic authentication
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="password" type="xs:string" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Password used for HTTP basic authentication
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="tlsClientAuthType">
|
||||
<xs:attribute name="key-store-file" type="xs:anyURI" use="required"/>
|
||||
<xs:attribute name="key-store-password" type="xs:string" use="required"/>
|
||||
<xs:attribute name="key-alias" type="xs:token" use="required"/>
|
||||
<xs:attribute name="key-password" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="key-store-file" type="xs:anyURI" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
System path to the keystore file
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="key-store-password" type="xs:string" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Password to open they keystore file
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="key-alias" type="xs:token" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Alias of the keystore entry containing the private key
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="key-password" type="xs:string" use="optional">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Private key entry's encryption password
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="retryType">
|
||||
<xs:attribute name="max-attempts" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="initial-delay" type="xs:duration" default="PT1S"/>
|
||||
<xs:attribute name="exp" type="xs:double" default="2.0"/>
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Retry policy to use in case of failures, based on exponential backoff
|
||||
https://en.wikipedia.org/wiki/Exponential_backoff
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:attribute name="max-attempts" type="xs:positiveInteger" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Maximum number of attempts, after which the call will result in an error,
|
||||
throwing an exception related to the last received failure
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="initial-delay" type="xs:duration" default="PT1S">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Delay to apply before retrying after the first failed call
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="exp" type="xs:double" default="2.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Exponent to apply to compute the next delay
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="trustStoreType">
|
||||
<xs:attribute name="file" type="xs:string" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Path to the trustore file
|
||||
Path to the truststore file
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="password" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Trustore file password
|
||||
Truststore file password
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="check-certificate-status" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Whether or not check the certificate validity using CRL/OCSP
|
||||
Whether or not check the server certificate validity using CRL/OCSP
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="verify-server-certificate" type="xs:boolean" use="optional" default="true">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
If false, the client will blindly trust the provided server certificate
|
||||
If false, the client will blindly trust the certificate provided by the server
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
|
Reference in New Issue
Block a user