From 7a06d941c45a1cd1d8db79cca39a73266bea9138 Mon Sep 17 00:00:00 2001 From: Matthew Nesbit Date: Fri, 14 Jul 2017 13:17:02 +0100 Subject: [PATCH] Put Services.kt in clear files, so that at a glance people can see what public services there are. Fix include Correct doc links after code movement --- .../node/services/KeyManagementService.kt | 56 +++++ .../services/TransactionVerifierService.kt | 15 ++ .../core/node/services/VaultQueryService.kt | 140 +++++++++++ .../services/{Services.kt => VaultService.kt} | 227 +----------------- docs/source/api-vault-query.rst | 2 +- docs/source/soft-locking.rst | 4 +- .../services/messaging/P2PMessagingTest.kt | 2 +- .../node/services/api/AbstractNodeService.kt | 1 - .../node/services/api/AcceptsFileUpload.kt | 2 - .../node/services/api/ServiceHubInternal.kt | 26 +- .../keys/E2ETestKeyManagementService.kt | 2 - .../node/services/messaging/Messaging.kt | 2 +- .../messaging/ServiceRequestMessage.kt | 2 +- .../network/InMemoryNetworkMapCache.kt | 3 +- .../services/network/NetworkMapService.kt | 4 +- .../node/messaging/InMemoryMessagingTests.kt | 2 +- .../messaging/ArtemisMessagingTests.kt | 8 +- .../network/AbstractNetworkMapServiceTest.kt | 10 +- .../corda/bank/BankOfCordaRPCClientTest.kt | 3 +- 19 files changed, 255 insertions(+), 256 deletions(-) create mode 100644 core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt create mode 100644 core/src/main/kotlin/net/corda/core/node/services/TransactionVerifierService.kt create mode 100644 core/src/main/kotlin/net/corda/core/node/services/VaultQueryService.kt rename core/src/main/kotlin/net/corda/core/node/services/{Services.kt => VaultService.kt} (59%) diff --git a/core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt b/core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt new file mode 100644 index 0000000000..f9799a7f2c --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/node/services/KeyManagementService.kt @@ -0,0 +1,56 @@ +package net.corda.core.node.services + +import co.paralleluniverse.fibers.Suspendable +import net.corda.core.crypto.DigitalSignature +import net.corda.core.identity.PartyAndCertificate +import net.corda.flows.AnonymisedIdentity +import java.security.PublicKey + +/** + * The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example, + * call out to a hardware security module that enforces various auditing and frequency-of-use requirements. + */ +interface KeyManagementService { + /** + * Returns a snapshot of the current signing [PublicKey]s. + * For each of these keys a [PrivateKey] is available, that can be used later for signing. + */ + val keys: Set + + /** + * Generates a new random [KeyPair] and adds it to the internal key storage. Returns the public part of the pair. + */ + @Suspendable + fun freshKey(): PublicKey + + /** + * Generates a new random [KeyPair], adds it to the internal key storage, then generates a corresponding + * [X509Certificate] and adds it to the identity service. + * + * @param identity identity to generate a key and certificate for. Must be an identity this node has CA privileges for. + * @param revocationEnabled whether to check revocation status of certificates in the certificate path. + * @return X.509 certificate and path to the trust root. + */ + @Suspendable + fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): AnonymisedIdentity + + /** + * Filter some keys down to the set that this node owns (has private keys for). + * + * @param candidateKeys keys which this node may own. + */ + fun filterMyKeys(candidateKeys: Iterable): Iterable + + /** + * Using the provided signing [PublicKey] internally looks up the matching [PrivateKey] and signs the data. + * @param bytes The data to sign over using the chosen key. + * @param publicKey The [PublicKey] partner to an internally held [PrivateKey], either derived from the node's primary identity, + * or previously generated via the [freshKey] method. + * If the [PublicKey] is actually a [CompositeKey] the first leaf signing key hosted by the node is used. + * @throws IllegalArgumentException if the input key is not a member of [keys]. + * TODO A full [KeyManagementService] implementation needs to record activity to the [AuditService] and to limit signing to + * appropriately authorised contexts and initiating users. + */ + @Suspendable + fun sign(bytes: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey +} \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/node/services/TransactionVerifierService.kt b/core/src/main/kotlin/net/corda/core/node/services/TransactionVerifierService.kt new file mode 100644 index 0000000000..fd31e2a55a --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/node/services/TransactionVerifierService.kt @@ -0,0 +1,15 @@ +package net.corda.core.node.services + +import com.google.common.util.concurrent.ListenableFuture +import net.corda.core.transactions.LedgerTransaction + +/** + * Provides verification service. The implementation may be a simple in-memory verify() call or perhaps an IPC/RPC. + */ +interface TransactionVerifierService { + /** + * @param transaction The transaction to be verified. + * @return A future that completes successfully if the transaction verified, or sets an exception the verifier threw. + */ + fun verify(transaction: LedgerTransaction): ListenableFuture<*> +} \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/node/services/VaultQueryService.kt b/core/src/main/kotlin/net/corda/core/node/services/VaultQueryService.kt new file mode 100644 index 0000000000..48c8f4b3fd --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/node/services/VaultQueryService.kt @@ -0,0 +1,140 @@ +package net.corda.core.node.services + +import net.corda.core.contracts.ContractState +import net.corda.core.flows.FlowException +import net.corda.core.messaging.DataFeed +import net.corda.core.node.services.vault.PageSpecification +import net.corda.core.node.services.vault.QueryCriteria +import net.corda.core.node.services.vault.Sort + +interface VaultQueryService { + + // DOCSTART VaultQueryAPI + /** + * Generic vault query function which takes a [QueryCriteria] object to define filters, + * optional [PageSpecification] and optional [Sort] modification criteria (default unsorted), + * and returns a [Vault.Page] object containing the following: + * 1. states as a List of (page number and size defined by [PageSpecification]) + * 2. states metadata as a List of [Vault.StateMetadata] held in the Vault States table. + * 3. total number of results available if [PageSpecification] supplied (otherwise returns -1) + * 4. status types used in this query: UNCONSUMED, CONSUMED, ALL + * 5. other results (aggregate functions with/without using value groups) + * + * @throws VaultQueryException if the query cannot be executed for any reason + * (missing criteria or parsing error, paging errors, unsupported query, underlying database error) + * + * Notes + * If no [PageSpecification] is provided, a maximum of [DEFAULT_PAGE_SIZE] results will be returned. + * API users must specify a [PageSpecification] if they are expecting more than [DEFAULT_PAGE_SIZE] results, + * otherwise a [VaultQueryException] will be thrown alerting to this condition. + * It is the responsibility of the API user to request further pages and/or specify a more suitable [PageSpecification]. + */ + @Throws(VaultQueryException::class) + fun _queryBy(criteria: QueryCriteria, + paging: PageSpecification, + sorting: Sort, + contractType: Class): Vault.Page + + /** + * Generic vault query function which takes a [QueryCriteria] object to define filters, + * optional [PageSpecification] and optional [Sort] modification criteria (default unsorted), + * and returns a [Vault.PageAndUpdates] object containing + * 1) a snapshot as a [Vault.Page] (described previously in [queryBy]) + * 2) an [Observable] of [Vault.Update] + * + * @throws VaultQueryException if the query cannot be executed for any reason + * + * Notes: the snapshot part of the query adheres to the same behaviour as the [queryBy] function. + * the [QueryCriteria] applies to both snapshot and deltas (streaming updates). + */ + @Throws(VaultQueryException::class) + fun _trackBy(criteria: QueryCriteria, + paging: PageSpecification, + sorting: Sort, + contractType: Class): DataFeed, Vault.Update> + // DOCEND VaultQueryAPI + + // Note: cannot apply @JvmOverloads to interfaces nor interface implementations + // Java Helpers + fun queryBy(contractType: Class): Vault.Page { + return _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType) + } + + fun queryBy(contractType: Class, criteria: QueryCriteria): Vault.Page { + return _queryBy(criteria, PageSpecification(), Sort(emptySet()), contractType) + } + + fun queryBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification): Vault.Page { + return _queryBy(criteria, paging, Sort(emptySet()), contractType) + } + + fun queryBy(contractType: Class, criteria: QueryCriteria, sorting: Sort): Vault.Page { + return _queryBy(criteria, PageSpecification(), sorting, contractType) + } + + fun queryBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.Page { + return _queryBy(criteria, paging, sorting, contractType) + } + + fun trackBy(contractType: Class): DataFeed, Vault.Update> { + return _trackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType) + } + + fun trackBy(contractType: Class, criteria: QueryCriteria): DataFeed, Vault.Update> { + return _trackBy(criteria, PageSpecification(), Sort(emptySet()), contractType) + } + + fun trackBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification): DataFeed, Vault.Update> { + return _trackBy(criteria, paging, Sort(emptySet()), contractType) + } + + fun trackBy(contractType: Class, criteria: QueryCriteria, sorting: Sort): DataFeed, Vault.Update> { + return _trackBy(criteria, PageSpecification(), sorting, contractType) + } + + fun trackBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): DataFeed, Vault.Update> { + return _trackBy(criteria, paging, sorting, contractType) + } +} + +inline fun VaultQueryService.queryBy(): Vault.Page { + return _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), T::class.java) +} + +inline fun VaultQueryService.queryBy(criteria: QueryCriteria): Vault.Page { + return _queryBy(criteria, PageSpecification(), Sort(emptySet()), T::class.java) +} + +inline fun VaultQueryService.queryBy(criteria: QueryCriteria, paging: PageSpecification): Vault.Page { + return _queryBy(criteria, paging, Sort(emptySet()), T::class.java) +} + +inline fun VaultQueryService.queryBy(criteria: QueryCriteria, sorting: Sort): Vault.Page { + return _queryBy(criteria, PageSpecification(), sorting, T::class.java) +} + +inline fun VaultQueryService.queryBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.Page { + return _queryBy(criteria, paging, sorting, T::class.java) +} + +inline fun VaultQueryService.trackBy(): DataFeed, Vault.Update> { + return _trackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), T::class.java) +} + +inline fun VaultQueryService.trackBy(criteria: QueryCriteria): DataFeed, Vault.Update> { + return _trackBy(criteria, PageSpecification(), Sort(emptySet()), T::class.java) +} + +inline fun VaultQueryService.trackBy(criteria: QueryCriteria, paging: PageSpecification): DataFeed, Vault.Update> { + return _trackBy(criteria, paging, Sort(emptySet()), T::class.java) +} + +inline fun VaultQueryService.trackBy(criteria: QueryCriteria, sorting: Sort): DataFeed, Vault.Update> { + return _trackBy(criteria, PageSpecification(), sorting, T::class.java) +} + +inline fun VaultQueryService.trackBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): DataFeed, Vault.Update> { + return _trackBy(criteria, paging, sorting, T::class.java) +} + +class VaultQueryException(description: String) : FlowException("$description") \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/node/services/Services.kt b/core/src/main/kotlin/net/corda/core/node/services/VaultService.kt similarity index 59% rename from core/src/main/kotlin/net/corda/core/node/services/Services.kt rename to core/src/main/kotlin/net/corda/core/node/services/VaultService.kt index 3b139f4734..3eccef2bb9 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/Services.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/VaultService.kt @@ -3,46 +3,23 @@ package net.corda.core.node.services import co.paralleluniverse.fibers.Suspendable import com.google.common.util.concurrent.ListenableFuture import net.corda.core.contracts.* -import net.corda.core.crypto.composite.CompositeKey -import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.SecureHash -import net.corda.core.crypto.keys import net.corda.core.flows.FlowException import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.messaging.DataFeed -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.Sort -import net.corda.core.node.services.vault.DEFAULT_PAGE_SIZE import net.corda.core.serialization.CordaSerializable import net.corda.core.toFuture -import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.NonEmptySet import net.corda.core.utilities.OpaqueBytes -import net.corda.flows.AnonymisedIdentity import rx.Observable import rx.subjects.PublishSubject -import java.io.InputStream import java.security.PublicKey -import java.security.cert.X509Certificate import java.time.Instant import java.util.* -/** - * Session ID to use for services listening for the first message in a session (before a - * specific session ID has been established). - */ -val DEFAULT_SESSION_ID = 0L - -/** - * This file defines various 'services' which are not currently fleshed out. A service is a module that provides - * immutable snapshots of data that may be changing in response to user or network events. - */ - /** * A vault (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, * because we own them. This class represents an immutable, stable state of a vault: it is guaranteed not to @@ -345,206 +322,4 @@ inline fun VaultService.linearHeadsOfType() = class StatesNotAvailableException(override val message: String?, override val cause: Throwable? = null) : FlowException(message, cause) { override fun toString() = "Soft locking error: $message" -} - -interface VaultQueryService { - - // DOCSTART VaultQueryAPI - /** - * Generic vault query function which takes a [QueryCriteria] object to define filters, - * optional [PageSpecification] and optional [Sort] modification criteria (default unsorted), - * and returns a [Vault.Page] object containing the following: - * 1. states as a List of (page number and size defined by [PageSpecification]) - * 2. states metadata as a List of [Vault.StateMetadata] held in the Vault States table. - * 3. total number of results available if [PageSpecification] supplied (otherwise returns -1) - * 4. status types used in this query: UNCONSUMED, CONSUMED, ALL - * 5. other results (aggregate functions with/without using value groups) - * - * @throws VaultQueryException if the query cannot be executed for any reason - * (missing criteria or parsing error, paging errors, unsupported query, underlying database error) - * - * Notes - * If no [PageSpecification] is provided, a maximum of [DEFAULT_PAGE_SIZE] results will be returned. - * API users must specify a [PageSpecification] if they are expecting more than [DEFAULT_PAGE_SIZE] results, - * otherwise a [VaultQueryException] will be thrown alerting to this condition. - * It is the responsibility of the API user to request further pages and/or specify a more suitable [PageSpecification]. - */ - @Throws(VaultQueryException::class) - fun _queryBy(criteria: QueryCriteria, - paging: PageSpecification, - sorting: Sort, - contractType: Class): Vault.Page - /** - * Generic vault query function which takes a [QueryCriteria] object to define filters, - * optional [PageSpecification] and optional [Sort] modification criteria (default unsorted), - * and returns a [Vault.PageAndUpdates] object containing - * 1) a snapshot as a [Vault.Page] (described previously in [queryBy]) - * 2) an [Observable] of [Vault.Update] - * - * @throws VaultQueryException if the query cannot be executed for any reason - * - * Notes: the snapshot part of the query adheres to the same behaviour as the [queryBy] function. - * the [QueryCriteria] applies to both snapshot and deltas (streaming updates). - */ - @Throws(VaultQueryException::class) - fun _trackBy(criteria: QueryCriteria, - paging: PageSpecification, - sorting: Sort, - contractType: Class): DataFeed, Vault.Update> - // DOCEND VaultQueryAPI - - // Note: cannot apply @JvmOverloads to interfaces nor interface implementations - // Java Helpers - fun queryBy(contractType: Class): Vault.Page { - return _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType) - } - fun queryBy(contractType: Class, criteria: QueryCriteria): Vault.Page { - return _queryBy(criteria, PageSpecification(), Sort(emptySet()), contractType) - } - fun queryBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification): Vault.Page { - return _queryBy(criteria, paging, Sort(emptySet()), contractType) - } - fun queryBy(contractType: Class, criteria: QueryCriteria, sorting: Sort): Vault.Page { - return _queryBy(criteria, PageSpecification(), sorting, contractType) - } - fun queryBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.Page { - return _queryBy(criteria, paging, sorting, contractType) - } - - fun trackBy(contractType: Class): DataFeed, Vault.Update> { - return _trackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType) - } - fun trackBy(contractType: Class, criteria: QueryCriteria): DataFeed, Vault.Update> { - return _trackBy(criteria, PageSpecification(), Sort(emptySet()), contractType) - } - fun trackBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification): DataFeed, Vault.Update> { - return _trackBy(criteria, paging, Sort(emptySet()), contractType) - } - fun trackBy(contractType: Class, criteria: QueryCriteria, sorting: Sort): DataFeed, Vault.Update> { - return _trackBy(criteria, PageSpecification(), sorting, contractType) - } - fun trackBy(contractType: Class, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): DataFeed, Vault.Update> { - return _trackBy(criteria, paging, sorting, contractType) - } -} - -inline fun VaultQueryService.queryBy(): Vault.Page { - return _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), T::class.java) -} - -inline fun VaultQueryService.queryBy(criteria: QueryCriteria): Vault.Page { - return _queryBy(criteria, PageSpecification(), Sort(emptySet()), T::class.java) -} - -inline fun VaultQueryService.queryBy(criteria: QueryCriteria, paging: PageSpecification): Vault.Page { - return _queryBy(criteria, paging, Sort(emptySet()), T::class.java) -} - -inline fun VaultQueryService.queryBy(criteria: QueryCriteria, sorting: Sort): Vault.Page { - return _queryBy(criteria, PageSpecification(), sorting, T::class.java) -} - -inline fun VaultQueryService.queryBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.Page { - return _queryBy(criteria, paging, sorting, T::class.java) -} - -inline fun VaultQueryService.trackBy(): DataFeed, Vault.Update> { - return _trackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), T::class.java) -} - -inline fun VaultQueryService.trackBy(criteria: QueryCriteria): DataFeed, Vault.Update> { - return _trackBy(criteria, PageSpecification(), Sort(emptySet()), T::class.java) -} - -inline fun VaultQueryService.trackBy(criteria: QueryCriteria, paging: PageSpecification): DataFeed, Vault.Update> { - return _trackBy(criteria, paging, Sort(emptySet()), T::class.java) -} - -inline fun VaultQueryService.trackBy(criteria: QueryCriteria, sorting: Sort): DataFeed, Vault.Update> { - return _trackBy(criteria, PageSpecification(), sorting, T::class.java) -} - -inline fun VaultQueryService.trackBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): DataFeed, Vault.Update> { - return _trackBy(criteria, paging, sorting, T::class.java) -} - -class VaultQueryException(description: String) : FlowException("$description") - -/** - * The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example, - * call out to a hardware security module that enforces various auditing and frequency-of-use requirements. - */ - -interface KeyManagementService { - /** - * Returns a snapshot of the current signing [PublicKey]s. - * For each of these keys a [PrivateKey] is available, that can be used later for signing. - */ - val keys: Set - - /** - * Generates a new random [KeyPair] and adds it to the internal key storage. Returns the public part of the pair. - */ - @Suspendable - fun freshKey(): PublicKey - - /** - * Generates a new random [KeyPair], adds it to the internal key storage, then generates a corresponding - * [X509Certificate] and adds it to the identity service. - * - * @param identity identity to generate a key and certificate for. Must be an identity this node has CA privileges for. - * @param revocationEnabled whether to check revocation status of certificates in the certificate path. - * @return X.509 certificate and path to the trust root. - */ - @Suspendable - fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): AnonymisedIdentity - - /** - * Filter some keys down to the set that this node owns (has private keys for). - * - * @param candidateKeys keys which this node may own. - */ - fun filterMyKeys(candidateKeys: Iterable): Iterable - - /** - * Using the provided signing [PublicKey] internally looks up the matching [PrivateKey] and signs the data. - * @param bytes The data to sign over using the chosen key. - * @param publicKey The [PublicKey] partner to an internally held [PrivateKey], either derived from the node's primary identity, - * or previously generated via the [freshKey] method. - * If the [PublicKey] is actually a [CompositeKey] the first leaf signing key hosted by the node is used. - * @throws IllegalArgumentException if the input key is not a member of [keys]. - * TODO A full [KeyManagementService] implementation needs to record activity to the [AuditService] and to limit signing to - * appropriately authorised contexts and initiating users. - */ - @Suspendable - fun sign(bytes: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey -} - -/** - * An interface that denotes a service that can accept file uploads. - */ -// TODO This is no longer used and can be removed -interface FileUploader { - /** - * Accepts the data in the given input stream, and returns some sort of useful return message that will be sent - * back to the user in the response. - */ - fun upload(file: InputStream): String - - /** - * Check if this service accepts this type of upload. For example if you are uploading interest rates this could - * be "my-service-interest-rates". Type here does not refer to file extentions or MIME types. - */ - fun accepts(type: String): Boolean -} - -/** - * Provides verification service. The implementation may be a simple in-memory verify() call or perhaps an IPC/RPC. - */ -interface TransactionVerifierService { - /** - * @param transaction The transaction to be verified. - * @return A future that completes successfully if the transaction verified, or sets an exception the verifier threw. - */ - fun verify(transaction: LedgerTransaction): ListenableFuture<*> -} +} \ No newline at end of file diff --git a/docs/source/api-vault-query.rst b/docs/source/api-vault-query.rst index 84683b9763..099306bc30 100644 --- a/docs/source/api-vault-query.rst +++ b/docs/source/api-vault-query.rst @@ -11,7 +11,7 @@ Corda provides a number of flexible query mechanisms for accessing the Vault: The majority of query requirements can be satisfied by using the Vault Query API, which is exposed via the ``VaultQueryService`` for use directly by flows: -.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/node/services/Services.kt +.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/node/services/VaultQueryService.kt :language: kotlin :start-after: DOCSTART VaultQueryAPI :end-before: DOCEND VaultQueryAPI diff --git a/docs/source/soft-locking.rst b/docs/source/soft-locking.rst index 8cf05b3985..885951da98 100644 --- a/docs/source/soft-locking.rst +++ b/docs/source/soft-locking.rst @@ -17,7 +17,7 @@ These states are effectively soft locked until flow termination (exit or error) In addition, the ``VaultService`` exposes a number of functions a developer may use to explicitly reserve, release and query soft locks associated with states as required by their CorDapp application logic: -.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/node/services/Services.kt +.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/node/services/VaultService.kt :language: kotlin :start-after: DOCSTART SoftLockAPI :end-before: DOCEND SoftLockAPI @@ -25,7 +25,7 @@ query soft locks associated with states as required by their CorDapp application You can also control whether soft locked states are retrieved in general vault queries by setting an optional boolean `includeSoftLockedStates` flag (which is set to *true* by default) -.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/node/services/Services.kt +.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/node/services/VaultService.kt :language: kotlin :start-after: DOCSTART VaultStatesQuery :end-before: DOCEND VaultStatesQuery diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt index d7e0dc2c3e..611e87373e 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt @@ -6,12 +6,12 @@ import net.corda.core.* import net.corda.core.crypto.random63BitValue import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.node.services.ServiceInfo import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.node.internal.Node +import net.corda.node.services.api.DEFAULT_SESSION_ID import net.corda.node.services.messaging.* import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.node.services.transactions.SimpleNotaryService diff --git a/node/src/main/kotlin/net/corda/node/services/api/AbstractNodeService.kt b/node/src/main/kotlin/net/corda/node/services/api/AbstractNodeService.kt index 5c974fcfb1..73acab6e44 100644 --- a/node/src/main/kotlin/net/corda/node/services/api/AbstractNodeService.kt +++ b/node/src/main/kotlin/net/corda/node/services/api/AbstractNodeService.kt @@ -1,6 +1,5 @@ package net.corda.node.services.api -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize diff --git a/node/src/main/kotlin/net/corda/node/services/api/AcceptsFileUpload.kt b/node/src/main/kotlin/net/corda/node/services/api/AcceptsFileUpload.kt index a3967ec2ba..14dafbea77 100644 --- a/node/src/main/kotlin/net/corda/node/services/api/AcceptsFileUpload.kt +++ b/node/src/main/kotlin/net/corda/node/services/api/AcceptsFileUpload.kt @@ -1,7 +1,5 @@ package net.corda.node.services.api -import net.corda.core.node.services.FileUploader - /** * A service that implements AcceptsFileUpload can have new binary data provided to it via an HTTP upload. */ diff --git a/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt b/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt index fedc2c6477..0b909aa84c 100644 --- a/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt +++ b/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt @@ -12,7 +12,6 @@ import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.StateMachineTransactionMapping import net.corda.core.node.NodeInfo import net.corda.core.node.PluginServiceHub -import net.corda.core.node.services.FileUploader import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.TransactionStorage import net.corda.core.serialization.CordaSerializable @@ -24,6 +23,13 @@ import net.corda.node.services.messaging.MessagingService import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl import net.corda.node.services.statemachine.FlowStateMachineImpl import net.corda.node.utilities.CordaPersistence +import java.io.InputStream + +/** + * Session ID to use for services listening for the first message in a session (before a + * specific session ID has been established). + */ +val DEFAULT_SESSION_ID = 0L interface NetworkMapCacheInternal : NetworkMapCache { /** @@ -62,6 +68,24 @@ sealed class NetworkCacheError : Exception() { class DeregistrationFailed : NetworkCacheError() } +/** + * An interface that denotes a service that can accept file uploads. + */ +// TODO This is no longer used and can be removed +interface FileUploader { + /** + * Accepts the data in the given input stream, and returns some sort of useful return message that will be sent + * back to the user in the response. + */ + fun upload(file: InputStream): String + + /** + * Check if this service accepts this type of upload. For example if you are uploading interest rates this could + * be "my-service-interest-rates". Type here does not refer to file extentions or MIME types. + */ + fun accepts(type: String): Boolean +} + interface ServiceHubInternal : PluginServiceHub { companion object { private val log = loggerFor() diff --git a/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt b/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt index 0222ba6fa5..cfba3dd792 100644 --- a/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt +++ b/node/src/main/kotlin/net/corda/node/services/keys/E2ETestKeyManagementService.kt @@ -10,12 +10,10 @@ import net.corda.core.node.services.IdentityService import net.corda.core.node.services.KeyManagementService import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.flows.AnonymisedIdentity -import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.operator.ContentSigner import java.security.KeyPair import java.security.PrivateKey import java.security.PublicKey -import java.security.cert.CertPath import java.util.* import javax.annotation.concurrent.ThreadSafe diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/Messaging.kt b/node/src/main/kotlin/net/corda/node/services/messaging/Messaging.kt index c5396a0067..baf8c623d3 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/Messaging.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/Messaging.kt @@ -5,11 +5,11 @@ import com.google.common.util.concurrent.SettableFuture import net.corda.core.catch import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.node.services.PartyInfo import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize +import net.corda.node.services.api.DEFAULT_SESSION_ID import org.bouncycastle.asn1.x500.X500Name import java.time.Instant import java.util.* diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/ServiceRequestMessage.kt b/node/src/main/kotlin/net/corda/node/services/messaging/ServiceRequestMessage.kt index 35ce5218d1..9663a07a2b 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/ServiceRequestMessage.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/ServiceRequestMessage.kt @@ -3,8 +3,8 @@ package net.corda.node.services.messaging import com.google.common.util.concurrent.ListenableFuture import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.serialization.CordaSerializable +import net.corda.node.services.api.DEFAULT_SESSION_ID /** * Abstract superclass for request messages sent to services which expect a reply. diff --git a/node/src/main/kotlin/net/corda/node/services/network/InMemoryNetworkMapCache.kt b/node/src/main/kotlin/net/corda/node/services/network/InMemoryNetworkMapCache.kt index 0d3cd6e818..25087c0832 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/InMemoryNetworkMapCache.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/InMemoryNetworkMapCache.kt @@ -11,14 +11,13 @@ import net.corda.core.messaging.DataFeed import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.NodeInfo import net.corda.core.node.ServiceHub -import net.corda.core.node.services.DEFAULT_SESSION_ID -import net.corda.core.node.services.IdentityService import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.PartyInfo import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.loggerFor +import net.corda.node.services.api.DEFAULT_SESSION_ID import net.corda.node.services.api.NetworkCacheError import net.corda.node.services.api.NetworkMapCacheInternal import net.corda.node.services.messaging.MessagingService diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt index d0f51b534e..7ee02601b5 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt @@ -5,15 +5,14 @@ import net.corda.core.ThreadBox import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.SignedData import net.corda.core.crypto.isFulfilledBy +import net.corda.core.crypto.random63BitValue import net.corda.core.identity.PartyAndCertificate import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.NodeInfo -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.node.services.KeyManagementService import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.ServiceType -import net.corda.core.crypto.random63BitValue import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.deserialize @@ -21,6 +20,7 @@ import net.corda.core.serialization.serialize import net.corda.core.utilities.debug import net.corda.core.utilities.loggerFor import net.corda.node.services.api.AbstractNodeService +import net.corda.node.services.api.DEFAULT_SESSION_ID import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.messaging.MessageHandlerRegistration import net.corda.node.services.messaging.ServiceRequestMessage diff --git a/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt b/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt index b935635105..ad09bb67a8 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt @@ -1,7 +1,7 @@ package net.corda.node.messaging -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.node.services.ServiceInfo +import net.corda.node.services.api.DEFAULT_SESSION_ID import net.corda.node.services.messaging.Message import net.corda.node.services.messaging.TopicStringValidator import net.corda.node.services.messaging.createMessage diff --git a/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt b/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt index 6835133980..59f71acde4 100644 --- a/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt @@ -6,12 +6,10 @@ import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.SettableFuture import net.corda.core.crypto.generateKeyPair import net.corda.core.messaging.RPCOps -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.utilities.NetworkHostAndPort -import net.corda.testing.ALICE -import net.corda.testing.LogHelper import net.corda.node.services.RPCUserService import net.corda.node.services.RPCUserServiceImpl +import net.corda.node.services.api.DEFAULT_SESSION_ID import net.corda.node.services.api.MonitoringService import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.configureWithDevSSLCertificate @@ -21,11 +19,9 @@ import net.corda.node.services.transactions.PersistentUniquenessProvider import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor import net.corda.node.utilities.CordaPersistence import net.corda.node.utilities.configureDatabase -import net.corda.testing.freeLocalHostAndPort -import net.corda.testing.freePort +import net.corda.testing.* import net.corda.testing.node.MOCK_VERSION_INFO import net.corda.testing.node.makeTestDataSourceProperties -import net.corda.testing.testNodeConfiguration import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.After diff --git a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt index 9c6df604e7..549f52e848 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt @@ -4,13 +4,9 @@ import com.google.common.util.concurrent.ListenableFuture import net.corda.core.getOrThrow import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.NodeInfo -import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.node.services.ServiceInfo import net.corda.core.serialization.deserialize -import net.corda.testing.ALICE -import net.corda.testing.BOB -import net.corda.testing.CHARLIE -import net.corda.testing.DUMMY_MAP +import net.corda.node.services.api.DEFAULT_SESSION_ID import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.messaging.send import net.corda.node.services.messaging.sendRequest @@ -26,6 +22,10 @@ import net.corda.node.services.network.NetworkMapService.Companion.SUBSCRIPTION_ import net.corda.node.utilities.AddOrRemove import net.corda.node.utilities.AddOrRemove.ADD import net.corda.node.utilities.AddOrRemove.REMOVE +import net.corda.testing.ALICE +import net.corda.testing.BOB +import net.corda.testing.CHARLIE +import net.corda.testing.DUMMY_MAP import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork.MockNode import org.assertj.core.api.Assertions.assertThat diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt index 7159c077b4..71e98c6ace 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt @@ -7,14 +7,13 @@ import net.corda.core.getOrThrow import net.corda.core.messaging.startFlow import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault -import net.corda.core.node.services.trackBy import net.corda.core.node.services.vault.QueryCriteria import net.corda.flows.IssuerFlow.IssuanceRequester -import net.corda.testing.driver.driver import net.corda.node.services.startFlowPermission import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.* +import net.corda.testing.driver.driver import org.junit.Test class BankOfCordaRPCClientTest {