Setting Up Your Rancher Infrastructure

Before we can build and deploy our application we will need to first setup the infrastructure. I’ve decided that I’m going to be using Docker as the container service and Rancher as the orchestration layer. This blog post is just a quick overview of how to create a basic demo Docker/Rancher infrastructure. If you are considering using Docker/Rancher for production that I would highly encourage you to do plenty of additional research beyond this posting before setting anything up.

For the demo I’ve decided that I’m going to keep things simple and use a number of VMs running on my host machine to simulate a tiny production environment.  I have setup 4 VMs with 4Gb Ram each and all running RancherOS. RancherOS is not needed to run Rancher, Rancher can run on any host that can run Docker. I’m just using it for my demo to make it easier as the RancherOS already has Docker all setup for you.

The first of my virtual machines will be dedicated to be the Rancher Server. Setting up the rancher server is as simple as running a quick docker command to start the rancher server container.

docker run -d --restart=unless-stopped -p 8080:8080 rancher/server

This will start the download of the rancher server container and start it up. This is the most basic of commands and will setup a simple rancher server with a built in MySQL server. For production you should use an external MySQL server and also setup SSL.

Once the Rancher Server is up and running you should be able to access it in your web browser and access the VMs IP address on port 8080. You will notice that you were not asked to log in. By default Rancher comes with security turned off. In a production environment you should turn it on. A indicator on the admin dropdown will remind you that security is disabled.

2017-02-26_12-17-12

Before we can deploy any containers we need to add our first Rancher Host. Typically this is another machine that is running docker, however you can setup your Rancher Server to also be a host if you want but not really recommended for production. I have a second VM that I will run a host on.  After clicking on the Add A Host link you will be brought to a screen to add your first host. I’m using the Custom Host which is basically any machine running Docker but you may also notice that they have hooks in to Azure, Amazon and other cloud providers to make it easy to create VMs on those systems.

2017-02-26_12-25-52

Run the supplied command to start a Rancher Agent on your selected host machine and then go to the Infrastructure/Hosts tab. After a few minutes your new host will appear and start configuring itself.

2017-02-26_12-29-43

Congratulations, you now have your first Rancher Host and you can start deploying docker containers. In the next post I will extend my rancher system to provide separate environments for Testing and Production.

Advertisements
Tagged with: , , ,
Posted in Domino To Spring

AJAX and ThymeLeaf For Modal Dialogs

The final part of the basic phonebook application is being able to click on a person and see details about them. For this part I’ve decided for now not to open a new page but to open the persons details in a modal dialog box on the current screen just so I can demo how to do ajax calls using Spring and Thymeleaf.

First of all I need a PersonController which will populate the modelmap with the selected persons attributes and then return a thymeleaf page.

2017-02-25_15-42-00

This controller is very simple and very like all the other controllers it will respond on the /person/{Id} path and populate the modelmap with details of the selected person. I’m also adding in attributes for the person’s manager and their co-workers. The most important part however is the returned string at the end. In the other controllers I just returned a simple string that would match up to the thymeleaf html page that I wanted to render. This time, however, I have added a fragment name separated from the page name by a double colon. When this controller is called only a spamm portion of the modal/person.html page will be returned to the browser. Here is the corresponding fragment…

2017-02-25_15-57-30

To get the modal dialog to display I have added an onClick event to the table row which will run a function called openPersonModal and pass in that rows person id number.

2017-02-25_15-59-11

The function called the Spring MVC controller and is returned just the fragment of html code from Thymeleaf. I then pop this in to an empty div called personModalHolder which I had also added to the page and then I call the bootstrap function to show the modal.

2017-02-25_16-01-16

At this stage we have a very simple, read only, phonebook using our auto generated test data. For the next few posts I’m going to take a break from writing code and I’m going to show how to create a pipeline in VSTS and Rancher and Docker to auto build and deploy our application. After that we will come back to the app to add some additional features to allow for editing and adding new people.

Tagged with: , ,
Posted in Domino To Spring

Highlighting The Selected Area With Thymeleaf

Now that I have pulled the side navigation menu out in to its own reusable code fragment I can now make a small adjustment to it to highlight the currently selected option in the navigator. In the Domino/XPage world this would be the script that you write to add a css class to a menu item using the selected property.

For the bootstrap based side navigator that I am using in this application you can add a background color to the side navigator by adding a css class of ‘active’ to the list item tag. Currently our side navigator fragment looks as follows.

2017-02-25_13-29-13

The list item tags for both the home link and the location links do not have any class associated with them at this stage.

Using Thymeleaf you can use a conditional expression to set the class. A conditional expression if pretty much like a simple If/Then/Else statement like th:class=”${row.even}? ‘even’ : ‘odd'”, You can also use nest conditional expressions using parenthesis like th:class=”${row.even}? (${row.first}? ‘first’ : ‘even’) : ‘odd'”. You can also leave out the else part if you want which is what I have done in my code.

2017-02-25_13-47-15

To get this working correctly I had to add a new attribute to the model in both my home controller and my location controller called selectedLocation. It is manually set to ‘Home’ in the home controller and it is programmatically set to the location name in the location controller.

2017-02-25_13-56-54

Now my phonebook correctly shows the currently selected area as highlighted in the side navigator.

Tagged with:
Posted in Domino To Spring

Reuse More Code With ThymeLeaf Layouts

As you saw in the last entry you can use ThymeLeaf Fragments to split out reusable parts of your html pages so that you can just drop them in where needed just like Custom Controls in XPages. Another great XPage concept was using a Custom Control to design the main layout of your page and then drop the content for the page that you are displaying in to a facet on that custom control. With an add-on to ThymeLeaf, which is automatically supplied when using ThymeLeaf with SpringBoot, this is also easily achievable.

I’ve created a new folder in my resources section called ‘layouts’ and I’ve pulled over a copy of my homepage that I will convert in to a layout.  I forst need to add the xml namespace in to the HTML tag and then I can add a div with a tag of layout:fragment to the sections that will be replaced with the content that I’m supplying.

You will also see that I’m still including some ThymeLeaf fragments as defined in the last blog entry, and I have changed how the head tag is setup by adding in a th:block ( because div is invalid in the head tag )  and for the title tag I now have a new layout:title-pattern tag that allows me to programmatically define the title using a combination of the layouts title and then contents title.

Over on my home page I can now add the same namespace and also specify which layout I will be using by adding in a layout:decorate tag.

The system will now merge the <head> elements from both the layout and the content pages  and then replace the layout fragments in the layout page with the layout fragments in the content page while ignoring anything else in the content page that is not part of the fragments.

Over on my location page you can see where I am adding a ThymeLeaf fragment in the header for the DataTables CSS and where I have specified the custom-footer fragment so that I can also add in the DataTables scripts.

As you can see a combination of ThymeLeaf Fragments and ThymeLeaf Layouts is very powerful and this is just scratching the surface of what ThymeLeaf can do.

Tagged with:
Posted in Domino To Spring

Introducing ThymeLeaf Fragments

When I created my people by location page I just copied the entire home page of the application. I now want to make a few changes to the side navigator but if I leave things as they are now I would have to make those changes in all pages that share the side navigator. In the XPages world we had custom controls which could be used to break your page in to separate components and ThymeLeaf has a similar concept called Fragments.

Under my templates folder I’m going to create a new folder called fragments and in there I’m going to add a new html page called layout.html. I’m then going to move the html that makes up the side navigator to this html file and add in an extra ThymeLeaf tag.

This tag identifies the div and everything between it and the closing div as the fragment called ‘sidenav’.

Now back on both the home and location pages I can replace that entire block of code with one simple line.

This tag tells the ThymeLeaf processor to replace this entire div ( and anything in the div ) with the fragment called ‘sidenav’ from the file called layout in the fragments folder.

If you restart the application now you won’t see any changes on the page but the side navigation bar is no longer duplicated across multiple pages so if you need to change it then you just have to update one file.

You can add as many fragments as you want to a single fragment file or you could split them up in to different files. You could even use fragments to set all your head tags or load your scripts. I’ve setup a fragment for my global scripts and I have added an additional ThymeLeaf tag of th:remove=”tag”.

What this does is it will remove the

tags and only render the contents which, in this case, are the two script tags.

If you are using a fragment to setup all your css then you may run in to the issue of how to set a page title. To do this you can add parameters to a fragment. Here I’ve added a pageTitle parameter and I’m using it in the title tag.

When I call this fragment I can then pass in a value to the parameter.

or you could even calculate a title using a ThymeLeaf Expression

So now you can break your application up in to smaller chunks and make reusable code sections for the frontend.

Tagged with:
Posted in Domino To Spring

Adding More Fake Data

In the last entry we added our new People By Location page and when we looked at in the the browser is was fairly empty apart from the one test user.

Not very easy to do any proper testing with just one entry. You COULD if you wanted add a bunch more test users manually but what if you wanted to test with a few thousand users, that would be a lot of copy/pasting.

Thankfully there is an easier way using a Data Faker.

First I need to add a new dependency to my pom file for the JavaFaker project on GitHub

Now in my DemoData class I just need to instantiate the Faker object and then I can call the different accessors to pull out different pieces of random data.

As I have three locations setup in my demo data I have also decided to randomly select one of the locations to put my fake data in to. I then encapsulate it in a loop and I can easily generate as much demo data as I need to properly test the application.

 

 

 

Tagged with:
Posted in Domino To Spring

Add The People By Location Page

Now that the controller is created and has been committed to our source control it is time to create the page that is associated with it. I’ve started by copying the home.html page to it’s own file called location.html (to match the string returned by the controller in the last entry). I’ll break this in to components in a later part but for now a quick copy is all I need to get the exact same layout as the home page.

For the list of peoples details I’ve decided to use DataTables. This is a jQuery plugin for displaying table data in interactive tables that adds filtering and pagination as required. Just like Bootstrap I could add the DataTables to the static folders in my resources but instead I’m going to make use of WebJars again and import it via a Maven dependency. I’m also excluding jQuery as I’m already importing newer version of it.

I then add the CSS and JS to my page using the same method as I did for BootStrap

We then need to add our table to the page. This is just a standard html table. It has been styled using the BootStrap table styling with the bootstrap table striping and bootstrap table border classes.

The interesting part of the table is the <tr> tag. You can see that here I am using another th:each tag to do a thymeleaf based loop of add the data that was passed in to the model under the people attribute.

Finally I need to tell DataTables to activate against my new table. This is done with a little extra javascript. I’ve elected to out the javascript in to its own file in the static/js folder called phonebook.js and then add it on to the page via a script tag.

Now when I run my application and view my page I see the following results

It is starting to look good but kinda sparse. In the next section I’ll add some more fake data using a generator.

Tagged with: ,
Posted in Domino To Spring
Archives