Thursday, March 7, 2019

Learning Microservices with a Practical Example

Although this example application is simplistic and no one should ever use microservices to implement an application like this one, it shows you how it feels to run this kind of applications and how to implement it using Spring Cloud.

If you only want to play around with a microservices application, follow this tutorial. If you want to code the full app using Java, Eureka, Spring Cloud Config, Spring Data Rest, Hystrix, Zuul, Spring Session, and Vaadin, follow the complete 9 steps tutorial.

You'd end up with several terminals where each terminal is running a specific service:


In real-world projects, you most likely wouldn't start microservices like this. You would probably use an orchestration tool such as Docker Swarm or Kubernetes. There's a Git branch in the repository for this example application that contains Docker files you could experiment with to learn more about how to deploy microservices in production environments.

In the following sections, I describe some guidelines to create a practice environment.

Setting up the Machines

Use VirtualBox to create a virtual machine and install Alpine Linux on it. Use a Bridged Adapter in the network configuration.

Set up static IPs for both machines. Edit the /etc/network/interfaces file to:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.150
        netmask 255.255.255.0
        gateway 192.168.1.1

Set up SSH so you can use your host machine to connect to the virtual machine from now on (something that would happen in a real-world scenario):

apk add openssh

You would need to add PermitRootLogin yes to the /etc/ssh/sshd_config file to make things easier for now (or you can create a new OS user and connect to the VM using its credentials). With this, you can connect to the VM using:

ssh root@192.168.1.150

To install Docker, first add the following repository to the /etc/apk/repositories file:

http://dl-cdn.alpinelinux.org/alpine/latest-stable/community

Then run:

apk update
apk add docker

To run Docker at startup, execute:

rc-update add docker boot

In VirtualBox, shut down the VM and clone it. Generate a new MAC address for the cloned VM in the network configuration. Start and connect to the cloned VM to configure a different IP address in the /etc/network/interfaces file. For example 192.168.1.151. Restart the cloned VM and start the original one. You should have now two VMs ready.

Running the Application with Docker Swarm

In the 192.168.1.150 machine, init a swarm:

docker swarm init --advertise-addr 192.168.1.150

This machine is now the master machine.

Copy the reported docker swarm join command and run it in the other machine (192.168.1.151). The command should look similar to this:

docker swarm join --token SWMTKN-1-2j6qifl5jbb7zmcbr1ti7xl3qthmhj87b853afjmh29i7f6voi-5az2apq6vq80sls2uvd1sjz1o --advertise-addr 192.168.1.151 192.168.1.150:2377

This machine is now a worker machine.

In the master machine (192.168.1.150), create a new docker-compose.yml file with the following contents:

version: '3'

services:
  discovery-server:
    image: alejandrodu/microservices-discovery-server
    ports:
      - "8001:8080"
    command: --spring.cloud.inetutils.preferredNetworks=10.0 --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  config-server:
    image: alejandrodu/microservices-config-server
    ports:
      - "8101:8080"
    command: --spring.cloud.inetutils.preferredNetworks=10.0 --spring.cloud.config.server.git.default-label=docker --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  biz-application:
    image: alejandrodu/microservices-biz-application
    ports:
      - "9001:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    volumes:
      - ~/h2-databases:/root/h2-databases
    deploy:
      resources:
        limits:
          memory: 128M

  admin-application:
    image: alejandrodu/microservices-admin-application
    ports:
      - "9101:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 256M

  news-application:
    image: alejandrodu/microservices-news-application
    ports:
      - "9201:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  website-application:
    image: alejandrodu/microservices-website-application
    ports:
      - "9301:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  proxy-server:
    image: alejandrodu/microservices-proxy-server
    ports:
      - "8080:8080"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

  monitor-application:
    image: alejandrodu/microservices-monitor-application
    ports:
      - "8201:8201"
    command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
    deploy:
      resources:
        limits:
          memory: 128M

The main things to notice in the previous configuration are the usage of a preferred network when running a service, the shared volume in the biz-application, and the Git branch used by the config-server.

Run the stack by executing:

docker stack up -c docker-compose.yml microservices-demo

What's next?

The purpose of this article is not to explain all the concepts and details on Docker and Docker Swarm but rather give you some guidance on how to experiment and learn by yourself.

From here you can experiment with cloud providers several of which ease Docker-based deployments, replicating the Discovery and Config services to avoid having them as single points of failure; and setting up a database cluster for the same reason.

Share:

Thursday, January 24, 2019

How to call a Java method from a JavaScript function in the browser




In this video I demonstrate how to call a Java method that runs in the server from a JavaScript function running in the web browser:



In short, you need a Java web application with the Vaadin dependencies (you can quickly create one here), a script file in the webapp/frontend/ directory, and a Java class with a method annotated with @ClientCallable that sends an Element to the JavaScript function. The JavaScript function can use the $server object in the Element instance to call the annotated Java method.

Here's the code:

MainView.java:

@JavaScript("frontend://script.js")
@Route
public class MainView extends Div {
    public MainView() {
        getElement().executeJavaScript(
                "someJavaScriptFunction($0)", getElement());
    }

    @ClientCallable

    public someJavaMethod(String message) {
        System.out.println(message);
    }
}

script.js:

function someJavaScriptFunction(element) {
    element.$server.someJavaMethod("Hello server!");
}

You can read the full step-by-step tutorial here.
Share:

Friday, January 18, 2019

Infinite lazy loading

Here's a short excerpt of Chapter 9 Lazy Loading of my book Data-Centric Applications with Vaadin 8.

Even though we have explained lazy loading by using the Grid component, we can use the same backend service method to implement custom UI components that support lazy loading. For example, you can use a VerticalLayout to add sets of, say, 10 components any time the user clicks a load more button at the bottom of the layout. In this case, you would need to keep track of the current offset and keep incrementing it until the service method returns less than 10 items.

The following is a simple UI component that shows how to implement this type of infinite lazy loading:

public class LazyLoadingVerticalLayout extends Composite {

    private CssLayout content = new CssLayout();
    private Button button = new Button("Load more...");
    private int offset;
    private int pageSize;

    public LazyLoadingVerticalLayout(int pageSize) {
        this.pageSize = pageSize;
  
        button.setStyleName(ValoTheme.BUTTON_BORDERLESS_COLORED);
  
        VerticalLayout mainLayout = new VerticalLayout(content, button);
        setCompositionRoot(mainLayout);

        button.addClickListener(e -> loadMore());
        loadMore();
    }

    public void loadMore() {
        List<Call> calls = CallRepository.find(
                offset, pageSize, "", new HashMap<>());

        if (calls.size() < pageSize) {
            button.setVisible(false);
        }

        calls.stream()
                .map(call -> new Label(call.toString()))
                .forEach(content::addComponent);

        offset += pageSize;
    }
}

Notice how the loadMore method keeps adding components to the content layout until there are no more results to add, at which point the Load more... button is hidden from the UI.

The following screenshot shows this component in action:


You can learn more about lazy loading and many other topics related to web development with Vaadin in my book Data-Centric Applications with Vaadin 8 available at amazon.compacktpub.com, and many other online bookstores.
Share:

Wednesday, January 2, 2019

Hello, World in Vaadin 10+

Vaadin is a set of tools to create web applications tailored to both, client-side and server-side developers. If you are, say, a JavaScript Developer, you can use Vaadin Components in any HTML document. If you are a Java Developer, you can use the provided Java API and forget about coding any HTML or JavaScript at all.

In this article, I'll show you how to create the famous Hello, World application using the Java Programming Language and Vaadin 12 (also valid for Vaadin 10 and 11). Get comfortable, make sure you have Maven installed, fire up your favorite IDE, and let's get started!

Start with a starter, obviously

Go to https://vaadin.com/start/latest and select Project Base. This is the most straightforward project starter and serves well as an initial point. Click Download and extract the zip file. You should get a directory with a Maven project in it. Import this project into your favorite IDE (mine is IntelliJ IDEA, by the way).

You should get a directory structure that looks similar to the following:


Let's not worry about the resources and webapp subdirectories for now. Also, I want you to get your hands dirty and implement the example app by yourself. However, it turns out the starter includes the MainView class with kind of a Hello, World application in it. So, let's get rid of the code in the MainView class by removing any annotations, extended classes, and code in the constructor. Go ahead and remove code until it looks like the following (or delete the file and create a new one):

package org.vaadin.alejandro; // use yours, of course

public class MainView {

    public MainView() {
    }

}

The project is ready. Let's add some code to it!

Add UI components to the web page

Think of the MainView class as the web page shown when you request the app in the web browser. Let's start by doing the simplest Hello, World app we can do with Vaadin–a web app that shows a greeting on the screen.

First off, we need the MainView class to be of a type that Vaadin recognizes as a UI component it can deal with. You have many options, but we will extend a popular class called VerticalLayout:

package org.vaadin.alejandro;

import com.vaadin.flow.component.orderedlayout.VerticalLayout;

public class MainView extends VerticalLayout {

    public MainView() {
    }

}

Now the MainView class has more powers. Check in your IDE some of the methods available in VerticalLayout. You can use the autocompletion feature of your IDE to quickly explore what's available:



What is a VerticalLayout, though? A VerticalLayout is a UI component that arranges other UI components (like buttons or grids) in a vertical fashion or a column if you wish. You do this by using the VerticalLayout.add(Component...) method. But first, we need to prepare the component we want to add to the VerticalLayout. Let's use a very simple one: Text. Go ahead and create a new instance of this class inside the constructor:

public MainView() {
    Text text = new Text("Hello, World!");
}

Now call the add(Component...) method to actually add the text component to the VerticalLayout:

public MainView() {
    Text text = new Text("Hello, World!");
    add(text);
}

Expose the view as a web page

To serve this class as a web page, you need to tell Vaadin you wish to do so. Doing this is super easy. Just annotate your MainView class with @Route:

@Route
public class MainView extends VerticalLayout {
    ...
}

The @Route annotation accepts an optional parameter to specify the actual route (the last part of the URL) you want to use to show this view. For example, @Route("hello") would make the view available at http://localhost:8080/hello. However, Vaadin uses a convention with the class name. Since our class is named MainView, Vaadin exposes the view at the context root (http://localhost:8080/). Moreover, if you add a class named CustomersView, for example, Vaadin exposes the view at http://localhost:8080/customers (note how the "View" part in the class name is ignored). Any other names are exposed using the class name. Just remember that you can override this by using the String parameter in the @Route annotation.

Deploy and run the web application

Since we used a Vaadin starter to create the project, the pom.xml file includes the Jetty Maven plug-in which allows you to use Maven to deploy and run the web application in a local Jetty server. The quickest way to run the application is by using a command line terminal and run:

mvn jetty:run

However, I recommend creating a run configuration in your IDE. A run configuration is like a shortcut inside the IDE to execute an action, for example, a Maven command. Most IDEs offer the possibility to create this from a Maven view that shows all the plugins and its corresponding goals. In IntelliJ IDEA it looks like the following:



You can simply double-click the jetty:run option to deploy the app and start the Jetty server, or you can right-click the option to create a running configuration that will be shown on the top of the IDE's window. This last method has the advantage of offering a keyboard shortcut for the running configuration as well.
You can alternatively use any other server that includes a Web Servlet to deploy and run the application. For example Tomcat or GlassFish. We won't cover this topic here. There are plenty of useful resources on the web that explains how to use these servers.

Once the app is compiled, point your browser to http://localhost:8080 to see the result. Keep in mind that the compilation may take some time the first time you are doing it since you might not have all the Maven dependencies in your hard drive, but this is going to be much faster afterward, for both this project and new ones as well. Here's a screenshot of the application:

Add behavior to the web application

Vaadin includes many ready-to-use UI components. There are buttons, combo boxes, grids, check boxes, text fields, charts, and many others. Let's use the TextField and Button classes to add some interactivity to the web application.

Start by creating instances of these two classes in the constructor:

TextField textField = new TextField("What's your name?");
Button button = new Button("Ok");

We want to show a personalized greeting containing the name introduced in the text field anytime the user clicks the button. The way you react to user actions (like clicking a button) is by adding listeners. In the case of a Button, a click listener:

button.addClickListener(e -> ... your custom code here ...);

Let's use yet another Vaadin UI component to show a message: Notification:

button.addClickListener(e -> Notification.show("Hello"));

The greeting is not personalized yet. We want to use the name introduced in the text field as part of the greeting. We can get this value by using the TextField.getValue() method. Cannot be easier:

button.addClickListener(e -> Notification.show("Hello " + textField.getValue()));

There, you have new components and behavior in your app. We are just missing one last thing–we created and configured UI components, but we never added them into the VerticalLayout. Use the add method to fix this:

add(textField, button);

Restart the Jetty server and go to http://localhost:8080 to see the changes:

What next?

There are many other cool features in Vaadin. I would suggest you continue with the official Vaadin Tutorial at https://vaadin.com/tutorials/getting-started-with-flow which explains how to build a more real-life application. If you want to master Vaadin, I suggest reading the documentation at https://vaadin.com/docs.
Share:

Tuesday, July 3, 2018

Data-Centric Applications with Vaadin 10?

I recently got some hard copies of my last book about Vaadin. I love the matte colored look of the cover. Excellent job by Packt Publishing! Anyway, since the feeling of receiving a package with your own books is hard to describe with words, I decided to do it with code.

Although most of the concepts and design ideas that the book covers are valid for any version of Vaadin, I created a Git branch with all the examples migrated to Vaadin 10. At this time, there are certain features that Vaadin 10 doesn't include (yet?) such as Grid editors, Menus, and LAYOUT_COMPONENT_GROUP styles. But besides that, pretty much everything was easy to migrate.

There are some new features in Vaadin 10 that, obviously, I didn't cover in the book–things such as the new Router and the Element API. However, since the book is aimed at developers with basic Vaadin knowledge (i.e., they how to code UIs with the Vaadin Java API), the examples are useful and illustrate techniques you can use in your applications: modularization, authentication, authorization, database connectivity (with JDB, JPA, MyBatis, and jOOQ), CRUD user interfaces design, lazy loading, and reporting with JasperReports.

Keep in mind that this book is not for total beginners. If you don't know what kind of components are available in Vaadin and how to use the basic functionality they provide, you should start with the introduction to Vaadin Flow and the official Vaadin tutorial.
Share:

Saturday, May 5, 2018

Responsive embedded YouTube video or playlist online maker

I have to embed YouTube videos or playlists frequently, so I decided to implement this simple tool to generate the HTML code of an embedded responsive YouTube video or playlist:

YouTube video or playlist ID:
Playlist
Code:
Share:

Friday, May 4, 2018

What's so cool about Vaadin Flow?

Vaadin Flow is a free open-source web framework for Java developers. It allows you to implement a web application without having to code any JavaScript or HTML. See the following example:

@Route("")
public class MainView extends VerticalLayout {
    public MainView() {
        TextField textField = new TextField("Enter your name");
        Button button = new Button("Click me", event ->
                add(new Label("Hello from the server, " + textField.getValue())));
        add(textField, button);
    }
}

​If you deploy this to a Java server, you'll get the following:



Since the UI code runs on the server side, you can debug it using the tools that your Java IDE of your choice provides. For example, here we are adding a breakpoint in the line that gets invoked when the button is clicked:



These are some of the cool things about Vaadin Flow:

  • You can use one single programming language to implement a web application (Java or any other for the JVM).
  • ​You can “connect” Java business logic easily–just call the Java method, no need to implement REST web services and parse JSON.
  • You can “forget” about certain security issues. For example, if a button is disabled and a malicious user enabled it with for example Chrome DevTools in the browser and clicked it, the framework wouldn’t call the server-side listener anyway–if a button is disabled, you can rest assured the server logic won’t be invoked.
  • Flat learning curve. Since the programming model is closer to desktop development, developers can start maintaining applications easily.
  • Vaadin Flow includes many ready-to-use components such as ComboBox, DatePicker, Grid, Dialog, Checkbox, ProgressBar, Notification, Tabs, and many others.
  • You can create your own UI components by using object-oriented composition, HTML, and JavaScript.
  • It makes it easy to integrate existing Web Components. So, if you find or develop a useful Web Component, you can wrap it in a server-side Java class.
  • You can manipulate the DOM from the server side. You have full access to the underlying DOM in the browser form the server.

There are more cool features in Vaadin Flow. The following videos show some of them in action:

Share: