Wednesday, May 27, 2020

How to Setup Scalable ASP.NET MVC Core with Alibaba Cloud Container Service?

Today I would like to share how to deploy ASP.NET MVC Core web application to Alibaba Cloud Container Service and also how to enable automatic horizontal scalability by using Serverless Kubernetes.

First, let's create a simple web application using Visual Studio 2019 Community.


We are going to build a docker image and publish to the Alibaba Cloud Container Registry, so remember to check Enable Docker Support. I also presume that you have installed Docker Desktop already.


While you are developing your own web application, you can choose to run the debug mode in IIS Express, self-hosted console or Docker.

Once you are happy with your coding and ready for deployment, go to Alibaba Cloud Container Registry to register a repository.


Once you have created a container repository, you will expect to see the following screen.


Clicking the Repository will bring you to the docker image push guide page. Follow the instruction below to push your docker image to the Alibaba Cloud.


So, back to your PC, fire up command prompt. Change directory to where your ASP.NET MVC Core project folder where you see the Dockerfile exist.

Now, execute the following command to compile your application and create a docker image.

docker build -f Dockerfile ..


Then, execute the docker images command to show your docker image ID.

Now, follow the steps mentioned in Alibaba Cloud Container Registry:

docker login xxxxxxx
docker tag xxxxxxxxx
docker push xxxxxxxx


Now, your docker image has been pushed to the cloud. You may proceed to create a Kubernetes Cluster now. There are many type of cluster, for my own research and testing purpose, I have chosen Standard Serverless Cluster.


Pick a region and select whatever setting that suit you.


Once you have done creating the new Kubernetes Cluster, now proceed to the Applications \ Deployments page to deploy your docker image to Kubernetes Container

Fill up all the required information and select the Cluster as the one you had created in previous step.


Go to next page, then select the Image and Image Version. You will be able to see the docker image that you had pushed in the earlier step.


Select the CPU and Memory you need for each container. Then, configure the port for HTTP.



Go to next page to create a Service with Load Balancer. If you had created Load Balancer before, you can choose the existing one. Or, you can select Create SLB Instance like what I had done in this screen:


Now, setup the Ingress for your Load Balancer Service.


For the automatic horizontal scalability base on the server load, you can turn on the HPA (Horizontal Pod Autoscaler) feature, setup the condition of when should Kubernetes replicate a container to take up more load. For instance, I have setup minimum replica to begin with and if CPU of the replica hit 70% or above, it should replicate a new container immediately, and maximum up to 10 replica. 


Then, hit the Create button, the Kubernetes service will be setup.

The following is how the Kubernetes Cluster screen look like:


If you want to test whether your ASP.NET MVC application is hosted successfully, simply go to the Container Service page, then go to the Dashboard screen.

 You can check your application status here.


Now, go to the Discovery and Load Balancing section, you can find your load balancer public endpoint IP address.


Simply hit the IP address, it should bring you to your web application.

In summary, horizontal scaling is always a pain in the arse before docker and Kubernetes exists during the old days. We have to spend a lot of money in purchasing the server in advance and manually power up the server, configure the web service and load balancer. With Alibaba Cloud Container Service, imagine how much money we could save from having system engineers and developers in working on the deployment job.


Wednesday, May 6, 2020

How to Setup a Quorum Block Explorer in ECS?

As promised from the previous post, once the Quorum nodes are done setting up, we need a blockchain explorer to visualize the block activity. In this post, I will share how to setup Cakeshop, a set of tools and APIs for working with Quorum.

First, you can consider either setting it up on your existing ECS which is hosting with 4 Quorum nodes, or provision a separate new ECS from Alibaba Cloud.

Next, I would suggest go to the /mnt directory then create a new directory call cakeshop, then download the latest version of Cakeshop WAR file by issuing the following command:
wget https://github.com/jpmorganchase/cakeshop/releases/download/v0.11.0/cakeshop-0.11.0.war
I expect you have installed Java if you followed my previous post installing Tessera, otherwise please install Java by executing the following command. 
sudo apt install openjdk-11-jre-headless
Due to the reason that we already had an existing Quorum node running, hence we install the Cakeshop with attach mode. Therefore, execute the following command to extract the WAR file:
java -jar cakeshop-0.11.0.war example

Now go to diretory /mnt/cakeshop/data/local, open file editor with application.properties, change the geth.auto.start=false and geth.auto.stop=false


Alternatively, if you want to enable auto start, then change the following value accordingly to your Quorum node startup script which is located at /mnt:


For instance, the above setting is base on my following Geth startup script:
#!/bin/bash
PRIVATE_CONFIG=ignore nohup geth --datadir node1 --nodiscover --verbosity 5 --networkid 33333 --raft --raftport 50401 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21001 >> node1.log 2>&1 &

After saving the application.properties file, execute the following command to start the blockchain explorer:
java -jar cakeshop-0.11.0.war
Wait for a while until you see this screen:



Now, your blockchain explorer is up and running, open your browser, then navigate to your server IP at port 8080, or browse the blockchain explorer at http://localhost:8080/

Look for the function Manage Nodes on the top right corner of the explorer. Then, click the Add Node button. Enter the Node Name, then Geth RPC Url which for my case is 21001 where you can find it in the Geth startup script. I also setup my Tessera which the default port is unchanged, or you can find it in my previous post that mentioning the Tessera config file at /mnt/node1t/config.json.



Once you are done, click the View button, it will bring you to the Dashboard page, and you will see blockchain explorer should attach to your existing Quorum node.

Enjoy playing around with the blockchain explorer, you can deploy contract, transfer ETH from wallet to wallet and even check who are the peers connecting and also managing your node.

Saturday, May 2, 2020

How to Setup Transaction Privacy Between Quorum Nodes using Tessara?

Continue from the previous blog post about setting up Quorum node on Alibaba Cloud ECS instance, there is an optional module available for us to protect our transaction data privacy by limiting the data being exposed to certain authorized nodes.

Tessera is an independent software developed using Java and what it does is to perform data encryption for transaction dedicated to authorized nodes, and this software is sitting on top of Quorum node. The following diagram explain well how it perform the data encryption and decryption of the transaction:


As you can see Node A and B are in the same context but not Node C. When there is a transaction data being fed into the Node A, the transaction being encrypted and save the data into the private store.

The Node B Tessera is being configured to recognized Node A Tessera, and both share the same encryption key so that the authorized nodes manage to encrypt and decrypt the private store data.

So, today we are going to setup Node 1 and Node 2 to have Tessera protect their transaction privacy from the Quorum blockchain that I had setup from the previous post.

Environment

As mentioned earlier, Tessara is developed using Java, therefore, we need to make sure our node is installed with JDK 11 or latest by executing the following command:
sudo apt install openjdk-11-jre-headless

Installation

First, download Tessera installation file by executing the following command:
wget https://oss.sonatype.org/service/local/repositories/releases/content/com/jpmorgan/quorum/tessera-app/0.10.4/tessera-app-0.10.4-app.jar

Alternatively, you can also download the installation file manually at https://github.com/jpmorganchase/tessera/releases

Next, go to the mounted data disk directory, make directory for 4 nodes.



Then, move the Tessera software to the /mnt path, then execute the following command to create the key sets.
java -jar tessera-app-0.10.4-app.jar -keygen -filename t1
java -jar tessera-app-0.10.4-app.jar -keygen -filename t2 


Now, move the key files to the node1t and node2t folder:


Create a file call config.json, then copy and paste the follow content to the config file:

{
   "useWhiteList": false,
   "jdbc": {
       "username": "sa",
       "password": "",
       "url": "jdbc:h2:/mnt/node1t/db;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=0",
       "autoCreateTables": true
   },
   "serverConfigs":[
       {
           "app":"ThirdParty",
           "enabled": true,
           "serverAddress": "http://localhost:9081",
           "communicationType" : "REST"
       },
       {
           "app":"Q2T",
           "enabled": true,
            "serverAddress":"unix:/mnt/node1t/tm.ipc",
           "communicationType" : "REST"
       },
       {
           "app":"P2P",
           "enabled": true,
           "serverAddress":"http://localhost:9001",
           "sslConfig": {
               "tls": "OFF"
           },
           "communicationType" : "REST"
       }
   ],
   "peer": [
       {
           "url": "http://localhost:9001"
       },
       {
           "url": "http://localhost:9002"
       },
       {
           "url": "http://localhost:9003"
       },
       {
           "url": "http://localhost:9004"
       }
   ],
   "keys": {
       "passwords": [],
       "keyData": [
           {
               "privateKeyPath": "/mnt/node1t/t1.key",
               "publicKeyPath": "/mnt/node1t/t1.pub"
           }
       ]
   },
   "alwaysSendTo": []
}

Save the file, then exit. Then, execute the following command to kick start the Tessera process:
java -jar ../tessera-app-0.10.4-app.jar -configfile config.json >> tessera.log 2>&1 & 

When you see the tm.ipc file is exist in the node1t folder, it indicate that you have done it correctly and the Tessera process is running now. If you do not see, not to worry, wait for a few more seconds, or check the tessera.log file to see what went wrong.

Repeat the above config file creation step for the node2t, refer to the color highlighted value that need to be modified accordingly to the right node config.

Now, go to your data disk mount directory which is located at /mnt, open the file startnode1.sh with file editor, then modify the PRIVATE_CONFIG value to the Tessera ipc file path.


To:


After modifying and saving the startnode1.sh and startnode2.sh, straight away execute both scripts.

Testing

First, let's get Node 2 public key because it is required for setting up private smart contract by executing the following script at the /mnt/node2t:
cat t2.pub
You will get the public key value which look like this:


Then, go to the /mnt directory, create a test sample smart contract called private-contract.js, then copy and paste the following content to the new file, but remember to change the value for privateFor to your node 2 Tessera public key which you got it from previous step:

a = eth.accounts[0]
web3.eth.defaultAccount = a;

// abi and bytecode generated from simplestorage.sol:
// > solcjs --bin --abi simplestorage.sol
var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"payable":false,"type":"constructor"}];

var bytecode = "0x6060604052341561000f57600080fd5b604051602080610149833981016040528080519060200190919050505b806000819055505b505b610104806100456000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632a1afcd914605157806360fe47b11460775780636d4ce63c146097575b600080fd5b3415605b57600080fd5b606160bd565b6040518082815260200191505060405180910390f35b3415608157600080fd5b6095600480803590602001909190505060c3565b005b341560a157600080fd5b60a760ce565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b6000805490505b905600a165627a7a72305820d5851baab720bba574474de3d09dbeaabc674a15f4dd93b974908476542c23f00029";

var simpleContract = web3.eth.contract(abi);
var simple = simpleContract.new(42, {from:web3.eth.accounts[0], data: bytecode, gas: 0x47b760, privateFor: ["83vHGB2IGbmObH8Dl/tHWadA5KUQ3u7DxIs2byOuiQU="]}, function(e, contract) {
    if (e) {
        console.log("err creating contract", e);
    } else {
        if (!contract.address) {
            console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
        } else {
            console.log("Contract mined! Address: " + contract.address);
            console.log(contract);
        }
    }
}); 

Once done, save and exit from the file editor.

Now, attach geth to the Node 1 by executing the following command:
geth attach node1/geth.ipc
Then, before we could deploy smart contract, we need to unlock our account first by issuing the following geth command:
personal.unlockAccount(eth.accounts[0])
You will be prompted to key in the passphrase of your account which you had setup following my previous post.

Once you have unlocked your account, load the private contract script by issuing following geth command:
loadScript("private-contract.js") 
You will notice the returned transaction hashed and mined contract address which indicate the success of deploying smart contract.


Up to this stage, you are considered as successfully setup Tessera in your Quorum. However, we need a block explorer to further visualize how your blockchain work. In my next post, I will share how to setup a Quorum block explorer. Stay tuned!


Send Transactional SMS with API

This post cover how to send transactional SMS using the Alibaba Cloud Short Message Service API. Transactional SMS usually come with One Tim...