Why I loved Flutter despite being a fan of Native App Development

Reading Time: 5 minutes

In this post, I am going to write about Flutter based on my opinions. Please don’t hesitate to comment if you want to discuss, support or contradict any of the mentioned points 🙂

What is Flutter

“Flutter is Google’s portable UI toolkit for crafting beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source.” (from official Flutter website)

In the mobile development perspective, Flutter is a cross-platform mobile application development framework that is developed by Google and supports building apps for IOS and Android operating systems from a single codebase with native-like performance.

Cross-platform frameworks in general

I was always against developing apps with cross-platform tools however they are good options in terms of required resources such as they require less development time, less budget, less effort to maintain/support, etc. But for me, these factors are not much important somehow. Which things I didn’t like and made me avoid learning/developing cross-platform are:

  • Low performance, Poor UI – to be honest, I haven’t even played around with any cross-platform development. The fact which makes me come up with the ideas of cross-platform having low performance and poor UI is originated from the impressions I got from the usage cross-platform developed apps. Most of the time when I start using apps and see the bad performance and UI, unfortunately, I end up knowing that they are cross-platform developed apps.
  • It requires learning a new language – since I’m an android developer, I would rather choose to learn Swift for native IOS development so I will be able to develop for both platforms.

Dart language

Dart is a client-optimized programming language for fast apps on multiple platforms. It is developed by Google and is used to build mobile, desktop, backend and web applications. Dart is an object-oriented, class defined, garbage-collected language using a C-style syntax that transcompiles optionally into JavaScript. (wikipedia)

from dart.dev

Dart code is capable of being compiled into machine code. For mobile application development, Flutter uses this type of compilation which is Ahead-of-time compilation. This is the reason which makes Flutter distinguish from other cross-platform app development frameworks and lets an app developed in Flutter have native-like performance.

Things I liked about Flutter development

  • Faster code writing
  • Rich in UI components – lots of flutter widgets to build eye-catching UI
  • Native-like application performance
  • Instant hot reload – see the changes within seconds
  • No need to extra code to support older Android versions

Limitation

  • Less third-party libraries are available

Conclusion

The reason I wrote this blogpost is that Flutter caught my attention and I decided to give it a try. So I cloned the main page of the simple news application which is in the Play Store. Then I started to love Flutter because while the development process I easily found all the widgets that I needed to make the clone app look similar as much as possible to the original app. In the end, the result impressed me so much and I was convinced to learn more about flutter development.

I would also recommend you to give it a try. Especially, if you need to have MVP for your project then go for it. You will benefit from the advantages of cross-platform development such as faster development, less time to test, less effort to bugfix and maintenance and advantages of flutter such as native-like performance, great UI.

There is also one more thing I want to mention that, apps for Google’s Fuchsia OS are written in Flutter. I am not going to write about Fuchsia OS here, but briefly, it is assumed that Fuchsia OS can be Google’s next mobile OS or maybe replacement to Android OS (depending on the result of the problem between Google and Oracle). But it is hard to say how probable is that to happen. Anyway… The reason I mentioned this issue is to show you that – assuming that happened, then it is gonna be really valuable if you already know and have experience with Flutter. 🙂

Helpful resources which I think are worth to check:

CQRS and Event Sourcing with Axon Framework

Reading Time: 5 minutes

What is CQRS?

CQRS stands for Command Query Responsibility Segregation. It is a pattern where allowed actions in the application are divided into two groups: Commands and Queries. A command changes the state of an object but does not return any data, while a query returns data and does not change any state. This design style comes from the need for different strategies when scaling the reading part and the writing part of our application. By dividing methods into these two categories, you can use a different model to update information than the model you use to read information. By separate models we most commonly mean different object models, probably running in different logical processes, perhaps on separate hardware. A web example would see a user looking at a web page that’s rendered using the query model. If they initiate a change that change is routed to the separate command model for processing, the resulting change is communicated to the query model to render the updated state.

Event Sourcing

Event Sourcing is a specialized pattern for data storage. Instead of storing the current state for an entity, every change of state is stored as a separate event that makes sense to a business user. The current state is calculated by applying all events that changed the state of an entity. In terms of CQRS, the events stored are the results of executing a command against an aggregate on the right side. The event store also transmits events that it saves. The read side can process these events and builds the targeted data sets it needs for queries.

AXON Framework

Axon is “CQRS Framework” for Java. It is an Open-source framework that provides the building blocks that CQRS requires and helps to create scalable and extensible applications while maintaining application consistency in distributed systems. It provides basic building blocks for writing aggregates, commands, queries, events, sagas, command handlers, event handlers, query handlers, repositories, communication buses and so on. Axon Framework comes with a Spring Boot Starter, making using it as easy as adding a dependency. Axon will automatically configure itself based on best practices and other dependencies you have set. Providing explicit configuration is a matter of adding a bean of the component that needs to be configured differently. Furthermore, Axon Framework integrates with Spring Cloud Discovery, Spring Messaging and Spring Cloud AMQP.

AXON components

  • Command – a combination of expressed intent (which describes what you want to be done) as well as the information required to undertake action based on that intent. The Command Model is used to process the incoming command, to validate it and define the outcome. Commands are typically represented by simple and straightforward objects that contain all data necessary for a command handler to execute it
  • Command Bus – receives commands and routes them to the Command Handlers
  • Command Handler – the component responsible for handling commands of a certain type and taking action based on the information contained inside it. Each command handler responds to a specific type of command and executes logic based on the contents of the command
  • Event bus – dispatches events to all interested event listeners. This can either be done synchronously or asynchronously. Asynchronous event dispatching allows the command execution to return and hand over control to the user, while the events are being dispatched and processed in the background. Not having to wait for event processing to complete makes an application more responsive. Synchronous event processing, on the other hand, is simpler and is a sensible default. By default, synchronous processing will process event listeners in the same transaction that also processed the command
  • Event Handler – are the components that act on incoming events. They typically execute logic based on decisions that have been made by the command model. Usually, this involves updating view models or forwarding updates to other components, such as 3rd party integrations
  • Query Handler – components act on incoming query messages. They typically read data from the view models created by the Event listeners
  • Query Bus receives queries and routes them to the Query Handlers. A query handler is registered at the query bus with both the type of query it handles as well as the type of response it provides. Both the query and the result type are typically simple, read-only DTO objects

Will each application benefit from Axon?

Unfortunately not. Simple CRUD (Create, Read, Update, Delete) applications which are not expected to scale will probably not benefit from CQRS or Axon. Fortunately, there is a wide variety of applications that do benefit from Axon.
Axon platform is being used by a wide range of companies in highly demanding sectors such as healthcare, banking, insurance, logistics and public sector. Axon Framework is free and the source code is available in a Git repository: https://github.com/AxonFramework.

JMeter

Reading Time: 4 minutes

Today, we are gonna take a look at JMeter. You can embed it in your application as a library and make an external integration testing solution. You don’t have to use it for load testing, it could simply send onej request, check the return status code, check the return value and move on. There is an argument that JMeter may be overkill for that, but it provides an easy way to verify the return, allows you to set it up using JMeter desktop app and then you can move into testing latency under load.

First, we need to create a test file that will be put later in our spring boot application. The steps for creating the .jmx file are as follows:

1 – Open the JMeter window by clicking on /home/apache-jmeter-5.1.1/bin/jmeter.bat. The next step you want to do with every JMeter Test Plan is to add a thread group element. Set the “Loop Count” parameter equal to 1, as shown below:

2 – The next step is to create a while controller. The purpose the while controller is to repeat a given set of actions until the condition is broken. While is a basic programming concept to run actions where the number of iterations to run are unknown or varying.

3 – Create an HTTP request as shown in the figure below:

4 – Afterwards, we are gonna create a CSV Data Set Config. This step refers to the CSV file for which the partner users will be collected and replaced as in the httprequest.

5- After running our test, we want to see the results e.g. which calls have been done, and which ones have failed. This is done through Listeners, a recording mechanism that shows results, including logging and debugging.

The View Results Tree is the most common Listener.

Right-click – Add->Listener->View Results Tree

6 – At the end, it should be something like the figure below:

Now click ‘Save’. Your test will be saved as a .jmx file. To run the test, click the green arrow on top. After the test completes running, you can view the results on the Listener as in the figure below. In this example, you can see the tests were successful because they’re green. On the right, you can see more detailed results, like load time, connect time, errors, the request data, the response data, etc. You can also save the results if you want to.

JMeter can also be used for Maven testing through a plugin and work quite nicely with variables and prerequisites etc. Integrating Performance Testing in your projects has many benefits:

  • It provides a constant check of the performances of the application
  • Secures continuous delivery in production
  • Allows early detection of performance problems or performance regressions
  • Automates the process means less manual work, allowing your team to focus on more valuable tasks like performance analysis and optimisation

First of all, you need to add your plugin to the project. So go to Maven project directory (jmeter-testproject in this case) and edit the pom.xml file. Here you must add the plugin. You can find the basic configuration here. You just need to copy the configuration text and paste it in your pom.xml file.

Finally, you have a pom.xml file that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
   <groupId>com.lazerycode.jmeter</groupId>
   <artifactId>jmeter-maven-plugin</artifactId>
   <version>2.9.0</version>
   <executions>
      <execution>
         <id>jmeter-tests</id>
         <phase>test</phase>
         <goals>
            <goal>jmeter</goal>
         </goals>
      </execution>
      <execution>
         <id>jmeter-check-results</id>
         <phase>test</phase>
         <goals>
            <goal>results</goal>
         </goals>
      </execution>
   </executions>
   <configuration>
      <testFilesDirectory>src/test/resources/jmeter</testFilesDirectory>
      <ignoreResultFailures>false</ignoreResultFailures>
   </configuration>
</plugin>

In the code above we will be running 2 goals:

  • jmeter in phase Test: This goal will run the load test and generate the HTML report
  • results in phase Test: This goal runs some verification on error rate and fails the build

New to programming? 5 things you should pay more attention to

Reading Time: 5 minutes

You decided to start learning programming. You have started to learn programming concepts, you have decided which language you want to learn, and everything looks great.

Except it isn’t.

It’s frustrating; it’s boring; it’s painful. I am not here to make your life easy, but I hope that I will make it a little easier. Here are the 5 things that I believe will help you to become a better programmer.

Find the right source to learn from

I had a professor who said:

“It’s better to spend more time researching where to learn from, than actually learning from one source.”

And this is gold.

Let’s say that you have found a great book or a great video course that everyone is loving. You think that you will love it too, every word that you read/hear in the book/course you will understand, and after you finish it, you will become a master of the things you will learn (at least, I thought like that).

And maybe you will, but probably you won’t. Most (or let’s say, some) of the things you won’t understand, and it’s natural. You will try to read/watch again and again, but it’s not getting any clearer.

My advice is, try to find a great book/course, and start learning from, but use it more as a reference than learning source.

I am not suggesting to only go through the content. Try to understand the concept, but also research it (on Google). Look for more resources, more explanation, more examples. When you will understand the concept, save the source that helped you the most (bookmark the page), and search for examples that you can solve.

This way, it is easier to learn, because you are combining the explanations of different sources, and you are sticking with the most simple explanation that is working for you. Also, research is more interesting than reading\listening the same thing all over again.

Understand the base (minimum) necessary logic rather than implementation

This is important for a few reasons:

  • First, if you understand the logic, it will be easier to learn the implementation
  • Second, the implementation may change, but the base necessary logic won’t

At the very beginning, it will be difficult to differentiate between logic and implementation, and maybe you should try to learn and remember everything, but later try to understand and study just the minimum necessary required things.

I still google some basic things. But because I know what I have to do, I exactly know what to search for (only the implementation/syntax).

With this approach, you will spend your time wisely, and you will be able to learn more important things.

To learn your first programming language is very hard, but that’s because you have to learn programming concepts (the logic). After you learn that, you can learn any language (the implementation) you want, in a matter of weeks.

Code, code, code…

Learning programming is like learning how to drive, except it’s safer (at least, physically). You can read, you can learn, but when you sit down and start to drive, you’ll realize that you haven’t learned anything.

That’s why you should focus on coding. When you study something, try to learn the minimum, so you can start to code, and then code as you learn. There is a great answer on Quora, that mentions 3 rules that you should follow when coding.

  • Write at least one line of code per day
  • First, write code, then refactor
  • No distractions when coding

Here, you can check the answer, that has reasoning for these rules. Maybe you can forget the second rule, but the other 2 are very important.

Attitude

I had to mention attitude. It is a hard path, especially at the beginning, so the right attitude is required. Hard work, believing in yourself, learning to say YES to everything is needed. More precisely, you say NO only when you are 100% sure that it isn’t possible to do. In any other case, you say YES, and you investigate, you try different approaches, you ask for help if it is necessary, you do everything you can. A time will come when you will need to learn to say NO, but first, you have to learn to say YES.

Rest

Of course, don’t forget to rest. You have to rest from the hard work you have done. Most of the stupid things I have done were when I was too tired. When you are tired, you don’t think rationally. You just want to finish your task, no matter. That’s when the biggest mistakes come. You won’t learn anything, you won’t do anything well, you are just wasting your time and nerves.

Spring Cloud Function meets AWS Lambda

Reading Time: 5 minutes

Why spring cloud functions? 🤔

  • Serverless architecture
  • Ignore transport details and infrastructure, and focus on business logic
  • Keep using Spring Boot features
  • Run same code as REST API, a stream processor, or a task

AWS Lambda is one of the most popular serverless solutions. In this blog, we will create a simple spring function and deploy it as an AWS Lambda function.

First, we will create spring function

Let’s create a new project from https://start.spring.io/

In this example, we will create a simple function that will receive some name and will return the sum of all ASCII values of characters. For that purpose, we will create two DTO classes.

  • InputDTO
public class InputDTO {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • OutputDTO
public class OutputDTO {
    private int sum;

    public OutputDTO(int sum) {
        this.sum = sum;
    }

    public int getSum() {
        return sum;
    }

    public void setSum(int sum) {
        this.sum = sum;
    }
}

Let’s update our pom file. We will add all the dependencies we need for this demo. This is how the pom file should look like:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.north</groupId>
    <artifactId>north-demo-spring-aws</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>north-demo-spring-aws</name>
    <description>Demo project for Spring Boot</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-adapter-aws</artifactId>
            <version>${spring-cloud-function.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-function-web</artifactId>
            <version>${spring-cloud-function.version}</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-events</artifactId>
            <version>${aws-lambda-events.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>${aws-lambda-java-core.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <dependencies>
                    <dependency>
                        <groupId>org.springframework.boot.experimental</groupId>
                        <artifactId>spring-boot-thin-layout</artifactId>
                        <version>1.0.10.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                    <shadedArtifactAttached>true</shadedArtifactAttached>
                    <shadedClassifierName>aws</shadedClassifierName>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud-function.version>2.1.1.RELEASE</spring-cloud-function.version>
        <aws-lambda-events.version>2.2.6</aws-lambda-events.version>
        <aws-lambda-java-core.version>1.2.0</aws-lambda-java-core.version>
    </properties>

</project>

Now let’s write the function. We are implementing the function interface and override the method “apply”. All of the business logic we need, we are writing in that method.

public class UseCaseHandler implements Function<InputDTO, OutputDTO> {

    @Override
    public OutputDTO apply(InputDTO inputDTO) {
        int sum = 0;
        for (int i = 0; i < inputDTO.getName().length(); i++) {
            sum += ((int) inputDTO.getName().charAt(i));
        }
        return new OutputDTO(sum);
    }
}

UseCaseHandler class is created in com.north.northdemospringaws.function. Because of that, application.yml file needs an update.

spring:
  cloud:
    function:
      scan:
        packages: com.north.northdemospringaws.function

Now we will test our function. I will try it with my name Antonie Zafirov.
First, let’s create a simple unit test to check if the function works correctly.

@RunWith(MockitoJUnitRunner.class)
public class UseCaseHandlerTest {

    @InjectMocks
    private UseCaseHandler useCaseHandler;

    @Test
    public void testUseCaseHandler() {
        InputDTO inputDTO = new InputDTO();
        inputDTO.setName("Antonie Zafirov");
        OutputDTO outputDTO = useCaseHandler.apply(inputDTO);
        assertEquals(1487, outputDTO.getSum());
    }
}

We can check with postman if the function is acting like RESTful API

And it works!

Next step is exposing our function and uploading as a Lambda function.

The magic is done with extending SpringBootRequestHandler from AWS adapter. This class is acting as the entry point of the Lambda function and also defining its input and output.

package com.north.northdemospringaws.function;

import com.north.northdemospringaws.dto.InputDTO;
import com.north.northdemospringaws.dto.OutputDTO;
import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler;

public class DemoLambdaFunctionHandler extends SpringBootRequestHandler<InputDTO, OutputDTO> {

}

You should have AWS account for this step, so if you do not have you should create one. After that, go to AWS console and select Lambda from the services list.

From submenu select functions and click on the create function.
Add name on function and select runtime Java 8.
In my case, the function name is “demo”.

Build jar from the application with simple maven command, mvn clean package.

Upload the aws jar, in my case north-demo-spring-aws-0.0.1-SNAPSHOT-aws.jar

In the handler part, we should write the path to the DemoLambdaFunctionHandler. In this example, the path is “com.north.northdemospringaws.function.DemoLambdaFunctionHandler”.

We create environment variable FUNCTION_NAME with the name of our function as value starting with a lowercase letter useCaseHandler. Now let’s save it all and we are done!!! And the last step is to test it.
Create a test event with name testEvent and value:

{
  "name": "Antonie Zafirov"
}

Chose testEvent as event and execute the function with clicking Test button. The result is:

And we are done, and it works!!!

Download the source code

Project is freely available on our Gitlab repository. Feel free to fix any mistakes and to comment here if you have any questions or feedback.

https://gitlab.com/47northlabs/public/spring-functions-aws

WeAreDevelopers 2019 Berlin – The Good and the Bad parts

Reading Time: 7 minutes

You can find my expectations here. And here are my actual impressions:

Arrival

The conference took place on the 6th and 7th of June at the CityCube in Berlin. The CityCube is an exhibition site which is located roughly 10km from Berlin centre. My hotel was in Berlin-Charlottenburg, which is a nice area located just 2 stations from the exhibition site.

I arrived late on the 5th of June. Having not really planned my attendance I wanted to check the usual suspects (eg the web page) for more information. But wait. There is an app for that right? And there was. After downloading the app from the Appstore, I quickly set up an account and was ready to take a look. Overall the app was solid (with some bugs or undesired features; later more on that). I found the activity stream pretty useful. The activity stream is like a chatroom where attendees can exchange thoughts. After reading a little bit, I was able to gather most of the important info and got a little bit hyped by the people in the room. There was also an agenda section in the app which I could browse either by date and time or speakers. Each talk or workshop had a brief description. Each talk could also be added to a favourites section which was nice. In that way, I gathered rather quick my favourites and after going through them again by time and eliminating the less interesting ones I was ready for the first day.

Pro-Tip 1: A calendar or timeline section in the app where one could view one’s favourites would be nice. In that way, intersecting talks could be easily spotted.

Day 1

I arrived a little bit early at the venue because in the chatroom there were also some concerns about long queues. The weather was really nice, so I was not really worried to wait a little bit. But the fear of waiting for hours was not justified. There was enough stuff to take care of the attendees. I waited maybe 10 minutes. So all good.

Once I arrived at the main stage I also realized that there was more than enough space to accommodate everyone. With my schedule it went from here like this (Some of the talks I attended):

Welcome by WeAreDevelopers

The usual greetings and organizational stuff. It didn’t take so long so it was okayish. But already here I realized that the sound was really bad. Sitting somewhat in the middle you would get an echo. And that was without any other talks being held in parallel.

Pro-Tip 2: Please test the venues sound properties beforehand and adjust accordingly.

Where Machine Intelligence Ends and Human Creativity Begins – Garry Kasparov

As a starter, this talk was really good. Garry Kasparov is really a charismatic person. The main claim of Garry Kasparov is that eventually a huge amount of (non-creative) work will be replaced by AI. And there is nothing that we can do about it. His conclusion was that it doesn’t have to be a bad thing. We will have more time to do more important stuff.

Business vs Agile – Crimes against development teams continuously committed by management – Gerta Sheganaku

This one I chose based on the title. I was hoping for some entertaining session, actually against management (Sorry I’m a dev). The thing which I’ve got from the talk is that agile works best with top devs in an organization. For this group productivity and “happiness” increases. With diminishing skill set of the devs involved the gains of agile decreases and are even counterproductive in case of devs with decreasing skill set (I do not know how the skill set of devs was measured here and the productivity output either; it’s a company offering, so they have probably some empirical data on this). The fun story was that one consulted company consulted by this company fired almost all stuff based to rehire again for agile.

Lunch

Lunch was an epic disaster. Honestly, I thought lunch was included in the ticket price. It was not. There were around 5 food trucks with different types of food. So this was ok. The problem was that the capacity was way too low. You had to wait like 1 hour in full shining sun to get your food. After waiting for about 15 mins. I decided to go somewhere else to get some food. Doing so I discovered that the part of the CityCube the conference was held in was about 15 min away from the nearest restaurants. Ok, that’s another minus. (PS There was a massive rant about this in the app. Even some invited companies jumped in to deliver some food and free water. Shame, shame, shame…)

Pro-Tip 3: You know how many people will attend. Throughput of the trucks should also be known. Calculate with the worst case.

The Quake Postmortem: The End of the Original Id – John Romero

Yes, this John Romero. The talk was about people, growth, success and the price paid. Romero pictured a small company which was overwhelmed by its “astonishing” success. In the beginning, there is a passion but with success there comes the appetite for larger games and one have to scale. In the end, it’s not about fun anymore. Delivering is what counts. This reflects on the team.

Flutter – Google’s latest innovation for mobile, web, and desktop apps

It was nice. But we have SwiftUI now. Thank you.

Pro-Tip 4: When designing the app, please think about people on a mobile data plan. Scale down pictures posted in the chat (I had like 400MB data usage by the end of the day). 

Day 2

Once in my hotel room I quickly set up my schedule for the last day (Here some of it):

Thoughts on the Future of Programmable Money – Andreas M. Antonopoulos

This talk was epic. Andreas drew a coherent picture of what is wrong with the mindset of closed ecosystems. Starting with castle walls and getting to modern times firewalls was a nice analogy to draw. Eventually we “outgrew” castle walls/castles. Will we be able to break out of closed systems? Andreas has no doubt about it.

25 Years of PHP – Rasmus Lerdorf

I’m not a PHP dev but I wanted to hear the inventor of PHP talk about this un-opinionated language. So Mr Lerdorf is a nice, near to the ground guy. He explained very well that PHP was developed out of necessity. The desire to have a “simple layer” over CGI/C to write programs faster and more readable.

2nd day the lunch situation didn’t really change. There were water and free beer though.

Conclusion

I’m pretty undecided if I would visit this conference again. The speakers were really great but the organisation was seriously lacking.

Unit testing with Mockito

Reading Time: 4 minutes

A unit is the smallest testable part of an application. Mockito is a well known mock framework that allows us to create configure mock objects. With Mockito we can mock both interfaces and classes in the class under test. Mockito also helps us to reduce the number of boilerplate code while using mockito annotations.

Adding Mockito to the project

  • using gradle
testCompile "org.mockito:mockito−core:2.7.7"
  • using maven
<dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>2.7.7</version>
      <scope>test</scope>
</dependency>

Mockito annotations

  • @Mock – used for mock creation.
  • @Spy – creates a spy object.
  • @InjectMocks – instantiates the tested object and injects all the annotated field dependencies into it
  • @Captor – used to capture argument values for further assertions

Mockito example @Mock

Let’s say we have the following classes and we want to write a test for the CalculationService:

public class CalculationService {

   private AddService addService;
  
   public int calculate(int x, int y) {
       return addService.add(x, y);
   }
}

public class AddService {

   public int add(int x, int y) {
       return x+y;
   }
}

The usage of the @Mock and @InjectMock annotations is shown in the following sample code:

@InjectMocks
private CalculationService calculationService;

@Mock
private AddService addService;

@Before
public void setUp() {
   // initializes objects annotated with @Mock, @Spy, @Captor, or @InjectMocks
   MockitoAnnotations.initMocks(this);
}

@Test
public void testCalculationService() {
    // mock the result from method add in addService
    doReturn(20).when(addService).add(10, 10);

    // verify that the calculate method from calculationService will return the same value
    assertEquals(20, calculationService.calculate(10, 10));
}

@Spy

Mockito spy is used to spying on a real object. The main difference between a spy and mock is that with spy the tested instance will behave as a normal instance. The following example will explain it:

@Test
public void testSpyInstance() {
    List<String> spyList = spy(new ArrayList());
    spyList.add("firstElement");
    spyList.add("secondElement");
    verify(spyList).add("firstElement");
    verify(spyList).add("secondElement");

    assertEquals(2, spyList.size());
}

Note that method add is called and the size of the spy list is 2.

@Captor

Mockito framework gives us plenty of useful annotations. One of the most recent that I’ve had a chance to use is @Captor. ArgumentCaptor is used to capture the inner data in a method that is either void or returns a different type of object.
Let’s say we have the following method snippet:

public class AnyClass {
    public void doSearch(SearchData searchData) {
        CustomData data = new CustomData("custom data");
        searchData.doSomething(data);
    }
}

We want to capture the argument data so we can verify its inner data. So, to check that, we can use ArgumentCaptor from Mockito:

// Create a mock of the SearchData
SearchData data = mock(SearchData.class);

// Run the doSearch method with the mock
new AnyClass().doSearch(data);

// Capture the argument of the doSomething function
ArgumentCaptor<CustomData> captor = ArgumentCaptor.forClass(CustomData.class);
verify(data, times(1)).doSomething(captor.capture());

// Assert the argument
CustomData actualData = captor.getValue();
assertEquals("custom data", actualData.customData);

New features in Mockito 2.x

Since its inception, Mockito lacked mocking finals. One of the major features in the 2.X version is the support stubbing of the final method and final class. This feature has to be explicitly activated by creating the file MockMaker in this directory src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line:
mock-maker-inline

public final class MyFinalClass {

    public String hello() {
        return "my final class says hello";
    }
}

public class MyCallingClass {

    final MyFinalClass myFinalClass = new MyFinalClass();

    public String executeFinal() {
        return myFinalClass.hello();
    }
}

public class MyCallingClassTest {

    @Test
    public void testFinalClass() {
        MyCallingClass myCallingClass = new MyCallingClass();
        MyFinalClass myFinalClass = mock(MyFinalClass.java);

        when(myFinalClass.hello()).thenReturn("testString");

        assertEquals("testString", myCallingClass.executeFinal());
    }
}

Given the following example, without the file org.mockito.plugins.MockMaker and its content, we get the following error:

When the file is in the resources and the content is valid, we are all good.

The plan for the future is to have a programmatic way of using this feature.

Conclusion

In this article, I gave a brief overview of some of the features in Mockito test framework. Like any other tool, it must be used in a proper way to be useful. Now go and bring your unit tests to the next level.

Testing Spring Boot application with examples

Reading Time: 7 minutes

Why bother writing tests is already a well-discussed topic in software engineering. I won’t go into much details on this topic, but I will mention some of the main benefits.

In my opinion, testing your software is the only way to achieve confidence that your code will work on the production environment. Another huge benefit is that it allows you to refactor your code without fear that you will break some existing features.

Risk of bugs vs the number of tests

In the Java world, one of the most popular frameworks is Spring Boot, and part of the popularity and success of Spring Boot is exactly the topic of this blog – testing. Spring Boot and Spring framework offer out-of-the-box support for testing and new features are being added constantly. When Spring framework appeared on the Java scene in 2005, one of the reasons for its success was exactly this, ease of writing and maintaining tests, as opposed to JavaEE where writing integration requires additional libraries like Arquillian.

In the following, I will go over different types of tests in Spring Boot, when to use them and give a short example.

Testing pyramid

We can roughly group all automated tests into 3 groups:

  • Unit tests
  • Service (integration) tests
  • UI (end to end) tests

As we go from the bottom of the pyramid to the top tests become slower for execution, so if we measure execution times, unit tests will be in orders of few milliseconds, service in hundreds milliseconds and UI will execute in seconds. If we measure the scope of tests, unit as the name suggest test small units of code. Service will test the whole service or slice of that service that involve multiple units and UI has the largest scope and they are testing multiple different services. In the following sections, I will go over some examples and how we can unit test and service test spring boot application. UI testing can be achieved using external tools like Selenium and Protractor, but they are not related to Spring Boot.

Unit testing

In my opinion unit tests make the most sense when you have some kind of validators, algorithms or other code that has lots of different inputs and outputs and executing integration tests would take too much time. Let’s see how we can test validator with Spring Boot.

Validator class for emails

public class Validators {

    private static final String EMAIL_REGEX = "(?:[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";

    public static boolean isEmailValid(String email) {
        return email.matches(EMAIL_REGEX);
    }
}

Unit tests for email validator with Spring Boot

@RunWith(MockitoJUnitRunner.class)
public class ValidatorsTest {
    @Test
    public void testEmailValidator() {
        assertThat(isEmailValid("valid@north-47.com")).isTrue();
        assertThat(isEmailValid("invalidnorth-47.com")).isFalse();
        assertThat(isEmailValid("invalid@47")).isFalse();
    }
}

MockitoJUnitRunner is used for using Mockito in tests and detection of @Mock annotations. In this case, we are testing email validator as a separate unit from the rest of the application. MockitoJUnitRunner is not a Spring Boot annotation, so this way of writing unit tests can be done in other frameworks as well.

Integration testing of the whole application

If we have to choose only one type of test in Spring Boot, then using the integration test to test the whole application makes the most sense. We will not be able to cover all the scenarios, but we will significantly reduce the risk. In order to do integration testing, we need to start the application context. In Spring Boot 2, this is achieved with following annotations @RunWith(SpringRunner.class) and @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT. This will start the application on some random port and we can inject beans into our tests and do REST calls on application endpoints.

In the following is an example code for testing book endpoints. For making rest API calls we are using Spring TestRestTemplate which is more suitable for integration tests compared to RestTemplate.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SpringBootTestingApplicationTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private BookRepository bookRepository;

    private Book defaultBook;

    @Before
    public void setup() {
        defaultBook = new Book(null, "Asimov", "Foundation", 350);
    }

    @Test
    public void testShouldReturnCreatedWhenValidBook() {
        ResponseEntity<Book> bookResponseEntity = this.restTemplate.postForEntity("/books", defaultBook, Book.class);

        assertThat(bookResponseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
        assertThat(bookResponseEntity.getBody().getId()).isNotNull();
        assertThat(bookRepository.findById(1L)).isPresent();
    }

    @Test
    public void testShouldFindBooksWhenExists() throws Exception {
        Book savedBook = bookRepository.save(defaultBook);

        ResponseEntity<Book> bookResponseEntity = this.restTemplate.getForEntity("/books/" + savedBook.getId(), Book.class);

        assertThat(bookResponseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(bookResponseEntity.getBody().getId()).isEqualTo(savedBook.getId());
    }

    @Test
    public void testShouldReturn404WhenBookMissing() throws Exception {
        Long nonExistingId = 999L;
        ResponseEntity<Book> bookResponseEntity = this.restTemplate.getForEntity("/books/" + nonExistingId, Book.class);

        assertThat(bookResponseEntity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
    }
}

Integration testing of web layer (controllers)

Spring Boot offers the ability to test layers in isolation and only starting the necessary beans that are required for testing. From Spring Boot v1.4 on there is a very convenient annotation @WebMvcTest that only the required components in order to do a typical web layer test like controllers, Jackson converters and similar without starting the full application context and avoid startup of unnecessary components for this test like database layer. When we are using this annotation we will be making the REST calls with MockMvc class.

Following is an example of testing the same endpoints like in the above example, but in this case, we are only testing if the web layer is working as expected and we are mocking the database layer using @MockBean annotation which is also available starting from Spring Boot v1.4. Using these annotations we are only using BookController in the application context and mocking database layer.

@RunWith(SpringRunner.class)
@WebMvcTest(BookController.class)
public class BookControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private BookRepository repository;

    @Autowired
    private ObjectMapper objectMapper;

    private static final Book DEFAULT_BOOK = new Book(null, "Asimov", "Foundation", 350);

    @Test
    public void testShouldReturnCreatedWhenValidBook() throws Exception {
        when(repository.save(Mockito.any())).thenReturn(DEFAULT_BOOK);

        this.mockMvc.perform(post("/books")
                .content(objectMapper.writeValueAsString(DEFAULT_BOOK))
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isCreated())
                .andExpect(MockMvcResultMatchers.jsonPath("$.name").value(DEFAULT_BOOK.getName()));
    }

    @Test
    public void testShouldFindBooksWhenExists() throws Exception {
        Long id = 1L;
        when(repository.findById(id)).thenReturn(Optional.of(DEFAULT_BOOK));

        this.mockMvc.perform(get("/books/" + id)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(MockMvcResultMatchers.content().string(Matchers.is(objectMapper.writeValueAsString(DEFAULT_BOOK))));
    }

    @Test
    public void testShouldReturn404WhenBookMissing() throws Exception {
        Long id = 1L;
        when(repository.findById(id)).thenReturn(Optional.empty());

        this.mockMvc.perform(get("/books/" + id)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isNotFound());
    }
}

Integration testing of database layer (repositories)

Similarly to the way that we tested web layer we can test the database layer in isolation, without starting the web layer. This kind of testing in Spring Boot is achieved using the annotation @DataJpaTest. This annotation will do only the auto-configuration related to JPA layer and by default will use an in-memory database because its fastest to startup and for most of the integration tests will do just fine. We also get access TestEntityManager which is EntityManager with supporting features for integration tests of JPA.

Following is an example of testing the database layer of the above application. With these tests we are only checking if the database layer is working as expected we are not making any REST calls and we are verifying results from BookRepository, by using the provided TestEntityManager.

@RunWith(SpringRunner.class)
@DataJpaTest
public class BookRepositoryTest {
    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private BookRepository repository;

    private Book defaultBook;

    @Before
    public void setup() {
        defaultBook = new Book(null, "Asimov", "Foundation", 350);
    }

    @Test
    public void testShouldPersistBooks() {
        Book savedBook = repository.save(defaultBook);

        assertThat(savedBook.getId()).isNotNull();
        assertThat(entityManager.find(Book.class, savedBook.getId())).isNotNull();
    }

    @Test
    public void testShouldFindByIdWhenBookExists() {
        Book savedBook = entityManager.persistAndFlush(defaultBook);

        assertThat(repository.findById(savedBook.getId())).isEqualTo(Optional.of(savedBook));
    }

    @Test
    public void testFindByIdShouldReturnEmptyWhenBookNotFound() {
        long nonExistingID = 47L;
        
        assertThat(repository.findById(nonExistingID)).isEqualTo(Optional.empty());
    }
}

Conclusion

You can find a working example with all of these tests on the following repo: https://gitlab.com/47northlabs/public/spring-boot-testing

In the following table, I’m showing the execution times with the startup of the different types of tests that I’ve used as examples. We can clearly see that unit tests, as mentioned in the beginning, are the fastest ones and that separating integration tests into layered testing leads to faster execution times.

Type of testExecution time with startup
Unit test80 ms
Integration test620 ms
Web layer test190 ms
Database layer test220 ms

Editable Templates in AEM 6.5

Reading Time: 8 minutes

Editable templates have been introduced in AEM 6.2 and since then with each next version they are constantly improving. They allow authors to create and edit templates. Template authors can create and configure templates without help of development team. To be able to create and edit templates the authors must be members of the template-authors group.

Here are some of the benefits of using editable templates:

  • editable templates provide flexibility to define content policies to persist in design properties. There is no need for design mode which requires extra permission to give author to set design properties along with a replication of design page after making any design changes
  • it maintains a dynamic connection between pages and template which gives power to template authors to change template structure along with locked content which will be reflected across all pages based on the editable template
  • this doesn’t require any extra training for authors to create a new page based on an editable template. Authors can similarly create a new page as they create with static templates
  • can be created and edited by your authors
  • after the new page is created, a dynamic connection is maintained between the page and the template. This means that changes to the template structure are reflected on any pages created with that template (changes to the initial content will bot be reflected)
  • uses content policies (edited from the template author) to persist the design properties (does not use Design mode within the page editor)
  • are stored under /conf

Here are the tasks that the template author can do with the help of the AEM’s template editor:

  • create a new template or copy an existing template
  • manage the life cycle of the template
  • add components to the template and position them on a responsive grid
  • pre-configure the components using policies
  • define which components can be edited on pages created with the template

Create editable templates from the configuration browser

Go to Tools -> General -> Configuration Browser

It will create the basic hierarchy of templates in /conf directory.

There are three parts of template editor:

  • templates: all dynamic (editable) templates created by authors
  • policies: there are two types of policies
    template level policy: used for adding policies to the template
    component level policy: used for adding policies to the component level
  • template-types: base templates for the creation of new templates in runtime

There are three parts of a template:

  • initial: the initial content of the page created – based on the template. This content could be edited or removed by the author
  • policies: here a particular template is linked to a policy by using cq:policy property
  • structure:
    – the structure allows you to define the structure of the template
    – the components defined in the template level can’t be removed from the resulting page
    – if you want that template authors can add and remove components, add parsys to the template
    – components can be locked and unlocked to allow you to define initial content

How to create base template-type

To start working on editable templates, we need to create a page component. Navigate to /apps/47northlabs-sample-project/components/page and click on create component.

Next would be to create a template-type which helps the authors to create it’s editable templates. (Please note that the configuration is available on GitLab).

How can authors create editable templates

Next step would be to create the editable template. That can be done from Tools -> General -> Templates -> 47northlabs-sample-project -> Choose empty template.

Add template title, description and open the template. There should be a responsive grid available.

Configure policies

With defining policies, authors will be able to configure different components on the page for regular authors to place on the page. Since there is no defined policy on the template, no component is assigned to this template. Click on the first (Policy) icon will take the author to a new screen where the author can define what components can put on this template.

Create new policy.

Once done, components will be available on the page to drag & drop on the page.

Enable template

Once template authors are done with creating templates, authors must enable templates to make them available in sites section where regular authors can select templates to create pages.

Create editable templates from code

Another possibility is to We can create a sample project based on Adobe Archetype using the following command:

mvn archetype:generate -DarchetypeGroupId=com.adobe.granite.archetypes -DarchetypeArtifactId=aem-project-archetype -DarchetypeVersion=19

The generated sample project already contains content-page editable template by default. We are going to create three additional editable templates i.e.

  • home-page
  • landing-page
  • language-page

We are going to add some components as default in the templates, and few pages in ui.content project. The general idea is to have some test content and to play around with some corner cases. Let’s start.

The demo content is the like on the image below.

We have four editable templates available. With property cq:allowedTemplates we control the available templates that can be used to create child pages under a given page. For example, for the content-page we want to make available only the landing-page, so the initial content will look like:

<jcr:content
    ...
    cq:allowedTemplates="[conf/aem-editable-templates-demo/settings/wcm/templates/landing-page]">
    ...
 </jcr:content>

Similar, the initial content of the landing-page will have similar configuration:

<jcr:content
    ...
    cq:allowedTemplates="[conf/aem-editable-templates-demo/settings/wcm/templates/content-page]">
    ...
</jcr:content>

What happens in case we want to add a fancy new template which should be available only for a particular page types? These two solutions come to my mind:

  • write a groovy script that will update existing cq:allowedTemplates property of all the pages created for a given template with the new template
  • update the structure of the given template, so all the existing pages created with that template will be updated

With the second approach, for example, if we want to add that fancy page template to the content page template, we have to add the following configuration to the structure element of the content-page template:

<jcr:content
    ...
    cq:allowedTemplates="[conf/aem-editable-templates-demo/settings/wcm/templates/fancy-page]">
    ...
</jcr:content>

Given this, it is important to point out the differences between initial content and structure elements of the template definition.

Initial Content

  • is merged with the structure during page creation
  • changes to the initial content will not be reflected in all pages created with the given template
  • the jcr:content node is copied to any new page
  • the root node holds a list of components that defines what will be available in the resulting page

Structure

  • is merged with the initial content during page creation
  • changes to the structure will be reflected in all pages created with the given template
  • the cq:responsive node is responsible for the responsive layout
  • the root node defines the available components in the resulting page

Conclusion

With editable template, you give template authors the flexibility to create and modify the template as they want. It acts as a central place to manage everything about the template (structure, initial content, layout) and components used in the template. If you are migrating to use editable template, make sure you accessed the requirements for not only the template but also the components.

The code from this blog post is available on GitLab.

The way to the professional VueJS-Project ( Part 1 )

Reading Time: 4 minutes

Okay, it’s usually easy to start a VueJS project. There are many tutorials or Vue-Cli templates and with the Vue-Cli 3.x, it’s super easy to create your own. Here are some links:

BUT what if the requirements increase and become more demanding? Or if component/functional testing and typification are required? Or “newer” technologies such as GraphQL, serverless, state machines/diagrams and module dependency management come into play?

How to start?

We’ll start with the easiest way and use the VueCli API.

# via console
vue create professional-world
# or via the vue cli gui
vue ui

We will be prompted to pick a preset. First, select manually features.

After we select these features, we will choose the following setup.

Some points about our setup:

  • class-style
    I choose this mode to show you the TypeScript decorator for class-style Vue components. But of course, you can take the normal style it is not so many new stuff for the first time.
  • history mode
    We do not choose this router mode, because for simpler environment setup. If you don’t like this – feel free to change this. Read more about it here.
  • css pre-processor
    You can choose whatever you want. I prefer stylus regarding the less code. 😏
  • lintner
    It makes sense to activate here TSLint and also the autofix on commit. But we will add husky instead of a git-hook.
  • cypress vs nightwatch
    We choose cypress because it has some nice other testing features e.g. debuggability, automatic waiting, network traffic control, spies, stubs, clocks and screenshots and videos testing. But we will pay for it with the limited browser compatibility at the moment – later we will close this gap with regression tests.
  • config placing
    I prefer to use in dedicated config files. It is easier to change and also the package.json is more readable if you add more dependencies.

Now we will add some more dependencies before we can start:

yarn add -D husky vue-cli-plugin-pug eslint-plugin-pug jest-image-snapshot
  • husky
    It makes git hooks easy
  • pug
    It’s a robust, elegant, feature-rich template engine for Node.js
  • jest-image-snapshot
    It’s a jest matcher for image comparisons. Most commonly used for visual regression testing.

Last configurations

Husky needs to add the following file.huskyrc.js (If you want you can delete the links for the git-hook in the package.json😎

module.exports = {
  "hooks": {
    "pre-commit": "lint-staged"
  }
}

For pug, we add a vue plugin and also an eslint plugin. Eslint itself needs the following configuration in tslint.json.

"plugins": [ "pug" ],

Start coding

After this configurations we can start coding ☺️ Ok we start first with refactoring the example files from the Vue-Cli template to pug syntax. You can use for this a formatter e.g. html-to-pug.com.

Extra tipp

Create a new file named .editorconfig and add following content. It helps you with keep the coding style – you do not need to worry about the format.

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

After this you should have this status from your project:
https://gitlab.com/47northlabs/public/a-professional-vue-world/tree/part-1

Following parts

  • Coding with typescript, stylus and pug ( Part 2 )
  • First steps with unit component, functional and e2e tests ( Part 3 )
  • Vue and VueX meets state machines ( Part 4 )
  • Apollo/GraphQL with serverless services ( Part 5 )
  • Module dependency management in VUE ( Part 6 )