mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
ENT-11351 - Compiler warnings pass 1 (#7652)
* Removed warnings - pass 1 * Resolve detekt errors * Properly compare X500 distinguished names
This commit is contained in:
parent
c07b3906aa
commit
1ff853b421
@ -26,7 +26,7 @@ class StringToMethodCallParserTest {
|
|||||||
"simple" to "simple",
|
"simple" to "simple",
|
||||||
"string noteTextWord: A test of barewords" to "A test of barewords",
|
"string noteTextWord: A test of barewords" to "A test of barewords",
|
||||||
"twoStrings a: Some words, b: ' and some words, like, Kirk, would, speak'" to "Some words and some words, like, Kirk, would, speak",
|
"twoStrings a: Some words, b: ' and some words, like, Kirk, would, speak'" to "Some words and some words, like, Kirk, would, speak",
|
||||||
"simpleObject hash: $randomHash" to randomHash.toUpperCase(),
|
"simpleObject hash: $randomHash" to randomHash.uppercase(Locale.getDefault()),
|
||||||
"complexObject pair: { first: 12, second: Word up brother }" to Pair(12, "Word up brother"),
|
"complexObject pair: { first: 12, second: Word up brother }" to Pair(12, "Word up brother"),
|
||||||
"overload a: A" to "A",
|
"overload a: A" to "A",
|
||||||
"overload a: A, b: B" to "AB"
|
"overload a: A, b: B" to "AB"
|
||||||
|
@ -5,6 +5,7 @@ import net.corda.common.configuration.parsing.internal.versioned.VersionExtracto
|
|||||||
import net.corda.common.validation.internal.Validated
|
import net.corda.common.validation.internal.Validated
|
||||||
import net.corda.common.validation.internal.Validated.Companion.invalid
|
import net.corda.common.validation.internal.Validated.Companion.invalid
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -468,7 +469,7 @@ object Configuration {
|
|||||||
|
|
||||||
fun of(message: String, keyName: String? = null, typeName: String = UNKNOWN, containingPath: List<String> = emptyList()): WrongType = contextualize(keyName ?: UNKNOWN, containingPath).let { (key, path) -> WrongType(key, typeName, message, path) }
|
fun of(message: String, keyName: String? = null, typeName: String = UNKNOWN, containingPath: List<String> = emptyList()): WrongType = contextualize(keyName ?: UNKNOWN, containingPath).let { (key, path) -> WrongType(key, typeName, message, path) }
|
||||||
|
|
||||||
fun forKey(keyName: String, expectedTypeName: String, actualTypeName: String): WrongType = of("$keyName has type ${actualTypeName.toUpperCase()} rather than ${expectedTypeName.toUpperCase()}")
|
fun forKey(keyName: String, expectedTypeName: String, actualTypeName: String): WrongType = of("$keyName has type ${actualTypeName.uppercase(Locale.getDefault())} rather than ${expectedTypeName.uppercase(Locale.getDefault())}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun withContainingPath(vararg containingPath: String) = WrongType(keyName, typeName, message, containingPath.toList())
|
override fun withContainingPath(vararg containingPath: String) = WrongType(keyName, typeName, message, containingPath.toList())
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.common.logging.errorReporting
|
package net.corda.common.logging.errorReporting
|
||||||
|
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report errors that have occurred.
|
* Report errors that have occurred.
|
||||||
@ -12,7 +13,7 @@ import org.slf4j.Logger
|
|||||||
fun Logger.report(error: ErrorCode<*>) = ErrorReporting().getReporter().report(error, this)
|
fun Logger.report(error: ErrorCode<*>) = ErrorReporting().getReporter().report(error, this)
|
||||||
|
|
||||||
internal fun ErrorCode<*>.formatCode() : String {
|
internal fun ErrorCode<*>.formatCode() : String {
|
||||||
val namespaceString = this.code.namespace.toLowerCase().replace("_", "-")
|
val namespaceString = this.code.namespace.lowercase(Locale.getDefault()).replace("_", "-")
|
||||||
val codeString = this.code.toString().toLowerCase().replace("_", "-")
|
val codeString = this.code.toString().lowercase(Locale.getDefault()).replace("_", "-")
|
||||||
return "$namespaceString-$codeString"
|
return "$namespaceString-$codeString"
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
import java.security.Signature
|
import java.security.Signature
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
@ -154,7 +155,8 @@ class EdDSATests {
|
|||||||
val testVectors = listOf(testVector1, testVector2, testVector3, testVector1024, testVectorSHAabc)
|
val testVectors = listOf(testVector1, testVector2, testVector3, testVector1024, testVectorSHAabc)
|
||||||
testVectors.forEach {
|
testVectors.forEach {
|
||||||
val privateKey = EdDSAPrivateKey(EdDSAPrivateKeySpec(it.privateKeyHex.hexToByteArray(), edParams))
|
val privateKey = EdDSAPrivateKey(EdDSAPrivateKeySpec(it.privateKeyHex.hexToByteArray(), edParams))
|
||||||
assertEquals(it.signatureOutputHex, doSign(privateKey, it.messageToSignHex.hexToByteArray()).toHex().toLowerCase())
|
assertEquals(it.signatureOutputHex, doSign(privateKey, it.messageToSignHex.hexToByteArray()).toHex()
|
||||||
|
.lowercase(Locale.getDefault()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test vector for the variant Ed25519ctx, expected to fail.
|
// Test vector for the variant Ed25519ctx, expected to fail.
|
||||||
@ -171,7 +173,8 @@ class EdDSATests {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val privateKey = EdDSAPrivateKey(EdDSAPrivateKeySpec(testVectorEd25519ctx.privateKeyHex.hexToByteArray(), edParams))
|
val privateKey = EdDSAPrivateKey(EdDSAPrivateKeySpec(testVectorEd25519ctx.privateKeyHex.hexToByteArray(), edParams))
|
||||||
assertNotEquals(testVectorEd25519ctx.signatureOutputHex, doSign(privateKey, testVectorEd25519ctx.messageToSignHex.hexToByteArray()).toHex().toLowerCase())
|
assertNotEquals(testVectorEd25519ctx.signatureOutputHex, doSign(privateKey, testVectorEd25519ctx.messageToSignHex.hexToByteArray()).toHex()
|
||||||
|
.lowercase(Locale.getDefault()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A test vector object for digital signature schemes. */
|
/** A test vector object for digital signature schemes. */
|
||||||
|
@ -3,6 +3,7 @@ package net.corda.core.utilities
|
|||||||
import net.corda.core.crypto.AddressFormatException
|
import net.corda.core.crypto.AddressFormatException
|
||||||
import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY
|
import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ class EncodingUtilsTest {
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `decoding lowercase and mixed HEX`() {
|
fun `decoding lowercase and mixed HEX`() {
|
||||||
val testHexStringLowercase = testHexString.toLowerCase()
|
val testHexStringLowercase = testHexString.lowercase(Locale.getDefault())
|
||||||
assertEquals(testHexString.hexToRealString(), testHexStringLowercase.hexToRealString())
|
assertEquals(testHexString.hexToRealString(), testHexStringLowercase.hexToRealString())
|
||||||
|
|
||||||
val testHexStringMixed = testHexString.replace('C', 'c')
|
val testHexStringMixed = testHexString.replace('C', 'c')
|
||||||
|
@ -74,6 +74,7 @@ data class _L_i__ (val listy: List<_i_>)
|
|||||||
|
|
||||||
data class _ALd_ (val a: Array<List<Double>>)
|
data class _ALd_ (val a: Array<List<Double>>)
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun main (args: Array<String>) {
|
fun main (args: Array<String>) {
|
||||||
initialiseSerialization()
|
initialiseSerialization()
|
||||||
val path = "../cpp-serializer/bin/test-files";
|
val path = "../cpp-serializer/bin/test-files";
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.internal.uncheckedCast
|
|||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
private class PrettyPrint(arr : Arrangement) {
|
private class PrettyPrint(arr : Arrangement) {
|
||||||
val parties = involvedParties(arr)
|
val parties = involvedParties(arr)
|
||||||
@ -46,10 +47,10 @@ private class PrettyPrint(arr : Arrangement) {
|
|||||||
val usedPartyNames = mutableSetOf<String>()
|
val usedPartyNames = mutableSetOf<String>()
|
||||||
|
|
||||||
fun createPartyName(party : Party): String {
|
fun createPartyName(party : Party): String {
|
||||||
val parts = party.name.organisation.toLowerCase().split(' ')
|
val parts = party.name.organisation.lowercase(Locale.getDefault()).split(' ')
|
||||||
|
|
||||||
var camelName = parts.drop(1).fold(parts.first()) {
|
var camelName = parts.drop(1).fold(parts.first()) {
|
||||||
s, i -> s + i.first().toUpperCase() + i.drop(1)
|
s, i -> s + i.first().uppercaseChar() + i.drop(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usedPartyNames.contains(camelName)) {
|
if (usedPartyNames.contains(camelName)) {
|
||||||
|
@ -67,8 +67,8 @@ internal class AMQPChannelHandler(private val serverMode: Boolean,
|
|||||||
try {
|
try {
|
||||||
MDC.put("serverMode", serverMode.toString())
|
MDC.put("serverMode", serverMode.toString())
|
||||||
MDC.put("remoteAddress", if (::remoteAddress.isInitialized) remoteAddress.toString() else null)
|
MDC.put("remoteAddress", if (::remoteAddress.isInitialized) remoteAddress.toString() else null)
|
||||||
MDC.put("localCert", localCert?.subjectDN?.toString())
|
MDC.put("localCert", localCert?.getSubjectX500Principal()?.toString())
|
||||||
MDC.put("remoteCert", remoteCert?.subjectDN?.toString())
|
MDC.put("remoteCert", remoteCert?.getSubjectX500Principal()?.toString())
|
||||||
MDC.put("allowedRemoteLegalNames", allowedRemoteLegalNames?.joinToString(separator = ";") { it.toString() })
|
MDC.put("allowedRemoteLegalNames", allowedRemoteLegalNames?.joinToString(separator = ";") { it.toString() })
|
||||||
block()
|
block()
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -5,6 +5,6 @@ import java.security.cert.X509Certificate
|
|||||||
|
|
||||||
data class ConnectionChange(val remoteAddress: InetSocketAddress, val remoteCert: X509Certificate?, val connected: Boolean, val connectionResult: ConnectionResult) {
|
data class ConnectionChange(val remoteAddress: InetSocketAddress, val remoteCert: X509Certificate?, val connected: Boolean, val connectionResult: ConnectionResult) {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "ConnectionChange remoteAddress: $remoteAddress connected state: $connected cert subject: ${remoteCert?.subjectDN} result: ${connectionResult}"
|
return "ConnectionChange remoteAddress: $remoteAddress connected state: $connected cert subject: ${remoteCert?.getSubjectX500Principal()} result: ${connectionResult}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.corda.nodeapi.internal.protonwrapper.netty
|
|||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import net.corda.nodeapi.internal.config.ConfigParser
|
import net.corda.nodeapi.internal.config.ConfigParser
|
||||||
import net.corda.nodeapi.internal.config.CustomConfigParser
|
import net.corda.nodeapi.internal.config.CustomConfigParser
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data structure for controlling the way how Certificate Revocation Lists are handled.
|
* Data structure for controlling the way how Certificate Revocation Lists are handled.
|
||||||
@ -58,7 +59,7 @@ class RevocationConfigParser : ConfigParser<RevocationConfig> {
|
|||||||
require(allKeys.size == 1 && allKeys.contains(oneAndTheOnly)) {"For RevocationConfig, it is expected to have '$oneAndTheOnly' property only. " +
|
require(allKeys.size == 1 && allKeys.contains(oneAndTheOnly)) {"For RevocationConfig, it is expected to have '$oneAndTheOnly' property only. " +
|
||||||
"Actual set of properties: $allKeys. Please check 'revocationConfig' section."}
|
"Actual set of properties: $allKeys. Please check 'revocationConfig' section."}
|
||||||
val mode = config.getString(oneAndTheOnly)
|
val mode = config.getString(oneAndTheOnly)
|
||||||
return when (mode.toUpperCase()) {
|
return when (mode.uppercase(Locale.getDefault())) {
|
||||||
"SOFT_FAIL" -> RevocationConfigImpl(RevocationConfig.Mode.SOFT_FAIL)
|
"SOFT_FAIL" -> RevocationConfigImpl(RevocationConfig.Mode.SOFT_FAIL)
|
||||||
"HARD_FAIL" -> RevocationConfigImpl(RevocationConfig.Mode.HARD_FAIL)
|
"HARD_FAIL" -> RevocationConfigImpl(RevocationConfig.Mode.HARD_FAIL)
|
||||||
"EXTERNAL_SOURCE" -> RevocationConfigImpl(RevocationConfig.Mode.EXTERNAL_SOURCE, null) // null for now till `enrichExternalCrlSource` is called
|
"EXTERNAL_SOURCE" -> RevocationConfigImpl(RevocationConfig.Mode.EXTERNAL_SOURCE, null) // null for now till `enrichExternalCrlSource` is called
|
||||||
|
@ -40,6 +40,7 @@ import java.security.cert.CertificateException
|
|||||||
import java.security.cert.PKIXBuilderParameters
|
import java.security.cert.PKIXBuilderParameters
|
||||||
import java.security.cert.X509CertSelector
|
import java.security.cert.X509CertSelector
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
import java.util.concurrent.ThreadPoolExecutor
|
import java.util.concurrent.ThreadPoolExecutor
|
||||||
import javax.net.ssl.CertPathTrustManagerParameters
|
import javax.net.ssl.CertPathTrustManagerParameters
|
||||||
@ -349,5 +350,5 @@ internal fun x500toHostName(x500Name: CordaX500Name): String {
|
|||||||
val secureHash = SecureHash.sha256(x500Name.toString())
|
val secureHash = SecureHash.sha256(x500Name.toString())
|
||||||
// RFC 1035 specifies a limit 255 bytes for hostnames with each label being 63 bytes or less. Due to this, the string
|
// RFC 1035 specifies a limit 255 bytes for hostnames with each label being 63 bytes or less. Due to this, the string
|
||||||
// representation of the SHA256 hash is truncated to 32 characters.
|
// representation of the SHA256 hash is truncated to 32 characters.
|
||||||
return String.format(HOSTNAME_FORMAT, secureHash.toString().take(32).toLowerCase())
|
return String.format(HOSTNAME_FORMAT, secureHash.toString().take(32).lowercase(Locale.getDefault()))
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ object InputStreamSerializer : Serializer<InputStream>() {
|
|||||||
chunks.add(chunk)
|
chunks.add(chunk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val flattened = ByteArray(chunks.sumBy { it.size })
|
val flattened = ByteArray(chunks.sumOf { it.size })
|
||||||
var offset = 0
|
var offset = 0
|
||||||
for (chunk in chunks) {
|
for (chunk in chunks) {
|
||||||
System.arraycopy(chunk, 0, flattened, offset, chunk.size)
|
System.arraycopy(chunk, 0, flattened, offset, chunk.size)
|
||||||
|
@ -9,6 +9,7 @@ import net.corda.testing.node.User
|
|||||||
import org.assertj.core.api.Assertions
|
import org.assertj.core.api.Assertions
|
||||||
import org.junit.Assume
|
import org.junit.Assume
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class FlowsExecutionModeRpcTest {
|
class FlowsExecutionModeRpcTest {
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ class FlowsExecutionModeRpcTest {
|
|||||||
fun `persistent state survives node restart`() {
|
fun `persistent state survives node restart`() {
|
||||||
// Temporary disable this test when executed on Windows. It is known to be sporadically failing.
|
// Temporary disable this test when executed on Windows. It is known to be sporadically failing.
|
||||||
// More investigation is needed to establish why.
|
// More investigation is needed to establish why.
|
||||||
Assume.assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win"))
|
Assume.assumeFalse(System.getProperty("os.name").lowercase(Locale.getDefault()).startsWith("win"))
|
||||||
|
|
||||||
val user = User("mark", "dadada", setOf(Permissions.invokeRpc("setFlowsDrainingModeEnabled"), Permissions.invokeRpc("isFlowsDrainingModeEnabled")))
|
val user = User("mark", "dadada", setOf(Permissions.invokeRpc("setFlowsDrainingModeEnabled"), Permissions.invokeRpc("isFlowsDrainingModeEnabled")))
|
||||||
driver(DriverParameters(
|
driver(DriverParameters(
|
||||||
|
@ -27,6 +27,7 @@ import net.corda.testing.node.User
|
|||||||
import org.junit.Assume
|
import org.junit.Assume
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.lang.management.ManagementFactory
|
import java.lang.management.ManagementFactory
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ class NodeStatePersistenceTests {
|
|||||||
fun `persistent state survives node restart without reinitialising database schema`() {
|
fun `persistent state survives node restart without reinitialising database schema`() {
|
||||||
// Temporary disable this test when executed on Windows. It is known to be sporadically failing.
|
// Temporary disable this test when executed on Windows. It is known to be sporadically failing.
|
||||||
// More investigation is needed to establish why.
|
// More investigation is needed to establish why.
|
||||||
Assume.assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win"))
|
Assume.assumeFalse(System.getProperty("os.name").lowercase(Locale.getDefault()).startsWith("win"))
|
||||||
|
|
||||||
val user = User("mark", "dadada", setOf(Permissions.startFlow<SendMessageFlow>(), Permissions.invokeRpc("vaultQuery")))
|
val user = User("mark", "dadada", setOf(Permissions.startFlow<SendMessageFlow>(), Permissions.invokeRpc("vaultQuery")))
|
||||||
val message = Message("Hello world!")
|
val message = Message("Hello world!")
|
||||||
|
@ -127,7 +127,7 @@ class BrokerJaasLoginModule : BaseBrokerJaasLoginModule() {
|
|||||||
ArtemisMessagingComponent.NODE_P2P_USER -> {
|
ArtemisMessagingComponent.NODE_P2P_USER -> {
|
||||||
requireTls(certificates)
|
requireTls(certificates)
|
||||||
CertificateChainCheckPolicy.LeafMustMatch.createCheck(nodeJaasConfig.keyStore, nodeJaasConfig.trustStore).checkCertificateChain(certificates)
|
CertificateChainCheckPolicy.LeafMustMatch.createCheck(nodeJaasConfig.keyStore, nodeJaasConfig.trustStore).checkCertificateChain(certificates)
|
||||||
Pair(certificates.first().subjectDN.name, listOf(RolePrincipal(NODE_P2P_ROLE)))
|
Pair(certificates.first().getSubjectX500Principal().name, listOf(RolePrincipal(NODE_P2P_ROLE)))
|
||||||
}
|
}
|
||||||
ArtemisMessagingComponent.NODE_RPC_USER -> {
|
ArtemisMessagingComponent.NODE_RPC_USER -> {
|
||||||
requireTls(certificates)
|
requireTls(certificates)
|
||||||
@ -141,7 +141,7 @@ class BrokerJaasLoginModule : BaseBrokerJaasLoginModule() {
|
|||||||
CertificateChainCheckPolicy.RootMustMatch
|
CertificateChainCheckPolicy.RootMustMatch
|
||||||
.createCheck(p2pJaasConfig.keyStore, p2pJaasConfig.trustStore)
|
.createCheck(p2pJaasConfig.keyStore, p2pJaasConfig.trustStore)
|
||||||
.checkCertificateChain(certificates)
|
.checkCertificateChain(certificates)
|
||||||
Pair(certificates.first().subjectDN.name, listOf(RolePrincipal(PEER_ROLE)))
|
Pair(certificates.first().getSubjectX500Principal().name, listOf(RolePrincipal(PEER_ROLE)))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
requireNotNull(rpcJaasConfig) { "Attempted to connect as an rpc user to the P2P broker." }
|
requireNotNull(rpcJaasConfig) { "Attempted to connect as an rpc user to the P2P broker." }
|
||||||
|
@ -79,7 +79,7 @@ sealed class CertificateChainCheckPolicy {
|
|||||||
class UsernameMustMatchCommonNameCheck : Check {
|
class UsernameMustMatchCommonNameCheck : Check {
|
||||||
lateinit var username: String
|
lateinit var username: String
|
||||||
override fun checkCertificateChain(theirChain: Array<java.security.cert.X509Certificate>) {
|
override fun checkCertificateChain(theirChain: Array<java.security.cert.X509Certificate>) {
|
||||||
if (!theirChain.any { certificate -> CordaX500Name.parse(certificate.subjectDN.name).commonName == username }) {
|
if (!theirChain.any { certificate -> CordaX500Name.parse(certificate.getSubjectX500Principal().name).commonName == username }) {
|
||||||
throw CertificateException("Client certificate does not match login username.")
|
throw CertificateException("Client certificate does not match login username.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.corda.node.internal.artemis
|
package net.corda.node.internal.artemis
|
||||||
|
|
||||||
|
import net.corda.core.internal.isEquivalentTo
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.PEER_USER
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.PEER_USER
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
||||||
@ -8,6 +9,7 @@ import org.apache.activemq.artemis.core.server.ServerSession
|
|||||||
import org.apache.activemq.artemis.core.server.plugin.ActiveMQServerPlugin
|
import org.apache.activemq.artemis.core.server.plugin.ActiveMQServerPlugin
|
||||||
import org.apache.activemq.artemis.core.transaction.Transaction
|
import org.apache.activemq.artemis.core.transaction.Transaction
|
||||||
import org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage
|
import org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage
|
||||||
|
import javax.security.auth.x500.X500Principal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin to verify the user in the AMQP message header against the user in the authenticated session.
|
* Plugin to verify the user in the AMQP message header against the user in the authenticated session.
|
||||||
@ -32,7 +34,7 @@ class UserValidationPlugin : ActiveMQServerPlugin {
|
|||||||
throw ActiveMQSecurityException("Invalid message type: expected [${AMQPMessage::class.java.name}], got [${message.javaClass.name}]")
|
throw ActiveMQSecurityException("Invalid message type: expected [${AMQPMessage::class.java.name}], got [${message.javaClass.name}]")
|
||||||
}
|
}
|
||||||
val user = message.getStringProperty(Message.HDR_VALIDATED_USER)
|
val user = message.getStringProperty(Message.HDR_VALIDATED_USER)
|
||||||
if (user != null && user != session.validatedUser) {
|
if (user != null && !X500Principal(user).isEquivalentTo(X500Principal(session.validatedUser))) {
|
||||||
throw ActiveMQSecurityException("_AMQ_VALIDATED_USER mismatch: expected [${session.validatedUser}], got [${user}]")
|
throw ActiveMQSecurityException("_AMQ_VALIDATED_USER mismatch: expected [${session.validatedUser}], got [${user}]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import org.apache.shiro.authz.Permission
|
|||||||
import org.apache.shiro.authz.permission.PermissionResolver
|
import org.apache.shiro.authz.permission.PermissionResolver
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KFunction
|
import kotlin.reflect.KFunction
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
@ -54,7 +55,7 @@ internal object RPCPermissionResolver : PermissionResolver {
|
|||||||
private val FLOW_RPC_PERMITTED_START_FLOW_WITH_CLIENT_ID_CALLS = setOf("startFlowWithClientId", "startFlowDynamicWithClientId")
|
private val FLOW_RPC_PERMITTED_START_FLOW_WITH_CLIENT_ID_CALLS = setOf("startFlowWithClientId", "startFlowDynamicWithClientId")
|
||||||
|
|
||||||
override fun resolvePermission(representation: String): Permission {
|
override fun resolvePermission(representation: String): Permission {
|
||||||
when (representation.substringBefore(SEPARATOR).toLowerCase()) {
|
when (representation.substringBefore(SEPARATOR).lowercase(Locale.getDefault())) {
|
||||||
ACTION_INVOKE_RPC -> {
|
ACTION_INVOKE_RPC -> {
|
||||||
val rpcCall = representation.substringAfter(SEPARATOR, "")
|
val rpcCall = representation.substringAfter(SEPARATOR, "")
|
||||||
require(representation.count { it == SEPARATOR } == 1 && rpcCall.isNotEmpty()) { "Malformed permission string" }
|
require(representation.count { it == SEPARATOR } == 1 && rpcCall.isNotEmpty()) { "Malformed permission string" }
|
||||||
@ -90,7 +91,7 @@ internal object RPCPermissionResolver : PermissionResolver {
|
|||||||
* 3. Methods of specific group: InvokeRpc:com.fully.qualified.package.CustomClientRpcOps#READONLY
|
* 3. Methods of specific group: InvokeRpc:com.fully.qualified.package.CustomClientRpcOps#READONLY
|
||||||
*/
|
*/
|
||||||
private fun attemptNewStyleParsing(permAsString: String): Permission {
|
private fun attemptNewStyleParsing(permAsString: String): Permission {
|
||||||
return when(permAsString.substringBefore(NEW_STYLE_SEP).toLowerCase()) {
|
return when(permAsString.substringBefore(NEW_STYLE_SEP).lowercase(Locale.getDefault())) {
|
||||||
ACTION_INVOKE_RPC -> {
|
ACTION_INVOKE_RPC -> {
|
||||||
val interfaceAndMethods = permAsString.substringAfter(NEW_STYLE_SEP, "")
|
val interfaceAndMethods = permAsString.substringAfter(NEW_STYLE_SEP, "")
|
||||||
val interfaceParts = interfaceAndMethods.split(INTERFACE_SEPARATOR)
|
val interfaceParts = interfaceAndMethods.split(INTERFACE_SEPARATOR)
|
||||||
@ -98,7 +99,7 @@ internal object RPCPermissionResolver : PermissionResolver {
|
|||||||
val methodsMap = requireNotNull(cache.get(interfaceParts[0]))
|
val methodsMap = requireNotNull(cache.get(interfaceParts[0]))
|
||||||
{ "Method map for ${interfaceParts[0]} must not be null in the cache. There must have been error processing interface. " +
|
{ "Method map for ${interfaceParts[0]} must not be null in the cache. There must have been error processing interface. " +
|
||||||
"Please look at the error log lines above." }
|
"Please look at the error log lines above." }
|
||||||
val lookupKey = interfaceAndMethods.toLowerCase()
|
val lookupKey = interfaceAndMethods.lowercase(Locale.getDefault())
|
||||||
val methods = requireNotNull(methodsMap[lookupKey]) { "Cannot find record for " +
|
val methods = requireNotNull(methodsMap[lookupKey]) { "Cannot find record for " +
|
||||||
"'$lookupKey' for interface '${interfaceParts[0]}' in $methodsMap. " +
|
"'$lookupKey' for interface '${interfaceParts[0]}' in $methodsMap. " +
|
||||||
"Please check permissions configuration string '$permAsString' matching class representation." }
|
"Please check permissions configuration string '$permAsString' matching class representation." }
|
||||||
@ -171,9 +172,9 @@ internal object RPCPermissionResolver : PermissionResolver {
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val allKey = methodFullName(interfaceClass.java, ACTION_ALL).toLowerCase()
|
val allKey = methodFullName(interfaceClass.java, ACTION_ALL).lowercase(Locale.getDefault())
|
||||||
val methodFullName = methodFullName(method)
|
val methodFullName = methodFullName(method)
|
||||||
return listOf(allKey to methodFullName) + // ALL group
|
return listOf(allKey to methodFullName) + // ALL group
|
||||||
listOf(methodFullName.toLowerCase() to methodFullName) // Full method names individually
|
listOf(methodFullName.lowercase(Locale.getDefault()) to methodFullName) // Full method names individually
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -182,7 +182,7 @@ open class DBTransactionStorage(private val database: CordaPersistence, cacheFac
|
|||||||
|
|
||||||
private fun weighTx(actTx: TxCacheValue?): Int {
|
private fun weighTx(actTx: TxCacheValue?): Int {
|
||||||
if (actTx == null) return 0
|
if (actTx == null) return 0
|
||||||
return TXCACHEVALUE_OVERHEAD_BYTES + actTx.sigs.sumBy { it.size + TRANSACTION_SIGNATURE_OVERHEAD_BYTES } + actTx.txBits.size
|
return TXCACHEVALUE_OVERHEAD_BYTES + actTx.sigs.sumOf { it.size + TRANSACTION_SIGNATURE_OVERHEAD_BYTES } + actTx.txBits.size
|
||||||
}
|
}
|
||||||
|
|
||||||
private val log = contextLogger()
|
private val log = contextLogger()
|
||||||
|
@ -31,6 +31,7 @@ import java.sql.SQLTransientConnectionException
|
|||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.util.Locale
|
||||||
import java.util.Timer
|
import java.util.Timer
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import javax.persistence.PersistenceException
|
import javax.persistence.PersistenceException
|
||||||
@ -726,7 +727,7 @@ private fun <T : Throwable> Throwable?.mentionsThrowable(exceptionType: Class<T>
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val containsMessage = if (errorMessage != null) {
|
val containsMessage = if (errorMessage != null) {
|
||||||
message?.toLowerCase()?.contains(errorMessage) ?: false
|
message?.lowercase(Locale.getDefault())?.contains(errorMessage) ?: false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -82,9 +82,9 @@ abstract class AbstractQueryCriteriaParser<Q : GenericQueryCriteria<Q,P>, in P:
|
|||||||
column as Path<String?>
|
column as Path<String?>
|
||||||
when (columnPredicate.operator) {
|
when (columnPredicate.operator) {
|
||||||
EQUAL -> criteriaBuilder.equal(column, literal)
|
EQUAL -> criteriaBuilder.equal(column, literal)
|
||||||
EQUAL_IGNORE_CASE -> criteriaBuilder.equal(criteriaBuilder.upper(column), literal.toUpperCase())
|
EQUAL_IGNORE_CASE -> criteriaBuilder.equal(criteriaBuilder.upper(column), literal.uppercase(Locale.getDefault()))
|
||||||
NOT_EQUAL -> criteriaBuilder.notEqual(column, literal)
|
NOT_EQUAL -> criteriaBuilder.notEqual(column, literal)
|
||||||
NOT_EQUAL_IGNORE_CASE -> criteriaBuilder.notEqual(criteriaBuilder.upper(column), literal.toUpperCase())
|
NOT_EQUAL_IGNORE_CASE -> criteriaBuilder.notEqual(criteriaBuilder.upper(column), literal.uppercase(Locale.getDefault()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
when (columnPredicate.operator) {
|
when (columnPredicate.operator) {
|
||||||
@ -111,9 +111,9 @@ abstract class AbstractQueryCriteriaParser<Q : GenericQueryCriteria<Q,P>, in P:
|
|||||||
column as Path<String?>
|
column as Path<String?>
|
||||||
return when (columnPredicate.operator) {
|
return when (columnPredicate.operator) {
|
||||||
LIKE -> criteriaBuilder.like(column, columnPredicate.rightLiteral)
|
LIKE -> criteriaBuilder.like(column, columnPredicate.rightLiteral)
|
||||||
LIKE_IGNORE_CASE -> criteriaBuilder.like(criteriaBuilder.upper(column), columnPredicate.rightLiteral.toUpperCase())
|
LIKE_IGNORE_CASE -> criteriaBuilder.like(criteriaBuilder.upper(column), columnPredicate.rightLiteral.uppercase(Locale.getDefault()))
|
||||||
NOT_LIKE -> criteriaBuilder.notLike(column, columnPredicate.rightLiteral)
|
NOT_LIKE -> criteriaBuilder.notLike(column, columnPredicate.rightLiteral)
|
||||||
NOT_LIKE_IGNORE_CASE -> criteriaBuilder.notLike(criteriaBuilder.upper(column), columnPredicate.rightLiteral.toUpperCase())
|
NOT_LIKE_IGNORE_CASE -> criteriaBuilder.notLike(criteriaBuilder.upper(column), columnPredicate.rightLiteral.uppercase(Locale.getDefault()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,9 +126,9 @@ abstract class AbstractQueryCriteriaParser<Q : GenericQueryCriteria<Q,P>, in P:
|
|||||||
literal as Collection<String>
|
literal as Collection<String>
|
||||||
when (columnPredicate.operator) {
|
when (columnPredicate.operator) {
|
||||||
IN -> column.`in`(literal)
|
IN -> column.`in`(literal)
|
||||||
IN_IGNORE_CASE -> criteriaBuilder.upper(column).`in`(literal.map { it.toUpperCase() })
|
IN_IGNORE_CASE -> criteriaBuilder.upper(column).`in`(literal.map { it.uppercase(Locale.getDefault()) })
|
||||||
NOT_IN -> criteriaBuilder.not(column.`in`(literal))
|
NOT_IN -> criteriaBuilder.not(column.`in`(literal))
|
||||||
NOT_IN_IGNORE_CASE -> criteriaBuilder.not(criteriaBuilder.upper(column).`in`(literal.map { it.toUpperCase() }))
|
NOT_IN_IGNORE_CASE -> criteriaBuilder.not(criteriaBuilder.upper(column).`in`(literal.map { it.uppercase(Locale.getDefault()) }))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
when (columnPredicate.operator) {
|
when (columnPredicate.operator) {
|
||||||
|
@ -135,7 +135,7 @@ object ObjectDiffer {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (method.name.startsWith("get") && method.name.length > 3 && method.parameterCount == 0) {
|
if (method.name.startsWith("get") && method.name.length > 3 && method.parameterCount == 0) {
|
||||||
val fieldName = method.name[3].toLowerCase() + method.name.substring(4)
|
val fieldName = method.name[3].lowercaseChar() + method.name.substring(4)
|
||||||
foci.add(FieldFocus(fieldName, method.returnType, method))
|
foci.add(FieldFocus(fieldName, method.returnType, method))
|
||||||
} else if (method.name.startsWith("is") && method.parameterCount == 0) {
|
} else if (method.name.startsWith("is") && method.parameterCount == 0) {
|
||||||
foci.add(FieldFocus(method.name, method.returnType, method))
|
foci.add(FieldFocus(method.name, method.returnType, method))
|
||||||
|
@ -5,6 +5,7 @@ import net.corda.node.internal.rpc.proxies.RpcAuthHelper.methodFullName
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class RPCPermissionResolverTest {
|
class RPCPermissionResolverTest {
|
||||||
@ -29,7 +30,7 @@ class RPCPermissionResolverTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val readAlphaMethod = methodFullName(Alpha::class.java.getMethod("readAlpha"))
|
private val readAlphaMethod = methodFullName(Alpha::class.java.getMethod("readAlpha"))
|
||||||
private val readAlphaMethodKey = readAlphaMethod.toLowerCase()
|
private val readAlphaMethodKey = readAlphaMethod.lowercase(Locale.getDefault())
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `test Alpha`() {
|
fun `test Alpha`() {
|
||||||
|
@ -13,6 +13,7 @@ import net.corda.notarydemo.flows.DummyIssueAndMove
|
|||||||
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
|
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val address = NetworkHostAndPort("localhost", 10003)
|
val address = NetworkHostAndPort("localhost", 10003)
|
||||||
println("Connecting to the recipient node ($address)")
|
println("Connecting to the recipient node ($address)")
|
||||||
|
@ -51,6 +51,7 @@ import java.time.LocalDate
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val swapPricingExample = SwapPricingExample()
|
val swapPricingExample = SwapPricingExample()
|
||||||
swapPricingExample.main()
|
swapPricingExample.main()
|
||||||
|
@ -12,6 +12,7 @@ import net.corda.testing.driver.driver
|
|||||||
* This does not start any tests but has the nodes running in preparation for a live web demo or to receive commands
|
* This does not start any tests but has the nodes running in preparation for a live web demo or to receive commands
|
||||||
* via the web api.
|
* via the web api.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
driver(DriverParameters(waitForAllNodesToFinish = true)) {
|
driver(DriverParameters(waitForAllNodesToFinish = true)) {
|
||||||
val (nodeA, nodeB, nodeC) = listOf(
|
val (nodeA, nodeB, nodeC) = listOf(
|
||||||
|
@ -25,7 +25,7 @@ class AbstractAMQPSerializationSchemeTest {
|
|||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `number of cached factories must be bounded by maxFactories`() {
|
fun `number of cached factories must be bounded by maxFactories`() {
|
||||||
val genesisContext = SerializationContextImpl(
|
val genesisContext = SerializationContextImpl(
|
||||||
ByteSequence.of(byteArrayOf('c'.toByte(), 'o'.toByte(), 'r'.toByte(), 'd'.toByte(), 'a'.toByte(), 0.toByte(), 0.toByte(), 1.toByte())),
|
ByteSequence.of(byteArrayOf('c'.code.toByte(), 'o'.code.toByte(), 'r'.code.toByte(), 'd'.code.toByte(), 'a'.code.toByte(), 0.toByte(), 0.toByte(), 1.toByte())),
|
||||||
ClassLoader.getSystemClassLoader(),
|
ClassLoader.getSystemClassLoader(),
|
||||||
AllWhitelist,
|
AllWhitelist,
|
||||||
serializationProperties,
|
serializationProperties,
|
||||||
|
@ -17,6 +17,7 @@ import org.junit.Assert.assertNotSame
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.NotSerializableException
|
import java.io.NotSerializableException
|
||||||
import java.time.DayOfWeek
|
import java.time.DayOfWeek
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
@ -308,7 +309,7 @@ class EnumTests {
|
|||||||
THREE;
|
THREE;
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "[${name.toLowerCase()}]"
|
return "[${name.lowercase(Locale.getDefault())}]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.coretesting.internal.performance
|
|||||||
|
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +24,7 @@ data class Rate(
|
|||||||
*/
|
*/
|
||||||
operator fun times(inUnit: TimeUnit): Long = inUnit.convert(numberOfEvents, perTimeUnit)
|
operator fun times(inUnit: TimeUnit): Long = inUnit.convert(numberOfEvents, perTimeUnit)
|
||||||
|
|
||||||
override fun toString(): String = "$numberOfEvents / ${perTimeUnit.name.dropLast(1).toLowerCase()}" // drop the "s" at the end
|
override fun toString(): String = "$numberOfEvents / ${perTimeUnit.name.dropLast(1).lowercase(Locale.getDefault())}" // drop the "s" at the end
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun Long.div(timeUnit: TimeUnit) = Rate(this, timeUnit)
|
operator fun Long.div(timeUnit: TimeUnit) = Rate(this, timeUnit)
|
||||||
|
@ -10,6 +10,7 @@ import net.corda.core.internal.uncheckedCast
|
|||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import net.corda.core.transactions.WireTransaction
|
import net.corda.core.transactions.WireTransaction
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines output state lookup by label. It is split from the interpreter interfaces so that outputs may
|
* This interface defines output state lookup by label. It is split from the interpreter interfaces so that outputs may
|
||||||
@ -52,7 +53,7 @@ interface Verifies {
|
|||||||
"Expected exception containing '$expectedMessage' but raised exception had no message",
|
"Expected exception containing '$expectedMessage' but raised exception had no message",
|
||||||
exception
|
exception
|
||||||
)
|
)
|
||||||
} else if (!exceptionMessage.toLowerCase().contains(expectedMessage.toLowerCase())) {
|
} else if (!exceptionMessage.lowercase(Locale.getDefault()).contains(expectedMessage.lowercase(Locale.getDefault()))) {
|
||||||
throw AssertionError(
|
throw AssertionError(
|
||||||
"Expected exception containing '$expectedMessage' but raised exception was '$exception'",
|
"Expected exception containing '$expectedMessage' but raised exception was '$exception'",
|
||||||
exception
|
exception
|
||||||
|
@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
|||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -24,17 +24,17 @@ object HttpUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun putJson(url: URL, data: String) {
|
fun putJson(url: URL, data: String) {
|
||||||
val body = RequestBody.create("application/json; charset=utf-8".toMediaTypeOrNull(), data)
|
val body = data.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
|
||||||
makeRequest(Request.Builder().url(url).header("Content-Type", "application/json").put(body).build())
|
makeRequest(Request.Builder().url(url).header("Content-Type", "application/json").put(body).build())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun postJson(url: URL, data: String) {
|
fun postJson(url: URL, data: String) {
|
||||||
val body = RequestBody.create("application/json; charset=utf-8".toMediaTypeOrNull(), data)
|
val body = data.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
|
||||||
makeRequest(Request.Builder().url(url).header("Content-Type", "application/json").post(body).build())
|
makeRequest(Request.Builder().url(url).header("Content-Type", "application/json").post(body).build())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun postPlain(url: URL, data: String) {
|
fun postPlain(url: URL, data: String) {
|
||||||
val body = RequestBody.create("text/plain; charset=utf-8".toMediaTypeOrNull(), data)
|
val body = data.toRequestBody("text/plain; charset=utf-8".toMediaTypeOrNull())
|
||||||
makeRequest(Request.Builder().url(url).post(body).build())
|
makeRequest(Request.Builder().url(url).post(body).build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ class JarSignatureCollectorTest {
|
|||||||
fun `one signer with EC algorithm`() {
|
fun `one signer with EC algorithm`() {
|
||||||
dir.createJar(FILENAME, "_signable1", "_signable2")
|
dir.createJar(FILENAME, "_signable1", "_signable2")
|
||||||
// JDK11: Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.
|
// JDK11: Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.
|
||||||
val key = signAs(CHARLIE, CHARLIE_PASS)
|
val key = signAs(CHARLIE)
|
||||||
assertEquals(listOf(key), dir.getJarSigners(FILENAME)) // We only used CHARLIE's distinguished name, so the keys will be different.
|
assertEquals(listOf(key), dir.getJarSigners(FILENAME)) // We only used CHARLIE's distinguished name, so the keys will be different.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,12 +151,12 @@ class JarSignatureCollectorTest {
|
|||||||
assertEquals(listOf(key), dir.getJarSigners(FILENAME))
|
assertEquals(listOf(key), dir.getJarSigners(FILENAME))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun signAsAlice() = signAs(ALICE, ALICE_PASS)
|
private fun signAsAlice() = signAs(ALICE)
|
||||||
private fun signAsBob() = signAs(BOB, BOB_PASS)
|
private fun signAsBob() = signAs(BOB)
|
||||||
|
|
||||||
// JDK11: Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.
|
// JDK11: Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.
|
||||||
// TODO: use programmatic API support to implement signing (see https://docs.oracle.com/javase/9/docs/api/jdk/security/jarsigner/JarSigner.html)
|
// TODO: use programmatic API support to implement signing (see https://docs.oracle.com/javase/9/docs/api/jdk/security/jarsigner/JarSigner.html)
|
||||||
private fun signAs(alias: String, keyPassword: String = alias) : PublicKey {
|
private fun signAs(alias: String) : PublicKey {
|
||||||
return dir.signJar(FILENAME, alias, "storepass", "storepass")
|
return dir.signJar(FILENAME, alias, "storepass", "storepass")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.messaging.CordaRPCOps
|
|||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.util.Locale
|
||||||
import java.util.jar.JarInputStream
|
import java.util.jar.JarInputStream
|
||||||
import javax.servlet.http.HttpServlet
|
import javax.servlet.http.HttpServlet
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
@ -43,7 +44,7 @@ class AttachmentDownloadServlet : HttpServlet() {
|
|||||||
val attachment = rpc.openAttachment(hash)
|
val attachment = rpc.openAttachment(hash)
|
||||||
|
|
||||||
// Don't allow case sensitive matches inside the jar, it'd just be confusing.
|
// Don't allow case sensitive matches inside the jar, it'd just be confusing.
|
||||||
val subPath = reqPath.substringAfter('/', missingDelimiterValue = "").toLowerCase()
|
val subPath = reqPath.substringAfter('/', missingDelimiterValue = "").lowercase(Locale.getDefault())
|
||||||
|
|
||||||
resp.contentType = MediaType.APPLICATION_OCTET_STREAM
|
resp.contentType = MediaType.APPLICATION_OCTET_STREAM
|
||||||
if (subPath.isEmpty()) {
|
if (subPath.isEmpty()) {
|
||||||
|
@ -72,7 +72,7 @@ class CheckpointAgent {
|
|||||||
when (nvpItem[0].trim()) {
|
when (nvpItem[0].trim()) {
|
||||||
"instrumentClassname" -> instrumentClassname = nvpItem[1]
|
"instrumentClassname" -> instrumentClassname = nvpItem[1]
|
||||||
"instrumentType" -> try {
|
"instrumentType" -> try {
|
||||||
instrumentType = InstrumentationType.valueOf(nvpItem[1].toUpperCase())
|
instrumentType = InstrumentationType.valueOf(nvpItem[1].uppercase(Locale.getDefault()))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
display("Invalid value: ${nvpItem[1]}. Please specify read or write.")
|
display("Invalid value: ${nvpItem[1]}. Please specify read or write.")
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ abstract class CliWrapperBase(val alias: String, val description: String) : Call
|
|||||||
}
|
}
|
||||||
|
|
||||||
val specifiedLogLevel: String by lazy {
|
val specifiedLogLevel: String by lazy {
|
||||||
System.getProperty("log4j2.level")?.toLowerCase(Locale.ENGLISH) ?: loggingLevel.name.toLowerCase(Locale.ENGLISH)
|
System.getProperty("log4j2.level")?.lowercase(Locale.ENGLISH) ?: loggingLevel.name.lowercase(Locale.ENGLISH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ object CommonCliConstants {
|
|||||||
*/
|
*/
|
||||||
class LoggingLevelConverter : ITypeConverter<Level> {
|
class LoggingLevelConverter : ITypeConverter<Level> {
|
||||||
override fun convert(value: String?): Level {
|
override fun convert(value: String?): Level {
|
||||||
return value?.let { Level.valueOf(it.toUpperCase()) }
|
return value?.let { Level.valueOf(it.uppercase(Locale.getDefault())) }
|
||||||
?: throw TypeConversionException("Unknown option for --logging-level: $value")
|
?: throw TypeConversionException("Unknown option for --logging-level: $value")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ class ResourceGenerator(private val locales: List<Locale>) {
|
|||||||
throw ClassDoesNotExistException(it)
|
throw ClassDoesNotExistException(it)
|
||||||
}
|
}
|
||||||
if (ErrorCodes::class.java.isAssignableFrom(clazz) && clazz != ErrorCodes::class.java) {
|
if (ErrorCodes::class.java.isAssignableFrom(clazz) && clazz != ErrorCodes::class.java) {
|
||||||
val namespace = (clazz.enumConstants.first() as ErrorCodes).namespace.toLowerCase()
|
val namespace = (clazz.enumConstants.first() as ErrorCodes).namespace.lowercase(Locale.getDefault())
|
||||||
clazz.enumConstants.map { code -> "${namespace}-${code.toString().toLowerCase().replace("_", "-")}"}
|
clazz.enumConstants.map { code -> "${namespace}-${code.toString().lowercase(Locale.getDefault()).replace("_", "-")}"}
|
||||||
} else {
|
} else {
|
||||||
listOf()
|
listOf()
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,10 @@ class ResourceGeneratorTest {
|
|||||||
private val classes = listOf(TestCodes1::class.qualifiedName!!, TestCodes2::class.qualifiedName!!)
|
private val classes = listOf(TestCodes1::class.qualifiedName!!, TestCodes2::class.qualifiedName!!)
|
||||||
|
|
||||||
private fun expectedCodes() : List<String> {
|
private fun expectedCodes() : List<String> {
|
||||||
val codes1 = TestCodes1.values().map { "${it.namespace.toLowerCase()}-${it.name.replace("_", "-").toLowerCase()}" }
|
val codes1 = TestCodes1.values().map { "${it.namespace.lowercase(Locale.getDefault())}-${it.name.replace("_", "-")
|
||||||
val codes2 = TestCodes2.values().map { "${it.namespace.toLowerCase()}-${it.name.replace("_", "-").toLowerCase()}" }
|
.lowercase(Locale.getDefault())}" }
|
||||||
|
val codes2 = TestCodes2.values().map { "${it.namespace.lowercase(Locale.getDefault())}-${it.name.replace("_", "-")
|
||||||
|
.lowercase(Locale.getDefault())}" }
|
||||||
return codes1 + codes2
|
return codes1 + codes2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import javafx.scene.input.MouseEvent
|
|||||||
import net.corda.client.jfx.utils.ChosenList
|
import net.corda.client.jfx.utils.ChosenList
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
import net.corda.client.jfx.utils.map
|
import net.corda.client.jfx.utils.map
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic search bar filters [ObservableList] with provided filterCriteria.
|
* Generic search bar filters [ObservableList] with provided filterCriteria.
|
||||||
@ -68,9 +69,9 @@ class SearchField<T>(private val data: ObservableList<T>, vararg filterCriteria:
|
|||||||
})
|
})
|
||||||
textField.promptTextProperty().bind(searchCategory.valueProperty().map {
|
textField.promptTextProperty().bind(searchCategory.valueProperty().map {
|
||||||
val category = if (it == ALL) {
|
val category = if (it == ALL) {
|
||||||
filterCriteria.joinToString(", ") { it.first.toLowerCase() }
|
filterCriteria.joinToString(", ") { it.first.lowercase(Locale.getDefault()) }
|
||||||
} else {
|
} else {
|
||||||
it.toLowerCase()
|
it.lowercase(Locale.getDefault())
|
||||||
}
|
}
|
||||||
"Filter by $category."
|
"Filter by $category."
|
||||||
})
|
})
|
||||||
|
@ -59,10 +59,6 @@ class Settings : CordaView() {
|
|||||||
getModel<SettingsModel>().commit()
|
getModel<SettingsModel>().commit()
|
||||||
clientPane.isDisable = true
|
clientPane.isDisable = true
|
||||||
}
|
}
|
||||||
val disableProperty = clientPane.disableProperty()
|
clientPane.disableProperty()
|
||||||
// save.visibleProperty().bind(disableProperty.map { !it })
|
|
||||||
// editCancel.textProperty().bind(disableProperty.map { if (!it) "Cancel" else "Edit" })
|
|
||||||
// editCancel.graphicProperty().bind(disableProperty
|
|
||||||
// .map { if (!it) FontAwesomeIconView(FontAwesomeIcon.TIMES) else FontAwesomeIconView(FontAwesomeIcon.EDIT) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
|
|||||||
val (consistentVaults, diffQueues) = if (previousState == null) {
|
val (consistentVaults, diffQueues) = if (previousState == null) {
|
||||||
Pair(currentNodeVaults, mapOf<AbstractParty, Map<AbstractParty, List<Pair<AbstractParty, Long>>>>())
|
Pair(currentNodeVaults, mapOf<AbstractParty, Map<AbstractParty, List<Pair<AbstractParty, Long>>>>())
|
||||||
} else {
|
} else {
|
||||||
log.info("${previousState.diffQueues.values.sumBy { it.values.sumBy { it.size } }} txs in limbo")
|
log.info("${previousState.diffQueues.values.sumOf { it.values.sumOf { it.size } }} txs in limbo")
|
||||||
val newDiffQueues = previousState.copyQueues()
|
val newDiffQueues = previousState.copyQueues()
|
||||||
val newConsistentVault = previousState.copyVaults()
|
val newConsistentVault = previousState.copyVaults()
|
||||||
previousState.diffQueues.forEach { entry ->
|
previousState.diffQueues.forEach { entry ->
|
||||||
|
@ -8,6 +8,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
|
|||||||
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
|
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
|
||||||
import com.microsoft.azure.management.resources.ResourceGroup
|
import com.microsoft.azure.management.resources.ResourceGroup
|
||||||
import com.microsoft.azure.management.resources.fluentcore.arm.Region
|
import com.microsoft.azure.management.resources.fluentcore.arm.Region
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class Constants {
|
class Constants {
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ class Constants {
|
|||||||
const val REGION_ARG_NAME = "REGION"
|
const val REGION_ARG_NAME = "REGION"
|
||||||
|
|
||||||
fun ResourceGroup.restFriendlyName(): String {
|
fun ResourceGroup.restFriendlyName(): String {
|
||||||
return this.name().replace(ALPHA_NUMERIC_ONLY_REGEX, "").toLowerCase()
|
return this.name().replace(ALPHA_NUMERIC_ONLY_REGEX, "").lowercase(Locale.getDefault())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import net.corda.networkbuilder.context.Context
|
|||||||
import net.corda.networkbuilder.nodes.*
|
import net.corda.networkbuilder.nodes.*
|
||||||
import net.corda.networkbuilder.notaries.NotaryCopier
|
import net.corda.networkbuilder.notaries.NotaryCopier
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
interface NetworkBuilder {
|
interface NetworkBuilder {
|
||||||
@ -142,7 +143,7 @@ private class NetworkBuilderImpl : NetworkBuilder {
|
|||||||
|
|
||||||
val nodeDiscoveryFuture = CompletableFuture.supplyAsync {
|
val nodeDiscoveryFuture = CompletableFuture.supplyAsync {
|
||||||
val foundNodes = nodeFinder.findNodes()
|
val foundNodes = nodeFinder.findNodes()
|
||||||
.map { it to nodeCounts.getOrDefault(it.name.toLowerCase(), 1) }
|
.map { it to nodeCounts.getOrDefault(it.name.lowercase(Locale.getDefault()), 1) }
|
||||||
.toMap()
|
.toMap()
|
||||||
foundNodes
|
foundNodes
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import net.corda.networkbuilder.nodes.NodeAdder
|
|||||||
import net.corda.networkbuilder.nodes.NodeInstantiator
|
import net.corda.networkbuilder.nodes.NodeInstantiator
|
||||||
import net.corda.networkbuilder.toSingleFuture
|
import net.corda.networkbuilder.toSingleFuture
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class CommandLineInterface {
|
class CommandLineInterface {
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ class CommandLineInterface {
|
|||||||
val (_, instantiator, _) = Backend.fromContext(context, cacheDir)
|
val (_, instantiator, _) = Backend.fromContext(context, cacheDir)
|
||||||
val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context))
|
val nodeAdder = NodeAdder(context, NodeInstantiator(instantiator, context))
|
||||||
parsedArgs.nodesToAdd.map {
|
parsedArgs.nodesToAdd.map {
|
||||||
nodeAdder.addNode(context, Constants.ALPHA_NUMERIC_ONLY_REGEX.replace(it.key.toLowerCase(), ""), CordaX500Name.parse(it.value))
|
nodeAdder.addNode(context, Constants.ALPHA_NUMERIC_ONLY_REGEX.replace(it.key.lowercase(Locale.getDefault()), ""), CordaX500Name.parse(it.value))
|
||||||
}.toSingleFuture().getOrThrow()
|
}.toSingleFuture().getOrThrow()
|
||||||
persistContext(contextFile, objectMapper, context)
|
persistContext(contextFile, objectMapper, context)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import net.corda.networkbuilder.containers.push.azure.RegistryLocator.Companion.
|
|||||||
import net.corda.networkbuilder.docker.DockerUtils
|
import net.corda.networkbuilder.docker.DockerUtils
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
class AzureContainerPusher(private val azureRegistry: Registry) : ContainerPusher {
|
class AzureContainerPusher(private val azureRegistry: Registry) : ContainerPusher {
|
||||||
@ -22,7 +23,7 @@ class AzureContainerPusher(private val azureRegistry: Registry) : ContainerPushe
|
|||||||
registryUser,
|
registryUser,
|
||||||
registryPassword)
|
registryPassword)
|
||||||
|
|
||||||
val privateRepoUrl = "${azureRegistry.loginServerUrl()}/$remoteImageName".toLowerCase()
|
val privateRepoUrl = "${azureRegistry.loginServerUrl()}/$remoteImageName".lowercase(Locale.getDefault())
|
||||||
dockerClient.tagImageCmd(localImageId, privateRepoUrl, networkName).exec()
|
dockerClient.tagImageCmd(localImageId, privateRepoUrl, networkName).exec()
|
||||||
val result = CompletableFuture<String>()
|
val result = CompletableFuture<String>()
|
||||||
dockerClient.pushImageCmd("$privateRepoUrl:$networkName")
|
dockerClient.pushImageCmd("$privateRepoUrl:$networkName")
|
||||||
|
@ -5,12 +5,13 @@ import net.corda.networkbuilder.Constants
|
|||||||
import net.corda.networkbuilder.backends.Backend
|
import net.corda.networkbuilder.backends.Backend
|
||||||
import net.corda.networkbuilder.nodes.NodeInstanceRequest
|
import net.corda.networkbuilder.nodes.NodeInstanceRequest
|
||||||
import org.apache.activemq.artemis.utils.collections.ConcurrentHashSet
|
import org.apache.activemq.artemis.utils.collections.ConcurrentHashSet
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
class Context(val networkName: String, val backendType: Backend.BackendType, backendOptions: Map<String, String> = emptyMap()) {
|
class Context(val networkName: String, val backendType: Backend.BackendType, backendOptions: Map<String, String> = emptyMap()) {
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
var safeNetworkName: String = networkName.replace(Constants.ALPHA_NUMERIC_ONLY_REGEX, "").toLowerCase()
|
var safeNetworkName: String = networkName.replace(Constants.ALPHA_NUMERIC_ONLY_REGEX, "").lowercase(Locale.getDefault())
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
var nodes: MutableMap<String, ConcurrentHashSet<PersistableNodeInstance>> = ConcurrentHashMap()
|
var nodes: MutableMap<String, ConcurrentHashSet<PersistableNodeInstance>> = ConcurrentHashMap()
|
||||||
|
@ -2,10 +2,11 @@ package net.corda.networkbuilder.nodes
|
|||||||
|
|
||||||
import net.corda.networkbuilder.Constants
|
import net.corda.networkbuilder.Constants
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
open class FoundNode(open val configFile: File,
|
open class FoundNode(open val configFile: File,
|
||||||
open val baseDirectory: File = configFile.parentFile,
|
open val baseDirectory: File = configFile.parentFile,
|
||||||
val name: String = configFile.parentFile.name.toLowerCase().replace(Constants.ALPHA_NUMERIC_ONLY_REGEX, "")) {
|
val name: String = configFile.parentFile.name.lowercase(Locale.getDefault()).replace(Constants.ALPHA_NUMERIC_ONLY_REGEX, "")) {
|
||||||
|
|
||||||
operator fun component1(): File {
|
operator fun component1(): File {
|
||||||
return baseDirectory
|
return baseDirectory
|
||||||
|
@ -5,6 +5,7 @@ import net.corda.networkbuilder.Constants
|
|||||||
import net.corda.networkbuilder.containers.instance.InstanceInfo
|
import net.corda.networkbuilder.containers.instance.InstanceInfo
|
||||||
import net.corda.networkbuilder.containers.instance.Instantiator
|
import net.corda.networkbuilder.containers.instance.Instantiator
|
||||||
import net.corda.networkbuilder.context.Context
|
import net.corda.networkbuilder.context.Context
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
class NodeInstantiator(val instantiator: Instantiator,
|
class NodeInstantiator(val instantiator: Instantiator,
|
||||||
@ -12,9 +13,9 @@ class NodeInstantiator(val instantiator: Instantiator,
|
|||||||
|
|
||||||
fun createInstanceRequests(pushedNode: PushedNode, nodeCount: Map<FoundNode, Int>): List<NodeInstanceRequest> {
|
fun createInstanceRequests(pushedNode: PushedNode, nodeCount: Map<FoundNode, Int>): List<NodeInstanceRequest> {
|
||||||
|
|
||||||
val namedMap = nodeCount.map { it.key.name.toLowerCase() to it.value }.toMap()
|
val namedMap = nodeCount.map { it.key.name.lowercase(Locale.getDefault()) to it.value }.toMap()
|
||||||
|
|
||||||
return (0 until (namedMap[pushedNode.name.toLowerCase()] ?: 1)).map { i ->
|
return (0 until (namedMap[pushedNode.name.lowercase(Locale.getDefault())] ?: 1)).map { i ->
|
||||||
createInstanceRequest(pushedNode, i)
|
createInstanceRequest(pushedNode, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,11 +66,11 @@ object CityDatabase {
|
|||||||
val matchResult = matcher.matchEntire(name) ?: throw Exception("Could not parse line: $line")
|
val matchResult = matcher.matchEntire(name) ?: throw Exception("Could not parse line: $line")
|
||||||
val (city, country) = matchResult.destructured
|
val (city, country) = matchResult.destructured
|
||||||
val location = WorldMapLocation(WorldCoordinate(lat.toDouble(), lng.toDouble()), city, country)
|
val location = WorldMapLocation(WorldCoordinate(lat.toDouble(), lng.toDouble()), city, country)
|
||||||
caseInsensitiveLookups[city.toLowerCase()] = location
|
caseInsensitiveLookups[city.lowercase(Locale.getDefault())] = location
|
||||||
cityMap[city] = location
|
cityMap[city] = location
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(name: String) = caseInsensitiveLookups[name.toLowerCase()]
|
operator fun get(name: String) = caseInsensitiveLookups[name.lowercase(Locale.getDefault())]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user