BNMS Starter
The corbeans-spring-boot-bnms-starter
provides autoconfigured, RESTful
BNMS services for Corda’s memberships-management
cordapp. The services expose operations for both members and BNOs, e.g.:
- List business network members
- Request a membership or amend own membership’s metadata
- Activate or suspend membership (for BNO nodes)
This document describes how to use the starter and quickly implement BNMS services for your Spring Boot app.
Installation
Corda BNMS Repository
Make sure to add the corda-solutions-releases repository to your build modules.
// Corda BNMS repo
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-solutions-releases'}
Cordapp Dependencies
Add the Corda BNMS dependencies to your cordapp:
dependencies {
// Corda memberships-management deps
compile "com.r3.businessnetworks:membership-service:$corda_solutions_version"
compile "com.r3.businessnetworks:membership-service-contracts-and-states:$corda_solutions_version"
//...
}
Spring Boot Application Dependencies
Corbeans is available in Maven central. To install the main and BNMS starters, add the following dependencies to your build.
dependencies {
// Corbeans starter
compile ("com.github.manosbatsis.corbeans:corbeans-spring-boot-starter:$corbeans_version")
// Corbeans BNMS starter
compile ("com.github.manosbatsis.corbeans:corbeans-spring-boot-bnms-starter:$corbeans_version")
// Optional: control the BNMS dependency versions
compile "com.r3.businessnetworks:membership-service:$corda_solutions_version"
compile "com.r3.businessnetworks:membership-service-contracts-and-states:$corda_solutions_version"
}
Configuration
The following steps are required to properly configure and use the BNMS starter.
- Create your custom membership metadata class
- Implement a custom BNMS service
The sections bellow describe the steps in detail.
Custom Metadata Class
First of all you need to create a metadata class that fits your needs.
MembershipState
allows the use of a custom type as
the value of it’s membershipMetadata
member. It’s worth noting the type
is also used by [com.r3.businessnetworks.membership.flows.GenericsUtilsKt#getAttachmentIdForGenericParam(com.r3.businessnetworks.membership.states.MembershipState<? extends java.lang.Object>)]
to to find the appropriate class location and turn it into an attachment.
Here’s a sample implementation that adds a simple comment metadatum:
@CordaSerializable
data class MyCustomMembershipMetadata(
val comment: String
// Add more custom members here
)
Your metadata class belongs to your cordapp contract module
BNMS Service Implementation
To integrate your custom metadata class with Corbeans, implement a CordaBnmsService
by extending AbstractCordaBnmsServiceImpl
to provide a mapping function between a JsonNode
and your custom metadata class:
/** BNMS service implementation */
class MyCustomBnmsService(
nodeRpcConnection: NodeRpcConnection
): AbstractCordaBnmsServiceImpl<MyCustomMembershipMetadata>(nodeRpcConnection) {
/** Convert the given JSON node to the target [MyCustomMembershipMetadata] instance */
override fun toMembershipMetadata(jsonNode: JsonNode?): MyCustomMembershipMetadata {
val givenComment = // read from JSON...
return MyCustomMembershipMetadata(comment = givenComment)
}
}
Nodes Configuration
Last but not least, specify the custom BNMS Service implementation
using the bnmsServiceType
slot for each of your nodes in application.properties.
# Common node config properties...
corbeans.nodes.partyA.username=user1
corbeans.nodes.partyA.password=test
corbeans.nodes.partyA.address=localhost:10006
corbeans.nodes.partyA.adminAddress=localhost:10046
# Custom BNMS service type for this node
corbeans.nodes.partyA.bnmsServiceType=mypackage.MyCustomBnmsService
Corbeans will create and register the appropriate BNMS service beans.
Endpoints
Starting with version 0.25, you need to explicitly add controllers to expose BNMS operations for BNO and members via RESTful services.
Simple Node Controllers
Implement minimal controller subclasses of CorbeansBmnsBnoController
and/or CorbeansBmnsMemberController
like bellow:
@RestController
class MyBmnsBnoController: CorbeansBmnsBnoController()
@RestController
class MyBmnsMemberController: CorbeansBmnsMemberController()
This will expose the folowing endpoints:
Method | Path | Description |
---|---|---|
PUT | /api/bnms/bno/memberships | Activate a pending membership |
DELETE | /api/bnms/bno/memberships | Suspend an active membership |
GET | /api/bnms/member/memberships | Get a memberships list from a BNO. URL params: bno (string) the BNO party name, filterOutMissingFromNetworkMap (boolean) whether to filter out anyone missing from the Network Map, default is true, forceRefresh (boolean) whether to force a refresh, default value is false |
POST | /api/bnms/member/memberships | Request the BNO to kick-off the on-boarding procedure |
PUT | /api/bnms/member/memberships | Propose a change to the membership metadata. |
This is suitable for a single node per Spring Boot app. To support multiple nodes on the same endpoints e.g. by inspecting headers, cookies or whatnot, you can override
getNodeName()
. Alternatively, see path fragment based controllers bellow.
Path Fragment Based Controllers
Implement minimal controller subclasses of CorbeansBmnsBnoPathFragmentController
and/or CorbeansBmnsMemberPathFragmentController
like bellow:
@RestController
class MyBmnsBnoController: CorbeansBmnsBnoPathFragmentController()
@RestController
class MyBmnsMemberController: CorbeansBmnsMemberPathFragmentController()
This will expose the folowing endpoints:
Method | Path | Description |
---|---|---|
PUT | /api/bnms/bnos/{nodeName}/memberships | Activate a pending membership |
DELETE | /api/bnms/bnos/{nodeName}/memberships | Suspend an active membership |
GET | /api/bnms/members/{nodeName}/memberships | Get a memberships list from a BNO. URL params: bno (string) the BNO party name, filterOutMissingFromNetworkMap (boolean) whether to filter out anyone missing from the Network Map, default is true, forceRefresh (boolean) whether to force a refresh, default value is false |
POST | /api/bnms/members/{nodeName}/memberships | Request the BNO to kick-off the on-boarding procedure |
PUT | /api/bnms/members/{nodeName}/memberships | Propose a change to the membership metadata. |
Where nodeName
path fragment is one of:
- the node name (e.g.
partyA
for configuration properties that readcorbeans.nodes.partyA.*
) - the node identity organization name
- the node identity X500 name
Custom Controllers
Implement a controller by subclassing CorbeansBmnsBnoBaseController
or CorbeansBmnsMemberBaseController
depending on your requirements.