Sunday, 15 January 2017

A Vert.x Perception - WebSockets Revisited

Websockets has always been an interesting subject to me and I always believe there is more to explore. Every time I spend time with it accompanied with information from various other beautiful, informative blogs and posts I learn something new, and when it is complemented by Vert.x toolkit it becomes more interesting.

In my Previous Post, We discussed about implementing WebSockets with SOCKJS and used SOCKJS handler at the server side along with SOCKJS event bus at the client end.

In this post we will look forward to explore how WebSocket Handler handles requests and generates responses with the help of Web Socket protocol. Here is the GITHUB CODEBASE for reference.

We are citing an exmaple to see things in action.

Within SockJSVerticle the request handler for path /sendToSocket is the main Actor in Action here.
Within the Handler we have perfomrmed the following Tasks:

1) Creating an HttpClient and opening WebSocket Stream with the Client.


 HttpClient httpClient = vertx.createHttpClient(new HttpClientOptions())
 httpClient.websocketStream(8084,"localhost","/sendToSocket")

2) Writing the Data to be sent to with a Websocket.


handler({websocket->.......
...........
 .write(Buffer.buffer("Send Data to Server...".toUpperCase().getBytes()))
 ......

3) Using the Websocket to receive data with the help of WebSocketFrame.

 .frameHandler({webSocketFrame -> println "The Data at the Client Socket is:${webSocketFrame.textData()}"})
Now when we write data to the Websocket as described in Point 2, the control passes on to the WebSocketHandler that we have already registered with the Vert.x server in SockJSVerticle.groovy

 httpServer1.websocketHandler(new WebSocketHandler());
If we peek into this Handler we can see that it implements Handler which is MUST MUST for any Handler handling WebSocket requests, as the handle() method which has a ServerWebSocket is used to receive requests as well as create and sent reponses too (Here we have used WebSocketFrame to do the same).

 .frameHandler(new WebSocketFrameHandler({buf->serverWebSocket.writeBinaryMessage(buf)}))
Within WebSocketFrameHandler we have passed Consumer function. This function is being used to send the response from the request that we have received in the handle method of WebSocketFrameHandler

 void handle(WebSocketFrame frame) {
    println "The Data at the Server Socket is:${frame.textData()}"
    consumerbuffer.accept(frame.binaryData())
    }
The data that is sent from handler method of the path /sendToSocket is received by WebSocketFrame at the handle() method of WebSocketFrameHandler and which is being sent again with the help of the Consumer function, this function sends the data with the help of ServerWebSocket as the definition of the function contains:

{buf->serverWebSocket.writeBinaryMessage(buf)}...
This is in short about WebSocket.

Please share your comments and feedback.
View Subhankar Paul's profile on LinkedIn

Sunday, 8 January 2017

A Vert.x Perception - Service Registration N Discovery

Service Publishing and Service Discovery is the integral part of any Microservice Architecture. So it is for Vert.x .

Publishing and Discovering Service can be done very easily with Vert.x and it also provides fault tolerance mechanism with Vert.x's own Circuit Breaker implementation or with the help of Hystrix.

Let's start with Service Publishing and Discovery first.

Vert.x does provide a variety of service types to be published, for Ex:

1) HttpEndpoint
2) EventBusService
3) MessageSource
4) JDBCDataSource

Our discussion will focus mainly on HttpEndpoint, JDBCDataSource. The Service Discovery Codebase can be accessed here.

Let's Start with Service Publishing part first. Service publishing requires two steps to be followed.

1) Creating the required Service Instance.
2) Publishing the Service with the help of a Service Discovery.

For Publishing Service we are using the Server3.groovy verticle. Please note we are publishing the service only after the Server3 verticle is being successfully deployed.

 
                                    if(!server2AsyncResult.succeeded())
                                        server2AsyncResult.cause().printStackTrace()
                                    else{
                                        println "The Server 2 Deployed Successfully... \n\n So, " +
                                                "Publishing the Service..."
                                        publishService(startFuture,serviceDiscovery,"Server2")
                                        publishJDBCService(startFuture,serviceDiscovery,jdbcConfig,"MY-H2-DB")
                                    }
 
 
publishService() method publishes HttpEndpoint with the name Server2 while publishJDBCService() method publishes JDBCDataSource with the name MY-H2-DB.

HttpEndpoint Service:

The HttpEndpoint is being created with:
 
 HttpEndpoint.createRecord(....
 
 
by passing service name, hostname, port and the relative URI for which the endpoint should be created.

JDBCDataSource Service:

Similarly, the JDBCDataSource service is created with:
 
  JDBCDataSource.createRecord(....
 
 
by passing the service name, DataBase Config and the DB name as the parameter.
The DataBase config basically consists of URL, Driver_Class, user, password and other DB specific parameters.

The error handling during publishing can be handled with the Handler provided as part of publish(.... method.
This is in short a very Basic description of the Service Publishing in Vert.x

Now, Any Service that is published is meant to be consumed.
So, let's move on to Service Discovery and subsequent Service consumption.

As said earlier, Fault Tolerance is an integral part any Microservice Architecture to isolate points of access to remote systems, services and 3rd party libraries and hence stop cascading failures and enable resilience in complex distributed systems where failure is inevitable.

With Service Discovery section Fault Tolerance is inherently related, but we will take it as a separate topic. within codebase, fault tolerance related work could be observed, I would discuss those sections again in our next post related to Circuit Breaker .

HttpEndpoint Discovery

We have defined a Handler for /dataServer2 in Server2.groovy Verticle, because this the relative URI for which HTTPEndpoint is created.

Upon invoking the this endpoint with the corresponding client the Handler will get executed which we will see very shortly.

The Discovery of any service has the following generic steps to be followed:

1) Fetch the the corresponding Record with the Service name with which it is published.

   serviceDiscovery.getRecord(....
 
 
2) Upon Successful Record fetch (as verified from the Hnadler), we get the Service Reference Type

 def reference = serviceDiscovery.getReference(ar.result())
 
3) From the Service reference we fetch the client that will be used in invoking of consuming the service.

 def client = reference.get()
 
4) Finally we consume the service and fetch the result. The Result in this case will be fetched from Handler for /dataServer2 as described above.

The HttpEndpoint service discovery can be found at Server3.groovy under the method invokeServer2() and this method is being invoked as part of the request handler for the URI /getServer2 i.e.

 
   router.route(HttpMethod.GET,'/getServer2').handler({routingContext->
            println " ***** Invoking Server2 with Service Discovery ***** "
            invokeServer2(routingContext,serviceDiscovery,circuitBreaker);})
 
 
The Codebase can be accessed here.

JDBCDataSource Discovery

For JDBCDataSource Service the steps to be followed for Service consumption is same as above the only difference is we use this service to fetch a JDBC connection and carry out some DataBase activities.

The HttpEndpoint service discovery can be found at Server3.groovy under the method fetchJDBC() and this method is being invoked as part of the request handler for the URI /getJDBC i.e.

   router.route(HttpMethod.GET,'/getJDBC').handler({routingContext->
            println " ***** Fetching JDBC with Service Discovery ***** "
            fetchJDBC(routingContext,serviceDiscovery,circuitBreaker);})
 
This is short very Basic on Service Discovery. Please feel free to share your thoughts and feedback.

In our next post we will try to discuss on Circuit Breaker. Till then Keep Coding and Keep Sharing.

View Subhankar Paul's profile on LinkedIn

Monday, 2 January 2017

A Vert.x Perception - Websockets with Vert.x Basics

To learn and understand WebSocket operation in Vertx I have taken the reference of the blog

Blog

.
The codebase can be accessed

HERE



The starting point of this app is index.html which makes websocket request with the help of Vertx-Eventbus. To use Vertx Eventbus we have used here a js for sending the request through Eventbus.

The request is being sent with the help of a js function sendData which is a part of realtime-auctions.js and which is invoked while clicking the Button with the value bid.

In realtime-auctions.js there is a function registerHandlerForUpdateCurrentPriceAndFeed() where we have created a EventBus and registered a Handler to receive events.

When this function is triggered during onload of index.html, the handler for the path "/eventbus/*" (as described in SockJSVerticle.groovy) is invoked because of:

router.route("/eventbus/*").handler(eventBusHandler())
and the BridgeEventType.SOCKET_CREATED event is published.
Now we can say that the Event Bus Handler is ready to send and receive messages.
So on clicking the bid button from the index.html data 'price': '0007' is being sent to the Handler as described above and the BridgeEventType.SEND event is published and from there we are again publishing data to the eventbus and that is received by the handler registered during html page onload and which makes the necessary changes within the page.

Similarly we have also registered another Handler:

 router.route("/api/test").handler(new EventBusHandler().&generateSockData)
 
So, when we access the URL http://host:port/context/api/test it independently publish data to the event bus and that too being received by the handler at the html page in the same way as described above.

So once the client side handlers are being registered, then those are capable of receiving messages as published from the server end, provided the eventbus name which is here 'auction' needs to be mentioned correctly. So, If we need to send and receive data over a different eventbus Say, for example 'auction2' then we need to register handler at for this eventbus both at the client and server end separately to send and receive data.

Similarly, while sending request data also, Eventbus with the same name (i.e. aution) is being registered at the sever end end with the help of BridgeOptions as used in SockJSHandler which then is used to intercept the request data.

View Subhankar Paul's profile on LinkedIn