From fbf0bd9bd94ff7c17fc1482e896e7215a02cd8db Mon Sep 17 00:00:00 2001 From: jakubbielawa Date: Tue, 12 May 2020 13:23:38 +0100 Subject: [PATCH 01/10] Upgrade ClassGraph to 4.8.78 (#6237) --- constants.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 8839cf5c54..6865651962 100644 --- a/constants.properties +++ b/constants.properties @@ -21,7 +21,7 @@ quasarVersion11=0.8.0_r3 jdkClassifier11=jdk11 proguardVersion=6.1.1 bouncycastleVersion=1.60 -classgraphVersion=4.8.71 +classgraphVersion=4.8.78 disruptorVersion=3.4.2 typesafeConfigVersion=1.3.4 jsr305Version=3.0.2 From c3ea2c14708105576acc321a63a6b7c316c83f35 Mon Sep 17 00:00:00 2001 From: "john.buckle@r3.com" Date: Wed, 13 May 2020 09:51:35 +0800 Subject: [PATCH 02/10] Ignore warning for CORDA environment variables in all caps --- .../net/corda/node/services/config/ConfigUtilities.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt index b2dc5dd773..3f4eab0295 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt @@ -36,6 +36,7 @@ object ConfigHelper { private const val UPPERCASE_PROPERTY_PREFIX = "CORDA." private val log = LoggerFactory.getLogger(javaClass) + @Suppress("LongParameterList") fun loadConfig(baseDirectory: Path, configFile: Path = baseDirectory / "node.conf", allowMissingConfig: Boolean = false, @@ -88,7 +89,13 @@ object ConfigHelper { return ConfigFactory.parseMap( toProperties() .mapKeys { - var newKey = (it.key as String) + val original = it.key as String + + if (original == original.toUpperCase()){ + return@mapKeys original + } + + var newKey = original .replace('_', '.') .replace(UPPERCASE_PROPERTY_PREFIX, CORDA_PROPERTY_PREFIX) @@ -175,4 +182,4 @@ fun MutualSslConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500N else -> throw IllegalArgumentException("CryptoService not supported.") } } -} \ No newline at end of file +} From 9caf6538ced911223fa2931fa206affa4846bd21 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Wed, 13 May 2020 13:15:05 +0100 Subject: [PATCH 03/10] ENT-5298: Increase timeout by two minutes because the test occasionally takes longer than five minutes (#6246) --- .../kotlin/net/corda/node/services/rpc/RpcReconnectTests.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node/src/integration-test-slow/kotlin/net/corda/node/services/rpc/RpcReconnectTests.kt b/node/src/integration-test-slow/kotlin/net/corda/node/services/rpc/RpcReconnectTests.kt index 5c3f103377..242cacdaad 100644 --- a/node/src/integration-test-slow/kotlin/net/corda/node/services/rpc/RpcReconnectTests.kt +++ b/node/src/integration-test-slow/kotlin/net/corda/node/services/rpc/RpcReconnectTests.kt @@ -75,7 +75,8 @@ class RpcReconnectTests { * This test runs flows in a loop and in the background kills the node or restarts it. * Also the RPC connection is made through a proxy that introduces random latencies and is also periodically killed. */ - @Test(timeout=300_000) + @Suppress("ComplexMethod") + @Test(timeout=420_000) fun `test that the RPC client is able to reconnect and proceed after node failure, restart, or connection reset`() { val nodeRunningTime = { Random().nextInt(12000) + 8000 } From febb5a44b7c689c290d65cdc32b7ab4b118336b4 Mon Sep 17 00:00:00 2001 From: "john.buckle@r3.com" Date: Wed, 13 May 2020 21:55:04 +0800 Subject: [PATCH 04/10] Added comment --- .../kotlin/net/corda/node/services/config/ConfigUtilities.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt index 3f4eab0295..8a5eec792f 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt @@ -91,6 +91,8 @@ object ConfigHelper { .mapKeys { val original = it.key as String + // Reject environment variable that are in all caps + // since these cannot be properties. if (original == original.toUpperCase()){ return@mapKeys original } From 74080e7cb6491e68d67e5bd3706368eaaf8d2f62 Mon Sep 17 00:00:00 2001 From: Adel El-Beik <48713346+adelel1@users.noreply.github.com> Date: Wed, 13 May 2020 15:11:25 +0100 Subject: [PATCH 05/10] CORDA-3772: Now specify source and target of 8 when compiling contract classes. (#6249) --- .../net/corda/testing/core/internal/ContractJarTestUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/core-test-utils/src/main/kotlin/net/corda/testing/core/internal/ContractJarTestUtils.kt b/testing/core-test-utils/src/main/kotlin/net/corda/testing/core/internal/ContractJarTestUtils.kt index 413f2bf843..3ba57fa20a 100644 --- a/testing/core-test-utils/src/main/kotlin/net/corda/testing/core/internal/ContractJarTestUtils.kt +++ b/testing/core-test-utils/src/main/kotlin/net/corda/testing/core/internal/ContractJarTestUtils.kt @@ -110,7 +110,7 @@ object ContractJarTestUtils { val fileManager = compiler.getStandardFileManager(null, null, null) fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(workingDir.toFile())) - compiler.getTask(System.out.writer(), fileManager, null, null, null, listOf(source)).call() + compiler.getTask(System.out.writer(), fileManager, null, listOf("-source", "8", "-target", "8"), null, listOf(source)).call() val outFile = fileManager.getFileForInput(StandardLocation.CLASS_OUTPUT, packages.joinToString("."), "$className.class") return Paths.get(outFile.name) } From c2ac22a41ff2c929f7418c39e57daf3e8ebaa3a3 Mon Sep 17 00:00:00 2001 From: Dan Newton Date: Wed, 13 May 2020 15:17:51 +0100 Subject: [PATCH 06/10] NOTICK Non-database error handling in `withEntityManager` (#6239) When a non-database exception is thrown out of a `withEntityManager` block, always check if the session needs to be rolled back. This means if a database error is caught and a new non-database error is thrown out of the `withEntityManager` block, the transaction is still rolled back. The flow can then continue progressing as normal. --- .../corda/node/flows/FlowEntityManagerTest.kt | 126 ++++++++++++++++++ .../net/corda/node/internal/AbstractNode.kt | 7 +- 2 files changed, 129 insertions(+), 4 deletions(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt b/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt index f8c68f0cb6..add2317a64 100644 --- a/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/flows/FlowEntityManagerTest.kt @@ -32,6 +32,7 @@ import net.corda.testing.driver.driver import org.hibernate.exception.ConstraintViolationException import org.junit.Before import org.junit.Test +import java.lang.RuntimeException import java.sql.Connection import java.util.concurrent.ExecutorService import java.util.concurrent.Executors @@ -39,6 +40,7 @@ import java.util.concurrent.Semaphore import javax.persistence.PersistenceException import kotlin.test.assertEquals +@Suppress("TooGenericExceptionCaught", "TooGenericExceptionThrown") class FlowEntityManagerTest : AbstractFlowEntityManagerTest() { @Before @@ -364,6 +366,62 @@ class FlowEntityManagerTest : AbstractFlowEntityManagerTest() { } } + @Test(timeout = 300_000) + fun `non database error caught outside entity manager does not save entities`() { + var counter = 0 + StaffedFlowHospital.onFlowDischarged.add { _, _ -> ++counter } + + driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) { + + val alice = startNode(providedName = ALICE_NAME).getOrThrow() + alice.rpc.startFlow(::EntityManagerSaveAndThrowNonDatabaseErrorFlow) + .returnValue.getOrThrow(30.seconds) + assertEquals(0, counter) + val entities = alice.rpc.startFlow(::GetCustomEntities).returnValue.getOrThrow() + assertEquals(0, entities.size) + + } + } + + @Test(timeout = 300_000) + fun `non database error caught outside entity manager after flush occurs does save entities`() { + var counter = 0 + StaffedFlowHospital.onFlowDischarged.add { _, _ -> ++counter } + + driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) { + + val alice = startNode(providedName = ALICE_NAME).getOrThrow() + alice.rpc.startFlow(::EntityManagerSaveFlushAndThrowNonDatabaseErrorFlow) + .returnValue.getOrThrow(30.seconds) + assertEquals(0, counter) + val entities = alice.rpc.startFlow(::GetCustomEntities).returnValue.getOrThrow() + assertEquals(3, entities.size) + } + } + + @Test(timeout = 300_000) + fun `database error caught inside entity manager non database exception thrown and caught outside entity manager should not save entities`() { + var counter = 0 + StaffedFlowHospital.onFlowDischarged.add { _, _ -> ++counter } + + driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true)) { + + val alice = startNode(providedName = ALICE_NAME).getOrThrow() + alice.rpc.expectFlowSuccessAndAssertCreatedEntities( + flow = ::EntityManagerCatchDatabaseErrorInsideEntityManagerThrowNonDatabaseErrorAndCatchOutsideFlow, + commitStatus = CommitStatus.NO_INTERMEDIATE_COMMIT, + numberOfDischarges = 0, + numberOfExpectedEntities = 1 + ) + alice.rpc.expectFlowSuccessAndAssertCreatedEntities( + flow = ::EntityManagerCatchDatabaseErrorInsideEntityManagerThrowNonDatabaseErrorAndCatchOutsideFlow, + commitStatus = CommitStatus.INTERMEDIATE_COMMIT, + numberOfDischarges = 0, + numberOfExpectedEntities = 1 + ) + } + } + @StartableByRPC class EntityManagerSaveEntitiesWithoutAFlushFlow : FlowLogic() { @@ -706,6 +764,74 @@ class FlowEntityManagerTest : AbstractFlowEntityManagerTest() { } } + @StartableByRPC + class EntityManagerSaveAndThrowNonDatabaseErrorFlow : FlowLogic() { + + @Suspendable + override fun call() { + try { + serviceHub.withEntityManager { + persist(entityWithIdOne) + persist(entityWithIdTwo) + persist(entityWithIdThree) + throw RuntimeException("die") + } + } catch (e: RuntimeException) { + logger.info("Caught error") + } + sleep(1.millis) + } + } + + @StartableByRPC + class EntityManagerSaveFlushAndThrowNonDatabaseErrorFlow : FlowLogic() { + + @Suspendable + override fun call() { + try { + serviceHub.withEntityManager { + persist(entityWithIdOne) + persist(entityWithIdTwo) + persist(entityWithIdThree) + flush() + throw RuntimeException("die") + } + } catch (e: RuntimeException) { + logger.info("Caught error") + } + sleep(1.millis) + } + } + + @StartableByRPC + class EntityManagerCatchDatabaseErrorInsideEntityManagerThrowNonDatabaseErrorAndCatchOutsideFlow(private val commitStatus: CommitStatus) : + FlowLogic() { + + @Suspendable + override fun call() { + serviceHub.withEntityManager { + persist(entityWithIdOne) + } + if (commitStatus == CommitStatus.INTERMEDIATE_COMMIT) { + sleep(1.millis) + } + try { + serviceHub.withEntityManager { + persist(anotherEntityWithIdOne) + try { + flush() + } catch (e: PersistenceException) { + logger.info("Caught the exception!") + } + throw RuntimeException("die") + } + } catch (e: RuntimeException) { + logger.info("Caught error") + } + sleep(1.millis) + } + } + @CordaService class MyService(private val services: AppServiceHub) : SingletonSerializeAsToken() { 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 18455a1bbe..9e878fc218 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -183,7 +183,7 @@ import java.sql.Savepoint import java.time.Clock import java.time.Duration import java.time.format.DateTimeParseException -import java.util.* +import java.util.Properties import java.util.concurrent.ExecutorService import java.util.concurrent.Executors import java.util.concurrent.LinkedBlockingQueue @@ -193,8 +193,6 @@ import java.util.concurrent.TimeUnit.MINUTES import java.util.concurrent.TimeUnit.SECONDS import java.util.function.Consumer import javax.persistence.EntityManager -import javax.persistence.PersistenceException -import kotlin.collections.ArrayList /** * A base node implementation that can be customised either for production (with real implementations that do real @@ -1196,6 +1194,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, */ override fun jdbcSession(): Connection = RestrictedConnection(database.createSession()) + @Suppress("TooGenericExceptionCaught") override fun withEntityManager(block: EntityManager.() -> T): T { return database.transaction(useErrorHandler = false) { session.flush() @@ -1210,7 +1209,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, connection.rollback(savepoint) } } - } catch (e: PersistenceException) { + } catch (e: Exception) { if (manager.transaction.rollbackOnly) { connection.rollback(savepoint) } From 4edf61844258b0b7e2663ab91b8b7060d7518c0a Mon Sep 17 00:00:00 2001 From: Stefano Franz Date: Wed, 13 May 2020 16:39:55 +0100 Subject: [PATCH 07/10] remove throttling --- .ci/dev/regression/Jenkinsfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 3bd9886e4e..efb64e7ce3 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -1,8 +1,6 @@ @Library('corda-shared-build-pipeline-steps') import static com.r3.build.BuildControl.killAllExistingBuildsForJob -killAllExistingBuildsForJob(env.JOB_NAME, env.BUILD_NUMBER.toInteger()) - pipeline { agent { label 'k8s' } options { From 5db44790d70fa25936d48c5b335d0ec5e2f96763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Waldemar=20=C5=BBurowski?= <45210402+wzur-r3@users.noreply.github.com> Date: Wed, 13 May 2020 17:10:46 +0100 Subject: [PATCH 08/10] disableConcurrentBuilds --- .ci/dev/regression/Jenkinsfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index efb64e7ce3..70ce2657fb 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -1,11 +1,9 @@ -@Library('corda-shared-build-pipeline-steps') -import static com.r3.build.BuildControl.killAllExistingBuildsForJob - pipeline { agent { label 'k8s' } options { timestamps() buildDiscarder(logRotator(daysToKeepStr: '7', artifactDaysToKeepStr: '7')) + disableConcurrentBuilds() timeout(time: 3, unit: 'HOURS') } From 8387e995357e06c430f8eef0c960faf8070091da Mon Sep 17 00:00:00 2001 From: Denis Rekalov Date: Thu, 14 May 2020 10:53:54 +0100 Subject: [PATCH 09/10] [NOTICK]: Do not use Security.addProvider(BouncyCastleProvider()) in tests to avoid disruptions of other tests (#6250) --- .../net/corda/coretests/crypto/X509NameConstraintsTest.kt | 4 ++-- .../net/corda/node/amqp/CertificateRevocationListNodeTests.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core-tests/src/test/kotlin/net/corda/coretests/crypto/X509NameConstraintsTest.kt b/core-tests/src/test/kotlin/net/corda/coretests/crypto/X509NameConstraintsTest.kt index 98f5e74a18..1b7170173d 100644 --- a/core-tests/src/test/kotlin/net/corda/coretests/crypto/X509NameConstraintsTest.kt +++ b/core-tests/src/test/kotlin/net/corda/coretests/crypto/X509NameConstraintsTest.kt @@ -12,7 +12,6 @@ import org.bouncycastle.asn1.x509.GeneralSubtree import org.bouncycastle.asn1.x509.NameConstraints import org.bouncycastle.jce.provider.BouncyCastleProvider import org.junit.Test -import java.security.Security import java.security.UnrecoverableKeyException import java.security.cert.CertPathValidator import java.security.cert.CertPathValidatorException @@ -95,7 +94,8 @@ class X509NameConstraintsTest { @Test(timeout=300_000) fun `x500 name with correct cn and extra attribute`() { - Security.addProvider(BouncyCastleProvider()) + // Do not use Security.addProvider(BouncyCastleProvider()) to avoid EdDSA signature disruption in other tests. + Crypto.findProvider(BouncyCastleProvider.PROVIDER_NAME) val acceptableNames = listOf("CN=Bank A TLS, UID=", "O=Bank A") .map { GeneralSubtree(GeneralName(X500Name(it))) }.toTypedArray() diff --git a/node/src/integration-test/kotlin/net/corda/node/amqp/CertificateRevocationListNodeTests.kt b/node/src/integration-test/kotlin/net/corda/node/amqp/CertificateRevocationListNodeTests.kt index 7924a06e5c..e941a78aea 100644 --- a/node/src/integration-test/kotlin/net/corda/node/amqp/CertificateRevocationListNodeTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/amqp/CertificateRevocationListNodeTests.kt @@ -58,7 +58,6 @@ import java.math.BigInteger import java.net.InetSocketAddress import java.security.KeyPair import java.security.PrivateKey -import java.security.Security import java.security.cert.X509CRL import java.security.cert.X509Certificate import java.util.* @@ -117,7 +116,8 @@ class CertificateRevocationListNodeTests { @Before fun setUp() { - Security.addProvider(BouncyCastleProvider()) + // Do not use Security.addProvider(BouncyCastleProvider()) to avoid EdDSA signature disruption in other tests. + Crypto.findProvider(BouncyCastleProvider.PROVIDER_NAME) revokedNodeCerts.clear() server = CrlServer(NetworkHostAndPort("localhost", 0)) server.start() From 06467d04b1f5c99a6bea0c748b7981b9e8c7345d Mon Sep 17 00:00:00 2001 From: James Higgs <45565019+JamesHR3@users.noreply.github.com> Date: Thu, 14 May 2020 12:57:59 +0100 Subject: [PATCH 10/10] EG-1980 - Remove stale docs links from OS (#6251) Remove hardcoded docs references, push docs link to gradle --- build.gradle | 2 ++ .../kotlin/net/corda/common/logging/CordaVersion.kt | 1 + .../errorReporting/CordaErrorContextProvider.kt | 13 +------------ .../logging/errorReporting/ErrorReporterImpl.kt | 2 +- .../errorReporting/CordaErrorContextProviderTest.kt | 3 ++- .../logging/errorReporting/ErrorReporterImplTest.kt | 12 ++++++------ .../contracts/TransactionVerificationException.kt | 10 ++-------- .../corda/core/internal/JarSignatureCollector.kt | 2 -- .../internal/TransactionVerifierServiceInternal.kt | 2 -- .../internal/rules/TargetVersionDependentRules.kt | 2 -- .../internal/AttachmentsClassLoader.kt | 3 +-- .../core/transactions/MissingContractAttachments.kt | 3 +-- .../nodeapi/internal/persistence/SchemaMigration.kt | 3 +-- .../kotlin/net/corda/node/internal/AbstractNode.kt | 5 ++--- .../net/corda/node/internal/CheckpointVerifier.kt | 9 ++++----- .../kotlin/net/corda/node/internal/NodeStartup.kt | 5 +---- .../services/statemachine/FlowStateMachineImpl.kt | 2 +- .../SingleThreadedStateMachineManager.kt | 3 +-- .../services/vault/HibernateQueryCriteriaParser.kt | 3 +-- .../corda/testing/core/JarSignatureCollectorTest.kt | 2 -- 20 files changed, 28 insertions(+), 59 deletions(-) diff --git a/build.gradle b/build.gradle index 833766c97f..e7d5dd3c84 100644 --- a/build.gradle +++ b/build.gradle @@ -152,6 +152,7 @@ buildscript { "unknown" } }() + ext.corda_docs_link = "https://docs.corda.net/docs/corda-os/$baseVersion" repositories { mavenLocal() mavenCentral() @@ -309,6 +310,7 @@ allprojects { attributes('Corda-Revision': corda_revision) attributes('Corda-Vendor': 'Corda Open Source') attributes('Automatic-Module-Name': "net.corda.${task.project.name.replaceAll('-', '.')}") + attributes('Corda-Docs-Link': corda_docs_link) } } diff --git a/common/logging/src/main/kotlin/net/corda/common/logging/CordaVersion.kt b/common/logging/src/main/kotlin/net/corda/common/logging/CordaVersion.kt index 083f0a078a..2e24a79a1c 100644 --- a/common/logging/src/main/kotlin/net/corda/common/logging/CordaVersion.kt +++ b/common/logging/src/main/kotlin/net/corda/common/logging/CordaVersion.kt @@ -13,6 +13,7 @@ class CordaVersion { val revision: String by lazy { manifestValue("Corda-Revision") ?: UNKNOWN } val vendor: String by lazy { manifestValue("Corda-Vendor") ?: UNKNOWN } val platformVersion: Int by lazy { manifestValue("Corda-Platform-Version")?.toInt() ?: 1 } + val docsLink: String by lazy { manifestValue("Corda-Docs-Link") ?: UNKNOWN } internal val semanticVersion: String by lazy { if(releaseVersion == UNKNOWN) CURRENT_MAJOR_RELEASE else releaseVersion } } diff --git a/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/CordaErrorContextProvider.kt b/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/CordaErrorContextProvider.kt index 17c9cdba82..d7d3e333a4 100644 --- a/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/CordaErrorContextProvider.kt +++ b/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/CordaErrorContextProvider.kt @@ -11,21 +11,10 @@ import java.util.* class CordaErrorContextProvider : ErrorContextProvider { companion object { - private const val BASE_URL = "https://docs.corda.net/docs" - private const val OS_PAGES = "corda-os" - private const val ENTERPRISE_PAGES = "corda-enterprise" private const val ERROR_CODE_PAGE = "error-codes.html" } override fun getURL(locale: Locale): String { - val versionNumber = CordaVersion.releaseVersion - - // This slightly strange block here allows the code to be merged across to Enterprise with no changes. - val productVersion = if (CordaVersion.platformEditionCode == "OS") { - OS_PAGES - } else { - ENTERPRISE_PAGES - } - return "$BASE_URL/$productVersion/$versionNumber/$ERROR_CODE_PAGE" + return "${CordaVersion.docsLink}/$ERROR_CODE_PAGE" } } \ No newline at end of file diff --git a/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/ErrorReporterImpl.kt b/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/ErrorReporterImpl.kt index ae6c8b9266..0e508959e8 100644 --- a/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/ErrorReporterImpl.kt +++ b/common/logging/src/main/kotlin/net/corda/common/logging/errorReporting/ErrorReporterImpl.kt @@ -25,7 +25,7 @@ internal class ErrorReporterImpl(private val resourceLocation: String, val resource = "$resourceLocation/$ERROR_INFO_RESOURCE" val codeMessage = fetchAndFormat(resource, ERROR_CODE_MESSAGE, arrayOf(error.formatCode())) val urlMessage = fetchAndFormat(resource, ERROR_CODE_URL, arrayOf(errorContextProvider.getURL(locale))) - return "[$codeMessage, $urlMessage]" + return "[$codeMessage $urlMessage]" } override fun report(error: ErrorCode<*>, logger: Logger) { diff --git a/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/CordaErrorContextProviderTest.kt b/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/CordaErrorContextProviderTest.kt index 85dcf4d73b..ee720716d1 100644 --- a/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/CordaErrorContextProviderTest.kt +++ b/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/CordaErrorContextProviderTest.kt @@ -11,7 +11,8 @@ class CordaErrorContextProviderTest { @Test(timeout = 300_000) fun `check that correct URL is returned from context provider`() { val context = CordaErrorContextProvider() - val expectedURL = "https://docs.corda.net/docs/corda-os/${CordaVersion.releaseVersion}/error-codes.html" + val version = CordaVersion.releaseVersion.substringBefore("-") // Remove SNAPSHOT if present + val expectedURL = "https://docs.corda.net/docs/corda-os/$version/error-codes.html" // In this first release, there is only one localisation and the URL structure for future localisations is currently unknown. As // a result, the same URL is expected for all locales. assertEquals(expectedURL, context.getURL(Locale.getDefault())) diff --git a/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/ErrorReporterImplTest.kt b/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/ErrorReporterImplTest.kt index 38192f81ad..40efb4e164 100644 --- a/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/ErrorReporterImplTest.kt +++ b/common/logging/src/test/kotlin/net/corda/commmon/logging/errorReporting/ErrorReporterImplTest.kt @@ -74,7 +74,7 @@ class ErrorReporterImplTest { val error = TEST_ERROR_1 val testReporter = createReporterImpl("en-US") testReporter.report(error, loggerMock) - assertEquals(listOf("This is a test message [Code: test-case1, URL: $TEST_URL/en-US]"), logs) + assertEquals(listOf("This is a test message [Code: test-case1 URL: $TEST_URL/en-US]"), logs) } @Test(timeout = 300_00) @@ -84,7 +84,7 @@ class ErrorReporterImplTest { val testReporter = createReporterImpl("en-US") testReporter.report(error, loggerMock) val format = DateFormat.getDateInstance(DateFormat.LONG, Locale.forLanguageTag("en-US")) - assertEquals(listOf("This is the second case with string foo, number 1, date ${format.format(currentDate)} [Code: test-case2, URL: $TEST_URL/en-US]"), logs) + assertEquals(listOf("This is the second case with string foo, number 1, date ${format.format(currentDate)} [Code: test-case2 URL: $TEST_URL/en-US]"), logs) } @Test(timeout = 300_000) @@ -92,7 +92,7 @@ class ErrorReporterImplTest { val error = TEST_ERROR_1 val testReporter = createReporterImpl("fr-FR") testReporter.report(error, loggerMock) - assertEquals(listOf("This is a test message [Code: test-case1, URL: $TEST_URL/fr-FR]"), logs) + assertEquals(listOf("This is a test message [Code: test-case1 URL: $TEST_URL/fr-FR]"), logs) } @Test(timeout = 300_000) @@ -100,7 +100,7 @@ class ErrorReporterImplTest { val error = TEST_ERROR_1 val testReporter = createReporterImpl("ga-IE") testReporter.report(error, loggerMock) - assertEquals(listOf("Is teachtaireacht earráide é seo [Code: test-case1, URL: $TEST_URL/ga-IE]"), logs) + assertEquals(listOf("Is teachtaireacht earráide é seo [Code: test-case1 URL: $TEST_URL/ga-IE]"), logs) } @Test(timeout = 300_000) @@ -108,7 +108,7 @@ class ErrorReporterImplTest { val error = TEST_ERROR_1 val testReporter = createReporterImpl("es-ES") testReporter.report(error, loggerMock) - assertEquals(listOf("This is a test message [Code: test-case1, URL: $TEST_URL/es-ES]"), logs) + assertEquals(listOf("This is a test message [Code: test-case1 URL: $TEST_URL/es-ES]"), logs) } @Test(timeout = 300_000) @@ -116,6 +116,6 @@ class ErrorReporterImplTest { val error = TEST_ERROR_3 val testReporter = createReporterImpl("en-US") testReporter.report(error, loggerMock) - assertEquals(listOf("This is the third test message [Code: test-case-3, URL: $TEST_URL/en-US]"), logs) + assertEquals(listOf("This is the third test message [Code: test-case-3 URL: $TEST_URL/en-US]"), logs) } } \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt b/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt index 0532199d0a..9e243277bc 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt @@ -229,8 +229,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S """ State of class ${state.data ::class.java.typeName} belongs to contract $requiredContractClassName, but is bundled in TransactionState with ${state.contract}. - - For details see: https://docs.corda.net/api-contract-constraints.html#contract-state-agreement """.trimIndent().replace('\n', ' ')) } @@ -243,8 +241,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S State of class ${state.data::class.java.typeName} does not have a specified owning contract. Add the @BelongsToContract annotation to this class to ensure that it can only be bundled in a TransactionState with the correct contract. - - For details see: https://docs.corda.net/api-contract-constraints.html#contract-state-agreement """.trimIndent()) } @@ -331,8 +327,7 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S */ class PackageOwnershipException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId, @Suppress("unused") val invalidClassName: String, val packageName: String) : TransactionVerificationException(txId, """The attachment JAR: $attachmentHash containing the class: $invalidClassName is not signed by the owner of package $packageName specified in the network parameters. - Please check the source of this attachment and if it is malicious contact your zone operator to report this incident. - For details see: https://docs.corda.net/network-map.html#network-parameters""".trimIndent(), null) + Please check the source of this attachment and if it is malicious contact your zone operator to report this incident.""".trimIndent(), null) class InvalidAttachmentException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId) : TransactionVerificationException(txId, "The attachment $attachmentHash is not a valid ZIP or JAR file.".trimIndent(), null) @@ -345,8 +340,7 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S class UntrustedAttachmentsException(val txId: SecureHash, val ids: List) : CordaException("Attempting to load untrusted transaction attachments: $ids. " + "At this time these are not loadable because the DJVM sandbox has not yet been integrated. " + - "You will need to manually install the CorDapp to whitelist it for use. " + - "Please follow the operational steps outlined in https://docs.corda.net/cordapp-build-systems.html#cordapp-contract-attachments to learn more and continue.") + "You will need to manually install the CorDapp to whitelist it for use.") /* If you add a new class extending [TransactionVerificationException], please add a test in `TransactionVerificationExceptionSerializationTests` diff --git a/core/src/main/kotlin/net/corda/core/internal/JarSignatureCollector.kt b/core/src/main/kotlin/net/corda/core/internal/JarSignatureCollector.kt index 5357cfbae6..6132dec45d 100644 --- a/core/src/main/kotlin/net/corda/core/internal/JarSignatureCollector.kt +++ b/core/src/main/kotlin/net/corda/core/internal/JarSignatureCollector.kt @@ -52,8 +52,6 @@ object JarSignatureCollector { """ Mismatch between signers ${firstSignerSet.toOrderedPublicKeys()} for file $firstFile and signers ${otherSignerSet.toOrderedPublicKeys()} for file ${otherFile}. - See https://docs.corda.net/api-contract-constraints.html#signature-constraints for details of the - constraints applied to attachment signatures. """.trimIndent().replace('\n', ' ')) } return firstSignerSet diff --git a/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt b/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt index 32dd39be5f..ab45b2c464 100644 --- a/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt +++ b/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt @@ -265,8 +265,6 @@ abstract class Verifier(val ltx: LedgerTransaction, protected val transactionCla logger.warnOnce(""" State of class ${state.data::class.java.typeName} belongs to contract $requiredContractClassName, but is bundled in TransactionState with ${state.contract}. - - For details see: https://docs.corda.net/api-contract-constraints.html#contract-state-agreement """.trimIndent().replace('\n', ' ')) } } diff --git a/core/src/main/kotlin/net/corda/core/internal/rules/TargetVersionDependentRules.kt b/core/src/main/kotlin/net/corda/core/internal/rules/TargetVersionDependentRules.kt index eb684db047..63f4f5372d 100644 --- a/core/src/main/kotlin/net/corda/core/internal/rules/TargetVersionDependentRules.kt +++ b/core/src/main/kotlin/net/corda/core/internal/rules/TargetVersionDependentRules.kt @@ -32,8 +32,6 @@ object StateContractValidationEnforcementRule { Unable to determine JAR location for contract state class ${state::class.java.name}, and consequently unable to determine target platform version. Enforcing state/contract agreement validation by default. - - For details see: https://docs.corda.net/api-contract-constraints.html#contract-state-agreement """.trimIndent().replace("\n", " ")) return true } diff --git a/core/src/main/kotlin/net/corda/core/serialization/internal/AttachmentsClassLoader.kt b/core/src/main/kotlin/net/corda/core/serialization/internal/AttachmentsClassLoader.kt index e4b00a6c8b..1851cd0eb8 100644 --- a/core/src/main/kotlin/net/corda/core/serialization/internal/AttachmentsClassLoader.kt +++ b/core/src/main/kotlin/net/corda/core/serialization/internal/AttachmentsClassLoader.kt @@ -116,8 +116,7 @@ class AttachmentsClassLoader(attachments: List, if (untrusted.isNotEmpty()) { log.warn("Cannot verify transaction $sampleTxId as the following attachment IDs are untrusted: $untrusted." + - "You will need to manually install the CorDapp to whitelist it for use. " + - "Please follow the operational steps outlined in https://docs.corda.net/cordapp-build-systems.html#cordapp-contract-attachments to learn more and continue.") + "You will need to manually install the CorDapp to whitelist it for use.") throw TransactionVerificationException.UntrustedAttachmentsException(sampleTxId, untrusted) } diff --git a/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt b/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt index cdb3aed810..ddcd01728f 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt @@ -18,5 +18,4 @@ class MissingContractAttachments @JvmOverloads constructor(val states: List>, contractsClassName: String? = null, minimumRequiredContractClassVersion: Version? = null) : FlowException( "Cannot find contract attachments for " + - "${contractsClassName ?: states.map { it.contract }.distinct()}${minimumRequiredContractClassVersion?.let { ", minimum required contract class version $minimumRequiredContractClassVersion"}}. " + - "See https://docs.corda.net/api-contract-constraints.html#debugging") + "${contractsClassName ?: states.map { it.contract }.distinct()}${minimumRequiredContractClassVersion?.let { ", minimum required contract class version $minimumRequiredContractClassVersion"}}.") diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt index b93d5de731..47a8f5a801 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt @@ -265,8 +265,7 @@ class OutstandingDatabaseChangesException(@Suppress("MemberVisibilityCanBePrivat class CheckpointsException : DatabaseMigrationException("Attempting to update the database while there are flows in flight. " + "This is dangerous because the node might not be able to restore the flows correctly and could consequently fail. " + - "Updating the database would make reverting to the previous version more difficult. " + - "Please drain your node first. See: https://docs.corda.net/upgrading-cordapps.html#flow-drains") + "Updating the database would make reverting to the previous version more difficult.") class DatabaseIncompatibleException(@Suppress("MemberVisibilityCanBePrivate") private val reason: String) : DatabaseMigrationException(errorMessageFor(reason)) { internal companion object { 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 9e878fc218..9c015067e3 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -910,8 +910,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, requireNotNull(getCertificateStores()) { "One or more keyStores (identity or TLS) or trustStore not found. " + "Please either copy your existing keys and certificates from another node, " + - "or if you don't have one yet, fill out the config file and run corda.jar initial-registration. " + - "Read more at: https://docs.corda.net/permissioning.html" + "or if you don't have one yet, fill out the config file and run corda.jar initial-registration." } } catch (e: KeyStoreException) { throw IllegalArgumentException("At least one of the keystores or truststore passwords does not match configuration.") @@ -1358,7 +1357,7 @@ fun CordaPersistence.startHikariPool(hikariProperties: Properties, databaseConfi NodeDatabaseErrors.COULD_NOT_CONNECT, cause = ex) ex.cause is ClassNotFoundException -> throw CouldNotCreateDataSourceException( - "Could not find the database driver class. Please add it to the 'drivers' folder. See: https://docs.corda.net/corda-configuration-file.html", + "Could not find the database driver class. Please add it to the 'drivers' folder.", NodeDatabaseErrors.MISSING_DRIVER) ex is OutstandingDatabaseChangesException -> throw (DatabaseIncompatibleException(ex.message)) else -> diff --git a/node/src/main/kotlin/net/corda/node/internal/CheckpointVerifier.kt b/node/src/main/kotlin/net/corda/node/internal/CheckpointVerifier.kt index 901d853109..acde0a1a9b 100644 --- a/node/src/main/kotlin/net/corda/node/internal/CheckpointVerifier.kt +++ b/node/src/main/kotlin/net/corda/node/internal/CheckpointVerifier.kt @@ -84,19 +84,18 @@ object CheckpointVerifier { sealed class CheckpointIncompatibleException(override val message: String) : Exception() { class CannotBeDeserialisedException(val e: Exception) : CheckpointIncompatibleException( "Found checkpoint that cannot be deserialised using the current Corda version. Please revert to the previous version of Corda, " + - "drain your node (see https://docs.corda.net/upgrading-cordapps.html#flow-drains), and try again. Cause: ${e.message}") + "drain your node, and try again. Cause: ${e.message}") class SubFlowCoreVersionIncompatibleException(val flowClass: Class>, oldVersion: Int) : CheckpointIncompatibleException( "Found checkpoint for flow: $flowClass that is incompatible with the current Corda platform. Please revert to the previous " + - "version of Corda (version $oldVersion), drain your node (see https://docs.corda.net/upgrading-cordapps.html#flow-drains), and try again.") + "version of Corda (version $oldVersion), drain your node, and try again.") class FlowVersionIncompatibleException(val flowClass: Class>, val cordapp: Cordapp, oldHash: SecureHash) : CheckpointIncompatibleException( "Found checkpoint for flow: $flowClass that is incompatible with the current installed version of ${cordapp.name}. " + - "Please reinstall the previous version of the CorDapp (with hash: $oldHash), drain your node " + - "(see https://docs.corda.net/upgrading-cordapps.html#flow-drains), and try again.") + "Please reinstall the previous version of the CorDapp (with hash: $oldHash), drain your node, and try again.") class CordappNotInstalledException(classNotFound: String) : CheckpointIncompatibleException( "Found checkpoint for CorDapp that is no longer installed. Specifically, could not find class $classNotFound. Please install the " + - "missing CorDapp, drain your node (see https://docs.corda.net/upgrading-cordapps.html#flow-drains), and try again.") + "missing CorDapp, drain your node, and try again.") } 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 5c5e13e5ce..d9167e2816 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -334,7 +334,6 @@ open class NodeStartup : NodeStartupLogging { if (!certDirectory.isDirectory()) { printError("Unable to access certificates directory ${certDirectory}. This could be because the node has not been registered with the Identity Operator.") - printError("Please see https://docs.corda.net/joining-a-compatibility-zone.html for more information.") printError("Node will now shutdown.") return false } @@ -350,9 +349,7 @@ open class NodeStartup : NodeStartupLogging { // // Also see https://bugs.openjdk.java.net/browse/JDK-8143378 val messages = listOf( - "Your computer took over a second to resolve localhost due an incorrect configuration. Corda will work but start very slowly until this is fixed. ", - "Please see https://docs.corda.net/troubleshooting.html#slow-localhost-resolution for information on how to fix this. ", - "It will only take a few seconds for you to resolve." + "Your computer took over a second to resolve localhost due an incorrect configuration. Corda will work but start very slowly until this is fixed." ) logger.warn(messages.joinToString("")) Emoji.renderIfSupported { diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt index 90362ac58e..b86aae1d81 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt @@ -563,7 +563,7 @@ val Class>.flowVersionAndInitiatingClass: Pair if (message.contains("Not an entity")) throw VaultQueryException(""" - Please register the entity '${entityStateClass.name}' - See https://docs.corda.net/api-persistence.html#custom-schema-registration for more information""") + Please register the entity '${entityStateClass.name}'.""") } throw VaultQueryException("Parsing error: ${e.message}") } diff --git a/testing/test-utils/src/test/kotlin/net/corda/testing/core/JarSignatureCollectorTest.kt b/testing/test-utils/src/test/kotlin/net/corda/testing/core/JarSignatureCollectorTest.kt index c22083f2e3..ab7946e768 100644 --- a/testing/test-utils/src/test/kotlin/net/corda/testing/core/JarSignatureCollectorTest.kt +++ b/testing/test-utils/src/test/kotlin/net/corda/testing/core/JarSignatureCollectorTest.kt @@ -112,8 +112,6 @@ class JarSignatureCollectorTest { """ Mismatch between signers [O=Alice Corp, L=Madrid, C=ES, O=Bob Plc, L=Rome, C=IT] for file _signable1 and signers [O=Bob Plc, L=Rome, C=IT] for file _signable2. - See https://docs.corda.net/api-contract-constraints.html#signature-constraints for details of the - constraints applied to attachment signatures. """.trimIndent().replace('\n', ' ') ) { dir.getJarSigners(FILENAME) } }