Building a blockchain application in Java using Amazon Managed Blockchain : idk.dev

Amazon Managed Blockchain allows you to easily set up and scale blockchain networks. You interact with the chaincode using the Hyperledger Fabric Command Line Interface (CLI). Your blockchain application interacts programmatically with your network using the Hyperledger Fabric SDK. For more information about creating a Hyperledger Fabric network, setting up members, creating channels, and deploying chaincode on your network, see Get Started Creating a Hyperledger Fabric Blockchain Network Using Amazon Managed Blockchain.

This post demonstrates how to set up a blockchain application written in Java to read and write data to Managed Blockchain using the Fabric Java SDK. The Java SDK allows customers with applications written in Java to integrate blockchain support with their existing codebase. This makes it easier to handle rich data structures and complex business logic before writing records to the blockchain. You can also integrate Managed Blockchain using the Fabric Node.js SDK. For more information, see Building serverless blockchain application with Fabric Node.js SDK.

In this post, you create a sample Java application that consists of a REST API server communicating with the blockchain network. You can run a REST API server on AWS either via an Amazon Elastic Compute Cloud (Amazon EC2) instance or using Amazon API Gateway and AWS Lambda.

Our application uses Lambda instead of an EC2 instance to avoid the operational overhead of provisioning and managing a server. Two benefits of the Lambda architecture are built-in scaling and fault-tolerance. Moreover, Lambda functions only incur costs when running, thus enabling high cost-optimization.

Solution overview

This post walks you through creating a blockchain application in Java running on Lambda that interacts with your blockchain network using the Fabric Java SDK. API requests are first sent to API Gateway, which dispatches the requests to Lambda. API Gateway allows you to securely authenticate and authorize incoming requests before forwarding them to Lambda. The solution also uses AWS Secrets Manager to securely store and retrieve the credentials required to transact on the blockchain network.

The following diagram illustrates the architecture of the solution.

The architecture consists of the following components:

  • API Gateway configured with Lambda proxy integration
  • A Java Lambda function integrating with the Fabric Java SDK and running in a custom VPC within a private subnet
  • VPC endpoints to access to Secrets Manager and Managed Blockchain
  • Secrets Manager to store Fabric users’ credentials
  • Managed Blockchain, which includes all the Hyperledger Fabric components (peer node, certificate authority (CA), and ordering service)

The incoming request originates from a web or a mobile application and goes to API Gateway. The request is forwarded from API Gateway to the Lambda function that runs the blockchain application written in Java using Spring Boot 2.

The application uses the Hyperledger Fabric SDK to interact with Managed Blockchain. Because the Lambda function doesn’t need to communicate with the outside world, it sits in a custom VPC within a private subnet. It communicates with Managed Blockchain and Secrets Manager using VPC endpoints. Using VPC endpoints allows private connection between your VPC and AWS services and the encrypted traffic stays within the AWS network without traversing the public internet.

Hyperledger Fabric networks require Fabric user credentials to read and write data to the blockchain. To achieve this, the Lambda function first reads the connection information (such as orderer endpoint, CA endpoint, and peer endpoint) from Lambda environment variables. It retrieves the Fabric user credentials from Secrets Manager, creates a Fabric user context, and uses it to build a request to query the chaincode. The request is sent to one of the peer nodes in Managed Blockchain. A peer node fulfills the query request and sends back the response to the Lambda function. The response is sent to the API Gateway, which transfers it to the requesting client.

The API Gateway in this solution is configured in Lambda proxy integration. For more information, see Set up Lambda proxy integrations in API Gateway.

The complete end-to-end architecture presented here is provided in the GitHub repo. Download it to follow the step-by-step guide.

Walkthrough

Each step of the walkthrough has a matching step in the repo, with additional info provided in the README file. You can follow along with the steps and the code base in the repo to gain a more in-depth understanding.

To implement the solution, you complete the following steps:

  1. Configure the project.
  2. Build and deploy the serverless stack using the AWS Serverless Application Model (AWS SAM) CLI.
  3. Register and enroll lambdaUser with the Fabric CA using the SDK.
  4. Test the application and interact with Managed Blockchain.

Prerequisites

You must have a Managed Blockchain network up and running with at least one chaincode installed and instantiated before proceeding further.

If you don’t have a blockchain network in your AWS account, follow the steps in Get Started Creating a Hyperledger Fabric Blockchain Network Using Amazon Managed Blockchain and complete it up to step 7 before continuing this post. After completing the guide, you will have the chaincode mycc instantiated in your network. You interact with this chaincode later in this post.

The example project uses AWS SAM to ease the deployment process. For installation instructions, see Installing the AWS SAM CLI. In the installation guide, you can skip the Docker installation step; it’s not required in this post.

Configuring the project

In this step, you set up and configure a Java application in Spring Boot 2 to run on Lambda and integrate it with the Fabric SDK. The configuration discussed in this step is done for you on the sample project on GitHub; you don’t need to configure anything. This step helps you better understand the configuration required and makes it easier to adopt to your own application.

The sample project is built using Spring Boot 2 framework, which allows you to easily set up a REST API Server in Java. However, Spring Boot by default isn’t optimized to run on Lambda. Therefore, the project integrates the AWS Serverless Java container library, which makes it easy to run Spring Boot on Lambda. This library acts as a Servlet container; it receives events object from Lambda and translates them to a request object for the Spring Boot framework. Similarly, it translates responses from the framework into valid return values for API Gateway. Finally, it natively supports API Gateway proxy integration models for requests and responses. For more information, see Running APIs written in Java on AWS Lambda.

To set up AWS Serverless Java container with Spring Boot 2, the sample application provides an implementation of the interface RequestStreamHandler in the class StreamLambdaHandler, as shown in the following code. This class serves as the main entry point to the Lambda function.

public class StreamLambdaHandler implements RequestStreamHandler {
    private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;

    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
        } catch (ContainerInitializationException e) {
            // if we fail here. We re-throw the exception to force another cold start
            e.printStackTrace();
            throw new RuntimeException("Could not initialize Spring Boot application", e);
        }
    }

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        handler.proxyStream(inputStream, outputStream, context);
    }
}

Next, you need to integrate Hyperledger Fabric Java SDK library in your application to interact with the Fabric network. The sample project achieves this by adding the following dependency in the dependencies section of pom.xml:

<dependency>
    <groupId>org.hyperledger.fabric-sdk-java</groupId>
    <artifactId>fabric-sdk-java</artifactId>
    <version>1.2.0</version>
</dependency>

Building and deploying the serverless stack using AWS SAM CLI

The Fabric SDK needs the Managed Blockchain TLS certificate chain to connect to your blockchain components. Copy the TLS certificate chain from Amazon Simple Storage Service (Amazon S3) to the project’s resources folder.

Next, build the project using the AWS SAM CLI sam build command. The build process is configured to exclude the Apache Tomcat server dependencies that comes by default with Spring Boot. Tomcat isn’t required because the Java application uses AWS Serverless Java container to run on Lambda with API Gateway.

You need to set a few environment variables for the Lambda function to register and enroll the new Fabric user lambdaUser. This user is dedicated for the Lambda function and is created in the next step. You need to provide the Fabric CA admin’s credentials for the registration process. Set the Fabric CA admin user name and password you used to create the Managed Blockchain network, and a choose a new password for lambdaUser (see the following code). In your own environment, choose a strong and unique password and consider using Secrets Manager or AWS Systems Manager Parameter Store to store these settings securely.

export ADMINUSER='YOUR_CA_ADMIN_USER'
export ADMINPWD='YOUR_CA_ADMIN_PASSWORD'
export LAMBDAUSERPWD='LamdaUserPwd1'

You’re now ready to deploy the AWS SAM template, which creates the following AWS resources:

  • Java Lambda function
  • API Gateway with endpoints to:
    • Register and enroll user
    • Query chaincode
    • Invoke chaincode
  • Custom VPC for Lambda with a private subnet without internet access
  • Two VPC endpoints for private communication between:
    • Lambda VPC and Managed Blockchain
    • Lambda VPC and Secrets Manager

To start the deployment, set the name of your blockchain network created in the prerequisites section:

export NETWORKNAME='YOUR_NETWORK_NAME'

Run the provided script deployLambda.sh to deploy the stack. The script exports all the required settings for Managed Blockchain (such as NETWORKID, MEMBERID, PEERID, and PEERENDPOINT). To ease the deployment process, the script retrieves your blockchain network settings using the AWS Command Line Interface (AWS CLI) commands. For more information, see Managed Blockchain Available Commands.

The script then creates an S3 bucket to host the Lambda source code and runs sam deploy to deploy the stack.

When the deployment is successful, you see an output similar to the following code:

$ ./deployLambda.sh
...
CloudFormation outputs from deployed stack
-----------------------------------------------------------
Outputs
-----------------------------------------------------------
Key                 BlockchainLambdaApi
Description         URL for Managed Blockchain Lambda Function
Value               https://XXXXXX.execute-api.us-east-1.amazonaws.com/
-----------------------------------------------------------
Successfully created/updated stack - lambda-java-blockchain in us-east-1
Lambda source code is stored in the S3 bucket - lambda-java-blockchain-sam-bucket-xxxxxxxxxx

Record the URL of the API that has been deployed; you use it in the following steps to interact with the Lambda function. You can also retrieve the URL on the AWS CloudFormation console: find the stack named lambda-java-blockchain and choose the Outputs tab.

On the sample project, the URL of the API is publicly accessible for testing purposes. In your own application, you should protect your API; for example, by integrating with Amazon Cognito user pools. For more information about API access, see Controlling and managing access to APIs in API Gateway.

For step-by-step instructions, see Step 2 – Build and deploy the serverless stack on the GitHub repo.

Registering and enrolling lambdaUser with the Fabric CA using the SDK

To interact with Hyperledger Fabric you need Fabric user credentials that are known by your organization’s Fabric CA.

To create a new user from the SDK, you enroll the admin user with the Fabric CA, which returns the credentials for the admin. You use the admin’s credentials to register and enroll a new Fabric user named lambdaUser dedicated for the Lambda function. The API Gateway provisioned in the previous step provides an endpoint /enroll-lambda-user to do this. In your own application, you may consider generalizing this endpoint so it can operate with additional parameters (such as user name and password) and handle registration and enrollment for many users. Use the API URL of your API Gateway and send the request to the /enroll-lambda-user endpoint to register and enroll the new user. See the following code:

$ export API_URL=API_URL_FROM_STEP_2
$ curl -s -X POST "${API_URL}/enroll-lambda-user"
lambdaUser registered and enrolled successfully

When the user is successfully registered with the Fabric CA, the enrollment process issues an enrollment certificate, which consists of a private key and a signing certificate. Secrets Manager stores these files, and the Lambda function can use them to sign transactions submitted to Managed Blockchain.

By default, the Lambda function is configured to query and invoke transactions in the blockchain on behalf of lambdaUser.

For more information about Fabric User enrollment using the AWS CLI, see Register and Enroll an Admin.

Testing the application by interacting with Managed Blockchain

You’re now ready to interact with the chaincode deployed in your blockchain network. You start with the sample chaincode mycc that you created in Step 7 of Get Started Creating a Hyperledger Fabric Blockchain Network Using Amazon Managed Blockchain.

Use the API URL of your API Gateway from Step 2 and use the endpoints /invoke and /query to send requests to the chaincode. For instructions, see Step 4 – Test the application and interact with Managed Blockchain on the GitHub repo.

The /query and /invoke endpoints are generic and work with any other chaincode. You can change the value of the following query parameters to interact with any other chaincode:

  • chaincodeName – The name of the chaincode
  • functionName – The name of the function to query or invoke
  • args/argList – The arguments to pass to the query or invoke functions

Conclusion

In this post, you learned how to build a serverless blockchain application in Java that communicates with your Managed Blockchain network using the Fabric Java SDK. You deployed an API Gateway with Lambda proxy integration that forwards incoming requests to a Java Lambda function, which communicates with the blockchain.

As a next step, you could enrich the application by creating new API endpoints to interact with other chaincodes. You could also explore other features of the Fabric SDK such as creating channels, installing, and upgrading chaincode.

 


About the author

Bishesh Adhikari is a Blockchain Prototyping Architect at AWS Prototyping team. He works with AWS customers to build prototypes on Blockchain and Machine Learning, which accelerates their journey to production. In his free time, he enjoys hiking, travelling, and spending time with family and friends.