diff --git a/build.gradle b/build.gradle index 7578f0a3fd..1a291b7279 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { file("publish.properties").withInputStream { props.load(it) } // Our version: bump this on release. - ext.corda_version = "0.8.1" + ext.corda_version = "0.8.2" ext.gradle_plugins_version = props.getProperty("gradlePluginsVersion") // Dependency versions. Can run 'gradle dependencyUpdates' to find new versions of things. diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index aba12670e0..f8a678471a 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -15,6 +15,7 @@ import net.corda.core.node.services.Vault import net.corda.core.transactions.SignedTransaction import rx.Observable import java.io.InputStream +import java.io.OutputStream import java.time.Instant data class StateMachineInfo( @@ -98,6 +99,11 @@ interface CordaRPCOps : RPCOps { */ fun attachmentExists(id: SecureHash): Boolean + /** + * Download an attachment JAR by ID + */ + fun openAttachment(id: SecureHash): InputStream + /** * Uploads a jar to the node, returns it's hash. */ diff --git a/docs/source/getting-set-up-fault-finding.rst b/docs/source/getting-set-up-fault-finding.rst index a3de482eb7..5f2b1c3038 100644 --- a/docs/source/getting-set-up-fault-finding.rst +++ b/docs/source/getting-set-up-fault-finding.rst @@ -6,7 +6,7 @@ Milestone releases When you clone the corda or cordapp-template repos, they will default to the master branch. The master branch is being continuously developed upon, and its features may not align with the state of Corda as described in the docs. Additionally, the master branch of the CorDapp Template may break in response to changes in the main corda repo. -When developing on Corda, you should always check out the latest stable release tag instead, by running ``git checkout release-M8.1``. +When developing on Corda, you should always check out the latest stable release tag instead, by running ``git checkout release-M8.2``. Java issues ----------- diff --git a/docs/source/getting-set-up.rst b/docs/source/getting-set-up.rst index ce2b59e0c4..dd85083860 100644 --- a/docs/source/getting-set-up.rst +++ b/docs/source/getting-set-up.rst @@ -76,7 +76,7 @@ and a basic CorDapp that you can use as the basis for your own CorDapps is avail You can clone both of these repos to your local machine by running the command ``git clone [repo URL]``. By default, both repos will be on the ``master`` branch. However, this is an unstable development branch. You should check -out the latest milestone release (currently Milestone 8.1) instead by running ``git checkout release-M8.1``. +out the latest milestone release (currently Milestone 8.2) instead by running ``git checkout release-M8.2``. Opening Corda/CorDapps in IDEA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/index.rst b/docs/source/index.rst index 0ededb0acc..dab43f8372 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -2,7 +2,7 @@ Welcome to the Corda documentation! =================================== `Corda `_ is an open-source distributed ledger platform. The latest *milestone* (i.e. stable) -release is M8.1. The codebase is on `GitHub `_, and our community can be found on +release is M8.2. The codebase is on `GitHub `_, and our community can be found on `Slack `_ and in our `forum `_. If you're new to Corda, you should start by learning about its motivating vision and architecture. A good introduction diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst index 2f2e0cac91..de0779e0b7 100644 --- a/docs/source/release-notes.rst +++ b/docs/source/release-notes.rst @@ -3,6 +3,11 @@ Release notes Here are brief summaries of what's changed between each snapshot release. +Milestone 8.2 +------------- + +* Added an openAttachment endpoint to the RPC interface to allow downloading of attachments via RPC. + Milestone 8.1 ------------- diff --git a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt index 6bf007ddf3..20b2dca198 100644 --- a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt +++ b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt @@ -101,6 +101,7 @@ class CordaRPCOpsImpl( } override fun attachmentExists(id: SecureHash) = services.storageService.attachments.openAttachment(id) != null + override fun openAttachment(id: SecureHash) = services.storageService.attachments.openAttachment(id)!!.open() override fun uploadAttachment(jar: InputStream) = services.storageService.attachments.importAttachment(jar) override fun currentNodeTime(): Instant = Instant.now(services.clock) override fun uploadFile(dataType: String, name: String?, file: InputStream): String { diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index 170840485f..562e8fd10a 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -24,15 +24,22 @@ import net.corda.testing.expectEvents import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.sequence +import org.apache.commons.io.IOUtils import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.junit.Before import org.junit.Test import rx.Observable +import java.io.ByteArrayOutputStream +import java.util.* import kotlin.test.assertEquals import kotlin.test.assertFalse class CordaRPCOpsImplTest { + private companion object { + val testJar = "net/corda/node/testing/test.jar" + } + lateinit var network: MockNetwork lateinit var aliceNode: MockNode lateinit var notaryNode: MockNode @@ -196,4 +203,24 @@ class CordaRPCOpsImplTest { )) } } + + @Test + fun `can upload an attachment`() { + val inputJar = Thread.currentThread().contextClassLoader.getResourceAsStream(testJar) + val secureHash = rpc.uploadAttachment(inputJar) + assert(rpc.attachmentExists(secureHash)) + } + + @Test + fun `can download an uploaded attachment`() { + val inputJar = Thread.currentThread().contextClassLoader.getResourceAsStream(testJar) + val secureHash = rpc.uploadAttachment(inputJar) + val bufferFile = ByteArrayOutputStream() + val bufferRpc = ByteArrayOutputStream() + + IOUtils.copy(Thread.currentThread().contextClassLoader.getResourceAsStream(testJar), bufferFile) + IOUtils.copy(rpc.openAttachment(secureHash), bufferRpc) + + assert(Arrays.equals(bufferFile.toByteArray(), bufferRpc.toByteArray())) + } } diff --git a/node/src/test/resources/net/corda/node/testing/test.jar b/node/src/test/resources/net/corda/node/testing/test.jar new file mode 100644 index 0000000000..9ce0b7d2d2 Binary files /dev/null and b/node/src/test/resources/net/corda/node/testing/test.jar differ