From 6d43a654ff45c3d80c4f67b37fa2a9787e2205d5 Mon Sep 17 00:00:00 2001 From: Michal Kit Date: Thu, 6 Sep 2018 10:12:56 +0100 Subject: [PATCH] CORDA-1938 Adding version info to the node info submission request (#3854) (#3885) --- .../net/corda/node/internal/AbstractNode.kt | 2 +- .../net/corda/node/internal/NodeStartup.kt | 2 +- .../node/services/network/NetworkMapClient.kt | 40 ++++++++++++++++--- .../HTTPNetworkRegistrationService.kt | 10 ++--- .../services/network/NetworkMapClientTest.kt | 3 +- .../network/NetworkParametersReaderTest.kt | 3 +- .../testing/node/internal/DriverDSLImpl.kt | 3 +- 7 files changed, 47 insertions(+), 16 deletions(-) diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 5456642045..0627ba4332 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -195,7 +195,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, val (identity, identityKeyPair) = obtainIdentity(notaryConfig = null) val identityService = makeIdentityService(identity.certificate) - networkMapClient = configuration.networkServices?.let { NetworkMapClient(it.networkMapURL, identityService.trustRoot) } + networkMapClient = configuration.networkServices?.let { NetworkMapClient(it.networkMapURL, identityService.trustRoot, versionInfo) } val networkParameteresReader = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory) val networkParameters = networkParameteresReader.networkParameters check(networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) { diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index 02e4d8a458..923a0cfc26 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -205,7 +205,7 @@ open class NodeStartup(val args: Array) { println("* Registering as a new participant with Corda network *") println("* *") println("******************************************************************") - NetworkRegistrationHelper(conf, HTTPNetworkRegistrationService(compatibilityZoneURL), nodeRegistrationConfig).buildKeystore() + NetworkRegistrationHelper(conf, HTTPNetworkRegistrationService(compatibilityZoneURL, getVersionInfo()), nodeRegistrationConfig).buildKeystore() } open protected fun loadConfigFile(cmdlineOptions: CmdLineOptions): NodeConfiguration = cmdlineOptions.loadConfig() diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt index 4508b7753b..f400aae5b5 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt @@ -3,7 +3,6 @@ package net.corda.node.services.network import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SignedData import net.corda.core.internal.openHttpConnection -import net.corda.core.internal.post import net.corda.core.internal.responseAs import net.corda.core.node.NodeInfo import net.corda.core.serialization.deserialize @@ -11,18 +10,22 @@ import net.corda.core.serialization.serialize import net.corda.core.utilities.contextLogger import net.corda.core.utilities.seconds import net.corda.core.utilities.trace +import net.corda.node.VersionInfo import net.corda.node.utilities.registration.cacheControl import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.network.NetworkMap import net.corda.nodeapi.internal.network.SignedNetworkMap import net.corda.nodeapi.internal.network.SignedNetworkParameters import net.corda.nodeapi.internal.network.verifiedNetworkMapCert +import org.apache.commons.io.IOUtils import java.io.BufferedReader +import java.io.IOException +import java.net.HttpURLConnection import java.net.URL import java.security.cert.X509Certificate import java.time.Duration -class NetworkMapClient(compatibilityZoneURL: URL, val trustedRoot: X509Certificate) { +class NetworkMapClient(compatibilityZoneURL: URL, val trustedRoot: X509Certificate, private val versionInfo: VersionInfo) { companion object { private val logger = contextLogger() } @@ -32,15 +35,40 @@ class NetworkMapClient(compatibilityZoneURL: URL, val trustedRoot: X509Certifica fun publish(signedNodeInfo: SignedNodeInfo) { val publishURL = URL("$networkMapUrl/publish") logger.trace { "Publishing NodeInfo to $publishURL." } - publishURL.post(signedNodeInfo.serialize()) - logger.trace { "Published NodeInfo to $publishURL successfully." } + val conn = publishURL.openHttpConnection() + conn.doOutput = true + conn.requestMethod = "POST" + conn.setRequestProperty("Content-Type", "application/octet-stream") + conn.setRequestProperty("Client-Version", versionInfo.releaseVersion) + conn.setRequestProperty("Platform-Version", versionInfo.platformVersion.toString()) + conn.outputStream.write(signedNodeInfo.serialize().bytes) + when (conn.responseCode) { + HttpURLConnection.HTTP_OK -> { + logger.trace { "Published NodeInfo to $publishURL successfully." } + } + else -> throw IOException("Response Code ${conn.responseCode}: ${IOUtils.toString(conn.errorStream)}") + } } fun ackNetworkParametersUpdate(signedParametersHash: SignedData) { val ackURL = URL("$networkMapUrl/ack-parameters") + + // Post request to certificate signing server via http. + val conn = ackURL.openHttpConnection() logger.trace { "Sending network parameters with hash ${signedParametersHash.raw.deserialize()} approval to $ackURL." } - ackURL.post(signedParametersHash.serialize()) - logger.trace { "Sent network parameters approval to $ackURL successfully." } + conn.doOutput = true + conn.requestMethod = "POST" + conn.setRequestProperty("Content-Type", "application/octet-stream") + conn.setRequestProperty("Client-Version", versionInfo.releaseVersion) + conn.setRequestProperty("Platform-Version", versionInfo.platformVersion.toString()) + conn.outputStream.write(signedParametersHash.serialize().bytes) + + when (conn.responseCode) { + HttpURLConnection.HTTP_OK -> { + logger.trace { "Sent network parameters approval to $ackURL successfully." } + } + else -> throw IOException("Response Code ${conn.responseCode}: ${IOUtils.toString(conn.errorStream)}") + } } fun getNetworkMap(): NetworkMapResponse { diff --git a/node/src/main/kotlin/net/corda/node/utilities/registration/HTTPNetworkRegistrationService.kt b/node/src/main/kotlin/net/corda/node/utilities/registration/HTTPNetworkRegistrationService.kt index 33b7b6b7d7..4ba2cbd0df 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/registration/HTTPNetworkRegistrationService.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/registration/HTTPNetworkRegistrationService.kt @@ -3,6 +3,7 @@ package net.corda.node.utilities.registration import com.google.common.net.MediaType import net.corda.core.internal.openHttpConnection import net.corda.core.utilities.seconds +import net.corda.node.VersionInfo import net.corda.nodeapi.internal.crypto.X509CertificateFactory import okhttp3.CacheControl import okhttp3.Headers @@ -17,12 +18,10 @@ import java.util.* import java.util.zip.ZipInputStream import javax.naming.ServiceUnavailableException -class HTTPNetworkRegistrationService(compatibilityZoneURL: URL) : NetworkRegistrationService { +class HTTPNetworkRegistrationService(compatibilityZoneURL: URL, val versionInfo: VersionInfo) : NetworkRegistrationService { private val registrationURL = URL("$compatibilityZoneURL/certificate") companion object { - // TODO: Propagate version information from gradle - val clientVersion = "1.0" private val TRANSIENT_ERROR_STATUS_CODES = setOf(HTTP_BAD_GATEWAY, HTTP_UNAVAILABLE, HTTP_GATEWAY_TIMEOUT) } @@ -57,12 +56,13 @@ class HTTPNetworkRegistrationService(compatibilityZoneURL: URL) : NetworkRegistr conn.doOutput = true conn.requestMethod = "POST" conn.setRequestProperty("Content-Type", "application/octet-stream") - conn.setRequestProperty("Client-Version", clientVersion) + conn.setRequestProperty("Client-Version", versionInfo.releaseVersion) + conn.setRequestProperty("Platform-Version", versionInfo.platformVersion.toString()) conn.outputStream.write(request.encoded) return when (conn.responseCode) { HTTP_OK -> IOUtils.toString(conn.inputStream, conn.charset) - HTTP_FORBIDDEN -> throw IOException("Client version $clientVersion is forbidden from accessing permissioning server, please upgrade to newer version.") + HTTP_FORBIDDEN -> throw IOException("Client version ${versionInfo.releaseVersion} is forbidden from accessing permissioning server, please upgrade to newer version.") else -> throwUnexpectedResponseCode(conn) } } diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt index c888ed6818..6455dd90b7 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapClientTest.kt @@ -5,6 +5,7 @@ import net.corda.core.crypto.sha256 import net.corda.core.internal.* import net.corda.core.serialization.serialize import net.corda.core.utilities.seconds +import net.corda.node.VersionInfo import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.BOB_NAME import net.corda.testing.core.SerializationEnvironmentRule @@ -41,7 +42,7 @@ class NetworkMapClientTest { fun setUp() { server = NetworkMapServer(cacheTimeout, PortAllocation.Incremental(10000).nextHostAndPort()) val hostAndPort = server.start() - networkMapClient = NetworkMapClient(URL("http://${hostAndPort.host}:${hostAndPort.port}"), DEV_ROOT_CA.certificate) + networkMapClient = NetworkMapClient(URL("http://${hostAndPort.host}:${hostAndPort.port}"), DEV_ROOT_CA.certificate, VersionInfo(1, "TEST", "TEST", "TEST")) } @After diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt index fd22e1c3e4..97cacba5d6 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkParametersReaderTest.kt @@ -9,6 +9,7 @@ import net.corda.core.internal.readObject import net.corda.core.serialization.deserialize import net.corda.core.utilities.days import net.corda.core.utilities.seconds +import net.corda.node.VersionInfo import net.corda.node.internal.NetworkParametersReader import net.corda.nodeapi.internal.network.* import net.corda.testing.common.internal.testNetworkParameters @@ -41,7 +42,7 @@ class NetworkParametersReaderTest { fun setUp() { server = NetworkMapServer(cacheTimeout, PortAllocation.Incremental(10000).nextHostAndPort()) val hostAndPort = server.start() - networkMapClient = NetworkMapClient(URL("http://${hostAndPort.host}:${hostAndPort.port}"), DEV_ROOT_CA.certificate) + networkMapClient = NetworkMapClient(URL("http://${hostAndPort.host}:${hostAndPort.port}"), DEV_ROOT_CA.certificate, VersionInfo(1, "TEST", "TEST", "TEST")) } @After diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index 0f95bdd1bc..88456ae269 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -24,6 +24,7 @@ import net.corda.core.utilities.contextLogger import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.millis import net.corda.node.NodeRegistrationOption +import net.corda.node.VersionInfo import net.corda.node.internal.Node import net.corda.node.internal.NodeStartup import net.corda.node.internal.StartedNode @@ -272,7 +273,7 @@ class DriverDSLImpl( return if (startNodesInProcess) { executorService.fork { - NetworkRegistrationHelper(config.corda, HTTPNetworkRegistrationService(compatibilityZoneURL), NodeRegistrationOption(rootTruststorePath, rootTruststorePassword)).buildKeystore() + NetworkRegistrationHelper(config.corda, HTTPNetworkRegistrationService(compatibilityZoneURL, VersionInfo(1, "Unknown", "Unknown", "Unknown")), NodeRegistrationOption(rootTruststorePath, rootTruststorePassword)).buildKeystore() config } } else {