Today, another small presentation, the third of a series about Cloud Computing and associated tools. This one about Infrastructure as a Service.
Sin categoría
Defining Software Architecture
The Software Architecture definition is something that, for a long time, the industry as a whole has not been able to agree or to find a consensual definition. In some cases, it is defined as the blueprint of a system and, in other, it is the roadmap for developing a system, including all the options in the middle.
The truth is that it is both things and, probably, much more than that. To try to figure out what it is, I think we are still far from a formal definition, we can focus on what it is analysed when we take a look at concrete architectures.
- Structure
- Architecture characteristics
- Architecture decisions
- Design principles
Structure
When we talk about the structure we are referring to the type or types of architecture styles selected to implement a system such as microservices, layered, or a microkernel. These styles do not describe and architecture but its structure.
Architecture characteristics
The architecture characteristics define the quality attributes of a system, the “-ilities” the system must support. These characteristics are not related to the business functionality of the system but with its proper function. They are sometimes known as non-functional requirements. Some of them are:
Availability | Reliability | Testability |
Scalability | Security | Agility |
Fault Tolerance | Elasticity | Recoverability |
Performance | Deployability | Learnability |
A long list of them, maybe too long, can be found on one of the articles on the Wikipedia: List of system quality attributes.
Architecture decisions
Architecture decisions define the rules of how a system should be built. Architecture decisions form the constraints of a system and inform the development teams of what it is allowed and what it is not when building the system.
An example, it is the decision of who should have access to the databases on the system, deciding that only business and service layers can access them and excluding the presentation layer.
When some of these decisions need to be broken due to constraints at one part of the system, this can be done using a variance.
Design principles
Design principles are guidelines rather than strong rules to follow. Things like synchronous versus asynchronous communications within a microservices architecture. It is some kind of a preferred way to do it but this does not mean developers cannot take different approaches on concrete situations.
Reference: “Fundamentals of Software Architecture by Mark Richards and Neal Ford (O’Reilly). Copyright 2020 Mark Richards, Neal Ford, 978-1-492-04345-4″
Git branch on terminal prompt
There are a lot of GUI tools to interact with git these days but, a lot of us, we are still using the terminal for that. One thing I have found very useful is, once you are in a folder with a git repository, to be able to see the branch in use on the terminal prompt. We can achieve this with a few steps.
Step 1
Let’s check the actual definition of our prompt. Mine looks something like:
echo $PS1 \[\e]0;\u@\h: \w\a\]\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$
Step 2
Open with our favourite the file ‘~/.bashrc. In my case, ‘Vim’.
Step 3
Let’s create a small function to figure out the branch we are once we are on a folder with a git repository.
git_branch() { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/' }
Step 4
Let’s redefine the variable ‘PS1’ to include the function we have just defined. In addition, let’s add some colour to the branch name to be able to see it easily. Taking my initial values and adding the function call the result should be something like:
export PS1="\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] \[\033[00;32m\]\$(git_branch)\[\033[00m\]\$ "
And, it should look like:

Spring Application Events
Today, we are going to implement a simple example using spring application events.
Spring application events allow us to throw and listen to specific application events that we can process as we wish. Events are meant for exchanging information between loosely coupled components. As there is no direct coupling between publishers and subscribers, it enables us to modify subscribers without affecting the publishers and vice-versa.
To build our PoC and to execute it, we are going to need just a few classes. We will start with a basic Spring Boot project with the ‘web’ starter. And, once we have that in place (you can use the Spring Initializr) we can start adding our classes.
Let’s start with a very basic ‘User’ model
public class User { private String firstname; private String lastname; public String getFirstname() { return firstname; } public User setFirstname(String firstname) { this.firstname = firstname; return this; } public String getLastname() { return lastname; } public User setLastname(String lastname) { this.lastname = lastname; return this; } @Override public String toString() { return "User{" + "firstname='" + firstname + '\'' + ", lastname='" + lastname + '\'' + '}'; } }
Nothing out of the ordinary here. Just a couple of properties and some getter and setter methods.
Now, let’s build a basic service that is going to simulate a ‘register’ operation:
... import org.springframework.context.ApplicationEventPublisher; ... @Service public class UserService { private static final Logger logger = LoggerFactory.getLogger(UserService.class); private final ApplicationEventPublisher publisher; public UserService(ApplicationEventPublisher publisher) { this.publisher = publisher; } public void register(final User user) { logger.info("Registering {}", user); publisher.publishEvent(new UserRegistered(user)); } }
Here we have the first references to the event classes the Spring Framework offers us. The ‘ApplicationEventPublished’ that it will allow us to publish the desired event to be consumer by listeners.
The second reference we are going to have to the events framework is when we create and event class we are going to send. In this case, the class ‘UserRegistered’ we can see on the publishing line above.
... import org.springframework.context.ApplicationEvent; public class UserRegistered extends ApplicationEvent { public UserRegistered(User user) { super(user); } }
As we can see, extending the class ‘ApplicationEvent’ we have very easily something we can publish and listen to it.
Now. let’s implements some listeners. The first of them is going to be one implementing the class ‘ApplicationListener’ and, the second one, it is going to be annotation based. Two simple options offered by Spring to build our listeners.
... import org.springframework.context.ApplicationListener; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; public class UserListeners { // Technical note: By default listener events return 'void'. If an object is returned, it will be published as an event /** * Example of event listener using the implementation of {@link ApplicationListener} */ static class RegisteredListener implements ApplicationListener<UserRegistered> { private static final Logger logger = LoggerFactory.getLogger(RegisteredListener.class); @Override public void onApplicationEvent(UserRegistered event) { logger.info("Registration event received for {}", event); } } /** * Example of annotation based event listener */ @Component static class RegisteredAnnotatedListener { private static final Logger logger = LoggerFactory.getLogger(RegisteredAnnotatedListener.class); @EventListener void on(final UserRegistered event) { logger.info("Annotated registration event received for {}", event); } } }
As we can see, very basic stuff. It is worth it to mention the ‘Technical note’. By default, the listener methods return ‘void’, they are initially design to received an event, do some stuff and finish. But, obviously, they can at the same time publish some messages, we can achieve this easily, returning an object. The returned object will be published as any other event.
Once we have all of this, let’s build a simple controller to run the process:
@RestController @RequestMapping("/api/users") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping @ResponseStatus(HttpStatus.CREATED) public void register(@RequestParam("firstname") final String firstname, @RequestParam("lastname") final String lastname) { Objects.requireNonNull(firstname); Objects.requireNonNull(lastname); userService.register(new User().setFirstname(firstname).setLastname(lastname)); } }
Nothing out of the ordinary, simple stuff.
We can invoke the controller with any tools we want but, a simple way, it is using cURL.
curl -X GET "http://localhost:8080/api/users?firstname=john&lastname=doe"
Once we call the endpoint, we can see the log messages generated by the publisher and the listeners:
Registering User{firstname='john', lastname='doe'} Annotated registration event received for dev.binarycoders.spring.event.UserRegistered Registration event received for dev.binarycoders.spring.event.UserRegistered
As we can see, the ‘register’ action is executed and it publishes the event and, both listeners, the annotated and the implemented, receive and process the message.
As usual you can find the source for this example here, in the ‘spring-events’ module.
For some extra information, you can take a look at one of the videos of the last SpringOne.