Infra-656 - NoSuchFileException in NodeInfoWatcher fix (#6672)

* Filter out tmp files

* Ignore .tmp files

* Ignore .tmp files

* Remove unused import
This commit is contained in:
Dries Samyn 2020-08-27 16:41:25 +01:00 committed by GitHub
parent 9a018e7bee
commit d08b62da39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 4 deletions

View File

@ -41,17 +41,20 @@ class NodeInfoWatcher(private val nodePath: Path,
private val logger = contextLogger() private val logger = contextLogger()
// TODO This method doesn't belong in this class // TODO This method doesn't belong in this class
fun saveToFile(path: Path, nodeInfoAndSigned: NodeInfoAndSigned) { fun saveToFile(path: Path, nodeInfoAndSigned: NodeInfoAndSigned): Path {
// By using the hash of the node's first name we ensure: // By using the hash of the node's first name we ensure:
// 1) node info files for the same node map to the same filename and thus avoid having duplicate files for // 1) node info files for the same node map to the same filename and thus avoid having duplicate files for
// the same node // the same node
// 2) avoid having to deal with characters in the X.500 name which are incompatible with the local filesystem // 2) avoid having to deal with characters in the X.500 name which are incompatible with the local filesystem
val fileNameHash = nodeInfoAndSigned.nodeInfo.legalIdentities[0].name.serialize().hash val fileNameHash = nodeInfoAndSigned.nodeInfo.legalIdentities[0].name.serialize().hash
val target = path / "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}$fileNameHash"
nodeInfoAndSigned nodeInfoAndSigned
.signed .signed
.serialize() .serialize()
.open() .open()
.copyTo(path / "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}$fileNameHash", REPLACE_EXISTING) .copyTo(target, REPLACE_EXISTING)
return target
} }
} }
@ -85,7 +88,7 @@ class NodeInfoWatcher(private val nodePath: Path,
logger.debug { "Examining $it" } logger.debug { "Examining $it" }
true true
} }
.filter { !it.endsWith(".tmp") } .filter { !it.toString().endsWith(".tmp") }
.filter { it.isRegularFile() } .filter { it.isRegularFile() }
.filter { file -> .filter { file ->
val lastModifiedTime = file.lastModifiedTime() val lastModifiedTime = file.lastModifiedTime()

View File

@ -7,11 +7,11 @@ import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.size import net.corda.core.internal.size
import net.corda.core.node.services.KeyManagementService import net.corda.core.node.services.KeyManagementService
import net.corda.coretesting.internal.createNodeInfoAndSigned
import net.corda.nodeapi.internal.NodeInfoAndSigned import net.corda.nodeapi.internal.NodeInfoAndSigned
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier import net.corda.nodeapi.internal.network.NodeInfoFilesCopier
import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.coretesting.internal.createNodeInfoAndSigned
import net.corda.testing.node.internal.MockKeyManagementService import net.corda.testing.node.internal.MockKeyManagementService
import net.corda.testing.node.makeTestIdentityService import net.corda.testing.node.makeTestIdentityService
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@ -21,7 +21,9 @@ import org.junit.Test
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import rx.observers.TestSubscriber import rx.observers.TestSubscriber
import rx.schedulers.TestScheduler import rx.schedulers.TestScheduler
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -132,6 +134,31 @@ class NodeInfoWatcherTest {
} }
} }
@Test(timeout=300_000)
fun `ignore tmp files`() {
nodeInfoPath.createDirectories()
// Start polling with an empty folder.
val subscription = nodeInfoWatcher.nodeInfoUpdates().subscribe(testSubscriber)
try {
// Ensure the watch service is started.
advanceTime()
// create file
// boohoo, we shouldn't create real files, instead mock Path
val file = NodeInfoWatcher.saveToFile(nodeInfoPath, nodeInfoAndSigned)
Files.move(file, Paths.get("$file.tmp"))
advanceTime()
// Check no nodeInfos are read.
assertEquals(0, testSubscriber.onNextEvents.distinct().flatten().size)
} finally {
subscription.unsubscribe()
}
}
private fun advanceTime() { private fun advanceTime() {
scheduler.advanceTimeBy(1, TimeUnit.MINUTES) scheduler.advanceTimeBy(1, TimeUnit.MINUTES)
} }