From b89eedb74432daa306b848625106bad6147ece68 Mon Sep 17 00:00:00 2001 From: ConnelMcGovern Date: Wed, 23 Mar 2022 16:51:48 +0000 Subject: [PATCH 1/6] INFRA-1743 Activate C4 email notifications Open source and Ent --- .ci/dev/regression/Jenkinsfile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 28a1dca022..63eda83925 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -407,6 +407,22 @@ pipeline { } } } + failure { + script { + def statusSymbol = '\u274c' + if (isReleaseTag || isReleaseBranch || isReleaseCandidate) { + emailext subject: "$statusSymbol " + '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!', + body: '${SCRIPT, template="groovy-html.template"}', + recipientProviders: [ + [$class: 'CulpritsRecipientProvider'], + [$class: 'RequesterRecipientProvider'] + ], + mimeType: 'text/html', + replyTo: '$DEFAULT_REPLYTO', + to: "adel.el-beik@r3.com" + } + } + } cleanup { deleteDir() /* clean up our workspace */ } From af1dbf4c6d8cb71c0549ca22a729dea919601966 Mon Sep 17 00:00:00 2001 From: Ulrik Rasmussen Date: Thu, 28 Apr 2022 11:35:33 +0200 Subject: [PATCH 2/6] Do not emit warning when StatePointer.isResolved = false The warning is misleading because it is emitted in the case where the ServiceHub reference is not null but one or more state pointers were configured to not be automatically resolved by the transaction builder. --- .../net/corda/core/transactions/TransactionBuilder.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt index 71fb6c728b..c05f378223 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt @@ -741,9 +741,11 @@ open class TransactionBuilder( addReferenceState(resolvedStateAndRef.referenced()) } } else { - log.warn("WARNING: You must pass in a ServiceHub reference to TransactionBuilder to resolve " + - "state pointers outside of flows. If you are writing a unit test then pass in a " + - "MockServices instance.") + if (nextStatePointer.isResolved) { + log.warn("WARNING: You must pass in a ServiceHub reference to TransactionBuilder to resolve " + + "state pointers outside of flows. If you are writing a unit test then pass in a " + + "MockServices instance.") + } return } } From 5b1e1bc8d0038cdd873c586655577f612743ae16 Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Mon, 9 May 2022 13:22:35 +0100 Subject: [PATCH 3/6] INFRA-1743 E-mail & Slack notifications --- .ci/dev/regression/Jenkinsfile | 47 ++++++++++------------------------ 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 63eda83925..977015e75f 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -3,6 +3,7 @@ * Jenkins pipeline to build Corda OS release branches and tags. * PLEASE NOTE: we DO want to run a build for each commit!!! */ +@Library('corda-shared-build-pipeline-steps') /** * Sense environment @@ -41,17 +42,6 @@ def nexusIqStageChoices = [nexusDefaultIqStage].plus( 'operate' ].minus([nexusDefaultIqStage])) -/** - * define an empty teamsWebHookURL and if it is a Release Branch - * then set it for the Corda 4 Jenkins Connector - */ -def teamsWebHookURL = "" -if (isReleaseBranch || isReleaseTag){ - withCredentials([string(credentialsId: 'ms-teams-webhook', variable: 'webhook_url')]) { - teamsWebHookURL = "$webhook_url" - } -} - /** * Common Gradle arguments for all Gradle executions */ @@ -74,18 +64,6 @@ pipeline { parallelsAlwaysFailFast() timeout(time: 6, unit: 'HOURS') timestamps() - office365ConnectorWebhooks([[ - name : "Corda 4 Jenkins Connector", - notifyBackToNormal : true, - startNotification : false, - notifyFailure : true, - notifySuccess : true, - notifyNotBuilt : false, - notifyAborted : false, - notifyRepeatedFailure: true, - notifyUnstable : true, - url : "${teamsWebHookURL}" - ]]) } parameters { @@ -102,6 +80,7 @@ pipeline { CORDA_ARTIFACTORY_PASSWORD = "${env.ARTIFACTORY_CREDENTIALS_PSW}" CORDA_ARTIFACTORY_USERNAME = "${env.ARTIFACTORY_CREDENTIALS_USR}" DOCKER_URL = "https://index.docker.io/v1/" + EMAIL_RECIPIENTS = credentials('corda4-email-recipient') } stages { @@ -407,19 +386,21 @@ pipeline { } } } + success { + script { + sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") + } + } + unstable { + script { + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") + } + } failure { script { - def statusSymbol = '\u274c' + sendSlackNotifications("danger", "BUILD FAILURE", true, "#corda-corda4-open-source-build-notifications") if (isReleaseTag || isReleaseBranch || isReleaseCandidate) { - emailext subject: "$statusSymbol " + '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!', - body: '${SCRIPT, template="groovy-html.template"}', - recipientProviders: [ - [$class: 'CulpritsRecipientProvider'], - [$class: 'RequesterRecipientProvider'] - ], - mimeType: 'text/html', - replyTo: '$DEFAULT_REPLYTO', - to: "adel.el-beik@r3.com" + sendEmailNotifications("${env.EMAIL_RECIPIENTS}") } } } From 99e2991bc30b24913bed87c0b5f5b17bbe8ccff2 Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Mon, 9 May 2022 16:15:53 +0100 Subject: [PATCH 4/6] Update Jenkinsfile --- .ci/dev/regression/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 977015e75f..1636250e98 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -388,12 +388,12 @@ pipeline { } success { script { - sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("good", "BUILD PASSED", true, "#corda-corda4-open-source-build-notifications") } } unstable { script { - sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", true, "#corda-corda4-open-source-build-notifications") } } failure { From 2f82660cdbfeb31c8e090ecdbe68bd49befe413b Mon Sep 17 00:00:00 2001 From: Connel McGovern <100574906+mcgovc@users.noreply.github.com> Date: Wed, 11 May 2022 14:22:46 +0100 Subject: [PATCH 5/6] NOTICK Remove Slack tagging on successful/unstable builds --- .ci/dev/regression/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/dev/regression/Jenkinsfile b/.ci/dev/regression/Jenkinsfile index 1636250e98..977015e75f 100644 --- a/.ci/dev/regression/Jenkinsfile +++ b/.ci/dev/regression/Jenkinsfile @@ -388,12 +388,12 @@ pipeline { } success { script { - sendSlackNotifications("good", "BUILD PASSED", true, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("good", "BUILD PASSED", false, "#corda-corda4-open-source-build-notifications") } } unstable { script { - sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", true, "#corda-corda4-open-source-build-notifications") + sendSlackNotifications("warning", "BUILD UNSTABLE - Unstable Builds are likely a result of Nexus Sonar Scanner violations", false, "#corda-corda4-open-source-build-notifications") } } failure { From 57ddafa1486a62cc081f2dd38032284356592f02 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Fri, 13 May 2022 17:09:56 +0100 Subject: [PATCH 6/6] ENT-6532: Close any deserialization classloader that is evicted from the cache. Also revert disabling caches when reading URLs. --- .../internal/AttachmentsClassLoader.kt | 14 +++++++++++++- .../kotlin/net/corda/node/internal/AbstractNode.kt | 11 +---------- .../net/corda/node/utilities/NodeNamedCache.kt | 7 ++++--- 3 files changed, 18 insertions(+), 14 deletions(-) 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 0a287a7f7d..6c8279a1e8 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 @@ -32,6 +32,7 @@ import net.corda.core.serialization.internal.AttachmentURLStreamHandlerFactory.t import net.corda.core.serialization.withWhitelist import net.corda.core.utilities.contextLogger import net.corda.core.utilities.debug +import net.corda.core.utilities.loggerFor import java.io.IOException import java.io.InputStream import java.lang.ref.WeakReference @@ -470,7 +471,18 @@ interface AttachmentsClassLoaderCache { @DeleteForDJVM class AttachmentsClassLoaderCacheImpl(cacheFactory: NamedCacheFactory) : SingletonSerializeAsToken(), AttachmentsClassLoaderCache { - private val cache: Cache = cacheFactory.buildNamed(Caffeine.newBuilder(), "AttachmentsClassLoader_cache") + private val cache: Cache = cacheFactory.buildNamed( + // Close deserialization classloaders when we evict them + // to release any resources they may be holding. + @Suppress("TooGenericExceptionCaught") + Caffeine.newBuilder().removalListener { key, context, _ -> + try { + (context?.deserializationClassLoader as? AutoCloseable)?.close() + } catch (e: Exception) { + loggerFor().warn("Error destroying serialization context for $key", e) + } + }, "AttachmentsClassLoader_cache" + ) override fun computeIfAbsent(key: AttachmentsClassLoaderKey, mappingFunction: Function): SerializationContext { return cache.get(key, mappingFunction) ?: throw NullPointerException("null returned from cache mapping function") 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 10bc96a666..32a7c15ef2 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -173,13 +173,12 @@ import org.jolokia.jvmagent.JolokiaServerConfig import org.slf4j.Logger import rx.Scheduler import java.lang.reflect.InvocationTargetException -import java.net.URLConnection import java.sql.Connection 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 @@ -238,7 +237,6 @@ abstract class AbstractNode(val configuration: NodeConfiguration, } quasarExcludePackages(configuration) - disableURLConnectionCache() if (allowHibernateToManageAppSchema && !configuration.devMode) { throw ConfigurationException("Hibernate can only be used to manage app schema in development while using dev mode. " + @@ -427,13 +425,6 @@ abstract class AbstractNode(val configuration: NodeConfiguration, } } - private fun disableURLConnectionCache() { - object : URLConnection(null) { - override fun connect() { - } - }.defaultUseCaches = false - } - private fun quasarExcludePackages(nodeConfiguration: NodeConfiguration) { val quasarInstrumentor = Retransform.getInstrumentor() diff --git a/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt b/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt index e43b2ab7ee..9c2e2eaf93 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt @@ -33,7 +33,8 @@ open class DefaultNamedCacheFactory protected constructor(private val metricRegi override fun bindWithMetrics(metricRegistry: MetricRegistry): BindableNamedCacheFactory = DefaultNamedCacheFactory(metricRegistry, this.nodeConfiguration) override fun bindWithConfig(nodeConfiguration: NodeConfiguration): BindableNamedCacheFactory = DefaultNamedCacheFactory(this.metricRegistry, nodeConfiguration) - open protected fun configuredForNamed(caffeine: Caffeine, name: String): Caffeine { + @Suppress("ComplexMethod") + protected open fun configuredForNamed(caffeine: Caffeine, name: String): Caffeine { return with(nodeConfiguration!!) { when { name.startsWith("RPCSecurityManagerShiroCache_") -> with(security?.authService?.options?.cache!!) { caffeine.maximumSize(maxEntries).expireAfterWrite(expireAfterSecs, TimeUnit.SECONDS) } @@ -84,7 +85,7 @@ open class DefaultNamedCacheFactory protected constructor(private val metricRegi return configuredForNamed(caffeine, name).build(loader) } - open protected val defaultCacheSize = 1024L + protected open val defaultCacheSize = 1024L private val defaultAttachmentsClassLoaderCacheSize = defaultCacheSize / CACHE_SIZE_DENOMINATOR } -private const val CACHE_SIZE_DENOMINATOR = 4L \ No newline at end of file +private const val CACHE_SIZE_DENOMINATOR = 4L