//Install express server
const express = require('express');
const path = require('path');
const app = express();
// Serve only the static files form the dist directory
app.use(express.static(__dirname + '/dist'));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname + '/dist/index.html'));
});
// Start the app by listening on the default Heroku port
app.listen(process.env.PORT || 8080);
In this article, I wanna share my thought about migrating a system from monolithic architecture to microservices architecture. Is it easy game or not. Let’s start!
Monolith Architecture
A monolithic application has single code base with multiple modules. Modules are divided as either for business features or technical features. It has single build system which build entire application. It also has single executable or deployable binary.
Microservices Architecture
A microservices architecture consists of a collection of small, autonomous services. Each service is self-contained and should implement a single business capability.
When do migration?
The system has high requirements related to reliability and scalability
The expected product development requires involving more than one team
The product needs quick and independent deployment because microservices allow for fast, independent delivery of individual parts within a larger, integrated system
How much the cost to do migration?
Complexity: the entire system as a whole is more complex especially when the number of services increases.
Development and Test: refactoring across service boundaries can be difficult. It is also challenging to test service dependencies.
Data Integrity: with each microservice responsible for its own data persistence. As a result, data consistency can be a challenge.
Network congestion and latency: when one business requires involving a lot of services dependencies, the latency can become a problem.
Management & Versioning: It could have problems with backward or forward compatibility when updating version of services.
Development team Skillset
Let’s try doing sample to migrate from monolithic to microservices. Take a look the exchange usecase below
Multiple users are using exchange for trading
Exchange receives buy/sell orders
Exchange matches orders between buyers and sellers
Exchange broadcasts updated order book to all users
Exchange Use Case
The monolithic architecture should be
Exchange Monolithic Architecture
To migrate to microservices architecture, we should do something below
Separate API to multiple smaller APIs
Using Event Bus (Publish–Subscribe pattern) to communicate all services
Using Api Gateway to aggregate as a single entry point into a system
From simple sample, it takes much effort to do migration and quite hard for testing and deployment.
Microservices are the latest software architecture trend, it can make more valuable but not a God. Personally I wanna recommend undertaking on a careful consideration process before diving in. Migrating monolithic to microservices could be more shit than we think.
To play with Docker on Windows, we have 2 options:
Docker for Windows: Docker for Windows requires that you’re running Windows Pro, Enterprise, or Education edition.
Docker Toolbox: if you have Windows 10 Home, this is only one option for you. Because Microsoft doesn’t currently allow Hyper-V to be installed on Home editions.
Option #1 is perfect one but there’re many issues when you go with option #2. And the most issue you could face is “Visual Studio Container Tools requires Docker to be running before building, debugging or running a containerized project”
To solve this, you should go following steps:
Check if the Hardware Virtualization is Enabled.
Install Docker Toolbox which is not legacy and works fine with Virtualbox.
Run Visual Studio from inside Docker Quickstart Terminal. ( /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2017/Community/Common7/IDE/devenv.exe C:\\PATH\\TO\\MY\\SOLUTION.sln)
Decentralized RideSharing platform can connect drivers directly with passengers via instant P2P protocol.
Here are the contents of this tutorial: Part 1: Decentralized Ridesharing – Solution Part 2: Decentralized Ridesharing – Creating smart contract Part 3: Decentralized Ridesharing – Building DApp Part 4: Decentralized Ridesharing – Deploying on blockchain
In this part, we’ll go through following points
Centralized Ridesharing concerns
Decentralized Ridesharing solution
Solving Booking Use Cases
DApp Architecture
Demo
Ready? Let’s start…
Centralized RideSharing concerns
High fees due to middleman: the ridesharing companies likes Uber, Lift and Grab could charge 10-30 percent of the total passenger’s pricing, costing high to the customers. Therefore, the involvement of intermediaries between a driver and a passenger will lead to increase costs.
Lack of transparency: if you have ever used ridesharing services, you must have faced a problem of surge pricing. Passengers don’t have a clear understanding of the reason behind the sudden price rise. Or another problem – driver’s rating, the company can cheat data completely if they want.
Lack of safety: one of the most important issues is the concern about the safety of both passengers and drivers. Taxi organizations are spending millions of dollars to verify users. But despite efforts, identities and criminal still exist.
Decentralized RideSharing solution
By moving from centralized platform to decentralized platform, taking advantages of the Blockchain, using Smart Contract so that:
Getting middleman out of the game, passengers pay less, drivers are paid more.
Drivers and passengers control the transactions, own the data, and transact securely through a peer-to-peer network.
All data transparent, no one can modify or cheat data.
In this tutorial, we’ll build a DApp and use Smart Contract on Blockchain to solve the concerns above.
Solving Booking Use Cases
In this tutorial, I want to show you to how to solve basic use cases as below
Passenger creates a booking
New booking is created with trip info (passenger info, location origin/destination, distance, cost…)
Tokens (cost) will be transferred from passenger’s wallet to smart contract.
Driver accepts a booking
Passenger cancels a booking
Cost will be refunded from smart contract.
Booking is cancelled.
Passenger completes a booking
Tokens (cost) will be transferred from smart contract to driver’s wallet.
Booking is completed.
DApp Architecture
We’ll be using the following tech stack to develop our application.
DApp: Decentralized Applications are applications that run on a P2P network of computers. If an App = frontend + server, since Ethereum contracts are code that runs on the global Ethereum decentralized peer-to-peer network, then: DApp = frontend + contracts
IPFS: IPFS stands for InterPlanetary File System. It’s a protocol designed to create a permanent and fully decentralized method to store and share files. A decentralized app should be hosted on decentralized storage.
Ethereum: Ethereum is an open-source, public, blockchain-based distributed computing platform and operating system featuring smart contract (scripting) functionality.
Web3.js: collection of libraries which allow you to interact with a local or remote ethereum node, using a HTTP or IPC connection.
Metamask: is a bridge that allows you to visit the distributed web of tomorrow in your browser today. It allows you to run Ethereum dApps right in your browser without running a full Ethereum node.
React/Angular: front-end javascript library/framework to develop web app.
Demo
Below is demo running on GoChain TestNet. You can develop on Ethereum of course, but I want to deploy on GoChain because it’s a scalable, Ethereum based smart contract blockchain that is fast, secure and 100x increased performance .
Overview: Identity Server 4 & Resource Owner Password
Most modern applications look more or less like this:
IdentityServer is middleware that adds the spec compliant OpenID Connect and OAuth 2.0 endpoints to an arbitrary ASP.NET Core application.
Grant types are a way to specify how a client wants to interact with IdentityServer. There are many types you can take a look here. I wanna focus on 2 common types almost applications applied.
Resource owner password: the grant type allows to request tokens on behalf of a user by sending the user’s name and password to the token endpoint. This is always used for Server App.
Client credentials: the simplest grant type and is used for server to server communication – tokens are always requested on behalf of a client, not a user. This is often used for Native App.
Scenario
I need to develop an application meets requirements below:
Back Office: Admin User can access via username/password.
Mobile App: Navative App User can access via phone number and passcode.
All requests to Resource Server must be authenticated via token from Identity Server issued.
Resource Server must identify users made requests.
The problem is Identity Server uses Client Credential grant type to authenticate with Native App User, the Resource Server will not identify who user is. Identity Server issues token without user information due to using Client Credential.
To identify user the Identity Server have to use Resource Owner Password grant type as treated with back office users.
Customization
Implementing ResourceOwnerPasswordValidator
namespace IdentityServer
{
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
TestUser user = null;
// verify username password
user = Config.GetUsers().FirstOrDefault(p => p.Username == context.UserName && p.Password == context.Password);
if (user != null)
{
context.Result = new GrantValidationResult(user.SubjectId, OidcConstants.AuthenticationMethods.Password);
}
else
{
// verify phone number and auth code
var authCode = context.Request.Raw["AuthCode"];
var phoneNumber = context.Request.Raw["PhoneNumber"];
user = Config.GetUsers().FirstOrDefault(p => p.Claims.Any(k => k.Type == "AuthCode" && k.Value == authCode)
&& p.Claims.Any(k => k.Type == ClaimTypes.MobilePhone && k.Value == phoneNumber));
if (user != null)
context.Result = new GrantValidationResult(user.SubjectId, OidcConstants.AuthenticationMethods.Password);
}
return Task.FromResult(0);
}
}
}
Customizing request from client
// using token client to request token
var clientId = "ro.client";
var clientSecret = "secret";
var tokenClient = new TokenClient(disco.TokenEndpoint, clientId, clientSecret);
// get token by phone/authcode
var extra = new Dictionary<string, string> { { "AuthCode", "1111" }, { "PhoneNumber", "0901111111" } };
var tokenClientResponse = await tokenClient.RequestResourceOwnerPasswordAsync("xxx", "xxx", extra: extra);
//// get token by username/password
//var tokenClientResponse = await tokenClient.RequestResourceOwnerPasswordAsync("alice", "password");
Yesterday, the client asked me a question “Hi guys, are we using any password hashing and salting methodology?”. I’m sure that almost developers would say MD5 :). It could be the best answer… for ten years ago :v. Now the power of computers will brute-force them… in one music note :v.
Everybody knows to use hashing function to hash password but who knows which algorithm it uses!? So, let try exploring the asp.net identity source-code and saw some codes as attached screenshot.
Boom! It uses PBKDF2 with HmacSHA1 algorithm. Is it interesting!?