Speaking at Devoxx Poland!

5 08 2019

Devoxx Poland is the biggest and the greatest Java conference in Poland. Since its beginning I missed only one edition. And this year was special as I joined it as a speaker!

Being selected as a speaker is a truly meaningful fact. Proving that what I have to say is interesting for the event at that scale.

I was thrilled to see 250 people from all over the Europe, listening to the idea I’m sharing. And getting feedback that they not only liked it, but also will try to use it in their daily work!

I hope it was a mind-opening session that everyone expects to see at the event of this brand.

Was it? Go on, check by yourself :)

Advertisements




J/vaCon Warsaw!

13 04 2019

54236883_2051852334862283_4618632440833900544_n

It was just a third meeting of this new meetup group but they’re already at the full speed! J/vaCon #3 was a very nice event! Organizers are full of energy and very commited.

I was there talking about automated tests – explaining what is the unit in unit tests and why it should be more than a method or a class.

Audience was big and very open! Thank you all! :)

20190326_183013

cof

 





Speaking at Warsaw Java User Group

28 03 2019

I was speaking about automated tests: unit and integration testing approach. See description here: https://www.meetup.com/Warszawa-JUG/events/258813049/ 

It was a very good meeting! The room was full and we had interesting discussions during that evening.

Video is here (in Polish)

And materials (slides + source code) here: https://github.com/yacekmm/testingDemo 

DSC_0087.JPG





Automated tests for Spring Boot WebSocket server

20 05 2017

Developing WebSocket server for your Spring Boot app is fairly simple and well described and documented. However when it comes to making sure that it ‘actually works’ is done manually in most cases.

Below I will show how I do the automated integration tests for Websocket server using Spring’s StompClient. I assume that you are familiar with the idea of WebSockets in Spring. If not, here is a very good article: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html

Source Code

Code of this tutorial is for you to see here: https://github.com/yacekmm/looksok/tree/WebSocketDemo/Spring/WebSocket

System under test: configuration

The demo will be presented on the simpliest WS configuration which consists of one entry point endpoint (`/ws`) and in-memory message broker (under `/queue`):

@Configuration
@EnableWebSocketMessageBroker
public class WsConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) { 
        registry.addEndpoint("/ws");
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/queue");
    }
}

The idea behind the integration test

In the test I’m going to:
– use SpringRunner to start up the whole application with the full context
– Autowire Component that in production will be responsible for sending messages to WebSocket clients
– Build and configure Spring’s StompClient and connect a StompSession to my WebSocket server
send a message over WebSocket and verify if my test client received it

Starting the application for tests

With SpringRunner.class used within jUnit test I start the app context and autowire the WSProxy component (the one that sends messages to WS clients):

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

    @Value("${local.server.port}")
    private int port;
    @Autowired
    private WsProxy wsProxy;

WsProxy in this demo is a simple component sending message with a SimpMessagingTemplate:

@Component
public class WsProxy {

    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    public WsProxy(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    public void sendMessage(@RequestParam String clientId,
                            @RequestParam String payload){
        messagingTemplate.convertAndSend("/queue/" + clientId, payload);
    }
}

In this configuration, the url of WS endpoint is:

String wsUrl = "ws://127.0.0.1:" + port + "/ws";

Configuring StompClient and connecting StompSession

Using the StompClient with a minimum configuration:

WebSocketStompClient stompClient = new WebSocketStompClient(new StandardWebSocketClient());
stompClient.setMessageConverter(new StringMessageConverter());

I create StompSession to my WS url:

StompSession stompSession = stompClient.connect(wsUrl, new MyStompSessionHandler()).get();

The connect() method returns a future, but here, in tests, I wait synchronously until this session is ready by calling get() on it to get the session instantly.

Oh, and don’t worry about the MyStompSessionHandler – in this configuration it does nothing, except debug logging on the ‘Connect to WS’ event (just overrides the StompSessionHandlerAdapter)

Now it’s time to subscribe the /queue/my-id Channel within the session:

stompSession.subscribe(
    "/queue/my-id", 
    new MyStompFrameHandler((payload) -> resultKeeper.complete(payload.toString())));

The MyStompFrameHandler class is responsible for handling the incoming message in within the session and completing the CompletableFuture promise that it received as an argument. CompletableFuture is a helper variable needed to test asynchronous code:

CompletableFuture<String> resultKeeper = new CompletableFuture<>();

And the handler uses it as follows:

public class MyStompFrameHandler implements StompFrameHandler {

    private final Consumer<String> frameHandler;

    public MyStompFrameHandler(Consumer<String> frameHandler) {
        this.frameHandler = frameHandler;
    }

    ...

    @Override
    public void handleFrame(StompHeaders headers, Object payload) {
        log.info("received message: {} with headers: {}", payload, headers);
        frameHandler.accept(payload.toString());
    }
}

Sending the message

Message is sent by a WsProxy with SimpMessagingTemplate:

@Component
public class WsProxy {

    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    public WsProxy(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    public void sendMessage(String clientId, String payload){
        messagingTemplate.convertAndSend("/queue/" + clientId, payload);
    }
}

On some machines it’s also good to wait until the connection is fully established so don’t hesitate to add good old:

Thread.currentThread().sleep(1000);

Testing the result asynchronously

The code in test is async so I pass the Future and wait until it completes with the expected result, or to fail test after timeout on waiting for the response, verifying its body:

assertThat(resultKeeper.get(2, SECONDS)).isEqualTo("test-payload");

That’s it

Now you can run the test, it will start your app, send a message, receive it and verify the contents. Which is everything you need to implement the WebSockets.

Source Code

I’m sure that seeing the source code will make you understand the article better. Grab it from my GitHub: https://github.com/yacekmm/looksok/tree/WebSocketDemo/Spring/WebSocket





Proxy configuration for Gradle

6 05 2017

Are you using gradle behind corporate proxy? Here is how to configure proxy data for gradle (urls and credentials)

gradle.properties file

Gradle (and gradlew as well) is automatically reading gradle.properties file that is either in project directory or in USER_HOME/.gradle directory.

Inside of gradle.properties file set properties:

systemProp.http.proxyHost=http_proxy_ip_or_url
systemProp.http.proxyPort=port
systemProp.http.proxyUser=username
systemProp.http.proxyPassword=pwd
systemProp.https.proxyHost=https_proxy_ip_or_url
systemProp.https.proxyPort=port
systemProp.https.proxyUser=username
systemProp.https.proxyPassword=password

The configuration above concerns both http and https traffic.

Inline properties

As an alternative you can specify properties in each gradle command by:

gradle build -Dhttp.proxyHost=http_proxy_ip_or_url ...




Free weekend on CodeSchool!

19 11 2016

Get off from beaten track with new technology you always wanted to learn – CodeSchool.com gives free access to all its courses over this weekend! 

Try it: https://www.codeschool.com/free-weekend

There are several courses that takes 2 to 4 hours to attend so no excuses :)





New Technology Radar – what’s new for me

12 11 2016

Here is the new analysis of trends in Technology, Tools, Platforms and Languages & Frameworks. ThoughtWorks is sharing their experiences from projects they support or build in a periodic Tech Radar publications. The pdf version for Nov 2016 is here and the newest edition is always here. In this post I’m going to share remarks that affects currently my daily job.

 

TECHNIQUES

ADOPT Customer Driven Contracts

A must in a microservice environment, when you need to test your service in isolation from others in a line with theirs API (contract). There are several tools utilizing that, depending on your technology. Not all of them are mature enough, however it is a good investment to use them.

ADOPT Pipeline as a code

Manual CI job configurations finally can be replaced. for sure your CI has some support of keeping the configuration as a code that is tested and versioned together with your source code.

HOLD A single CI instances for all teams

I can imagine 20 projects on one CI, one is building and 19 are in queue. Then comes the 21st project and it changes the CI config that breaks others builds. One CI for whole organization is not a solution.

HOLD Anemic REST

REST API is not just an API to browse database. Feel free to model your business processes in API as well. If you are adding new user to your system, you don’t need to POST on ‘/users’, since you have a table ‘users’ in your DB. Go on and make an API for business process that you are modelling and POST for ‘/registration’

 

TOOLS

ADOPT Consul

A Service Discovery tool supporting DNS and HTTP discovery with customizable health checks. Right now I’m into Eureka so time to compare those two once again

ADOPT Graphana

As a live monitoring tool for visualizing your metrics. Definetely useful and easy to integrate with your framework

 

LANGUAGES & FRAMEWORKS

ADOPT Spring Boot

It’s in adopt since April, however is widely used in industry in production systems for a bit longer. I have an experience with it in production systems and definetely agree with this judgement.

HOLD AngularJS

Do not start a new project with AngularJS v1. If you start a new project ThoughtWorks prefers ‘the ramp-up speed and more maintainable codebases we are seeing with Ember and React’








%d bloggers like this: