<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Michal Talaga</title>
    <description>The latest articles on Forem by Michal Talaga (@michaltalaga).</description>
    <link>https://forem.com/michaltalaga</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F652596%2Fa4803484-cdf0-43c9-b180-2984249251e5.png</url>
      <title>Forem: Michal Talaga</title>
      <link>https://forem.com/michaltalaga</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/michaltalaga"/>
    <language>en</language>
    <item>
      <title>Transition from Software Engineer to Product Owner - lessons learned</title>
      <dc:creator>Michal Talaga</dc:creator>
      <pubDate>Wed, 25 Oct 2023 16:04:01 +0000</pubDate>
      <link>https://forem.com/michaltalaga/transition-from-software-engineer-to-product-owner-lessons-learned-jm9</link>
      <guid>https://forem.com/michaltalaga/transition-from-software-engineer-to-product-owner-lessons-learned-jm9</guid>
      <description>&lt;p&gt;Some time ago, an opportunity came up for me to step into the Product Owner role in a project I was working on as an engineer. As a curious person, I was excited to discover new things and without much consideration, I agreed to take on the role. It turned out to be quite the ride, and I had to rethink my approach on many things. Here are a few points I've gathered to help other engineers like me who are considering this new business-related path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start thinking product-first, not solution-first
&lt;/h3&gt;

&lt;p&gt;This was the hardest yet most important thing I had to realise. Fortunately, I had execellent Product Owners around me who helped me with this. Above heading are the words one of my previous PO (thanks Marc!) told me. As engineers, we tend to focus too much on the implementation, forgetting that we are building it for someone else to use. On the other hand, for a Product Owner, the most important thing is if the desired functionality is delivered. Of course, quality is also important, but it is our responsibility to balance when the right time to release is. We need to start thinking about what is the least effort that can produce the maximum value, not necessarily in terms of money, but in terms of customer satisfaction.&lt;/p&gt;

&lt;p&gt;Itt was hard in the beginning. I often found myself constantly striving for the perfect solution. However, I quickly reminded myself that the product is what's most important, not the solution. Embracing the Minimum Viable Product approach was definitely helpful. Instead of focusing on what I can add, I started asking myself what I can cut out from the proposed solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write down, you won't remember everything
&lt;/h3&gt;

&lt;p&gt;As a developer, you often have the luxury of focusing on one task at a time. You're assigned a task, you work on it, and then you're done. There's no need to switch contexts or worry about other things, unless a bug related to your part of the application arises. However, as a Product Owner, this is no longer the case. You need to look at the bigger picture and handle multiple responsibilities, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aligning with stakeholders to understand their needs&lt;/li&gt;
&lt;li&gt;Collaborating with developers to determine what can be achieved&lt;/li&gt;
&lt;li&gt;Working with designers to define how the product should look&lt;/li&gt;
&lt;li&gt;Providing updates to stakeholders on progress and agreements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these interactions will raise questions and concerns from various individuals involved. &lt;em&gt;When can we expect it?&lt;/em&gt;,  &lt;em&gt;What about this specific corner case?&lt;/em&gt;,  &lt;em&gt;Will this feature be supported on mobile?&lt;/em&gt;. The truth is, your brain simply cannot remember all the details and discussions. That's why being proficient in note-taking is crucial.&lt;/p&gt;

&lt;p&gt;Every little-thing you agreed on needs to be stored somewhere. Either only for you, so you can get back to what you agreed or for everyone to know what was been already discussed. I prefer the latter option, as even if you're not there to answer the question, others will have reference point. If you have something like &lt;em&gt;Notion&lt;/em&gt; or &lt;em&gt;Confluence&lt;/em&gt; it helps to create dedicated page for the product. You can store there all decisions made, all future requests and all the discussions which are being currently in progress.&lt;/p&gt;

&lt;h3&gt;
  
  
  This is not a place if you don't like to talk to people
&lt;/h3&gt;

&lt;p&gt;Despite the fact that I'm big fan of async work, PO work requires at least &lt;em&gt;some&lt;/em&gt; meetings. And most often &lt;em&gt;you&lt;/em&gt; will be the person facilitating them. It is your responsibility to make sure that everyone is on the same page. No matter if it is a product demo or short discussion with engineering team, you need to feel comfortable leading meetings. It is not an easy job, but only practice can help you.&lt;/p&gt;

&lt;p&gt;Definitely, it is easiest to conduct a meeting where you have someone you already know. Leading team meetings is the best way to build up your confidence when speaking to others. For me it was definitely helpful to play Scrum Master role in the past. Organising retros and plannings will teach you how to prepare for a meeting.&lt;/p&gt;

&lt;p&gt;Always have an agenda, and stick to it. There are some people who like to dominate meetings, which can lead to lack of agreement at the end. It is your job to remind what the meeting goal is, and that it is the most important thing to discuss.&lt;/p&gt;

&lt;p&gt;Write down summary after the meeting. In here it can help to develop skills from previous point. For starters it can be only for yourself, to remember what was discussed and agreed. Later, if you will feel comfortable with your notes, you can share it with the members.&lt;/p&gt;

&lt;p&gt;Make sure, that everyone knows what is expected from them at the end of the meeting. Leave no place for own interpretation - assign action points to every person who is expected to do something.&lt;/p&gt;

&lt;p&gt;And thing that really maters - don't be afraid! We all make mistakes, so first meetings probbably will not be the best ones. With each one of them you will gain more confidence, and find your flow. Having your own schema of meetings which you will be leading helps you to prepare for them, and makes it easier for participants to know what to expect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Listen others needs
&lt;/h3&gt;

&lt;p&gt;Why do we need product owner? To listen. They should listen stakeholders opinion. They should listen customer opinion. They should listen engineers opinion. Take all of these opinions and combine into features. It is no longer that you can come to PO and ask for clarification, description, acceptance criteria. Now it's you who have to produce all of this as an result of listening. If you will not be careful enough, it may result with either product not tested enough or not fulfilling all the stakeholders needs.&lt;/p&gt;

&lt;p&gt;It is really important so you will ask right questions when listening. If someone is telling you to create button linking to customers CRM page, in the end it may not be the solution. Maybe it is the fact that some information is not easily available in your system? Maybe stakeholders does not know that it is already available in other place, more suitable for them based on previous feedback? These are all the things you need to get out. People tend to focus on solutions rather than problems. It is your job to find the problem, and help to produce the best solution available.&lt;/p&gt;

&lt;p&gt;When speaking with engineers, it may also be the fact that you will not listen to them. Maybe for you it is enough to link them to slack conversation where some bug was found out. But what about edge cases? What if API will not return exactly one result? Then they will start coming to you with all the things they lack. This is also an indicator what information engineers need to do their job. You were there in the past, you know how frustrating it was when there was not enough data available. Listen, and remove as much roadblocks as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summarize all conclusions and share it with others
&lt;/h3&gt;

&lt;p&gt;As I've written in first point, you need to be good at writing things down. We will not remember anything, no matter how hard we try. To make the best use out of these notes, start sharing them with others after each meeting. This will be good referencing point to which everyone can get back.&lt;/p&gt;

&lt;p&gt;Usually, there are a lot of brainstorming sessions which we set up to discuss about the problem. Lots of ideas and questions are being said, but after the meeting it is common case to forget about it. Because of the fact, a lot of misunderstandings pops up. Engineers may think of one way, whereas stakeholders thought of something completely different. Some people thought of rectangural button, where it should be squared. You need to be translator, making sure that everyone is on the same page.&lt;/p&gt;

&lt;p&gt;That's why it is a good practice to sum-up all the meetings. Write down action points, and assign them directly to the person responsible for them. Create definition of problematic cases, so everyone will understand it. This is an life saver. I remember the first meeting I held as an PO, when I had completely 0 notes. After the meeting people kept coming to me with questions referencing to that, where I had to get back to others to get an answers. Since then, I've tried to make best notes I can, to make everyones work easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Was it worth it?
&lt;/h3&gt;

&lt;p&gt;Definitely! I've learned a ton how product development looks like, not only from the engineering perspective but from business as well. You can expect a lot of misunderstandings. You can expect a lot of explaning. But in the end seeing happy customer praising features you delivered is the best prize. You not only take part in the process of building an solution, you are the part of the discovery process. This shows how important for engineering are techniques like Domain-Driven Design. It helps everyone to understand each other, and keep business really close to the code.&lt;/p&gt;

&lt;p&gt;If you're wondering if this is for you - feel free to reach out to me!&lt;/p&gt;

</description>
      <category>product</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My problem with Java Exceptions and remedy for it - Either</title>
      <dc:creator>Michal Talaga</dc:creator>
      <pubDate>Wed, 19 Apr 2023 07:43:49 +0000</pubDate>
      <link>https://forem.com/michaltalaga/my-problem-with-java-exceptions-and-remedy-for-it-either-40g9</link>
      <guid>https://forem.com/michaltalaga/my-problem-with-java-exceptions-and-remedy-for-it-either-40g9</guid>
      <description>&lt;p&gt;Recently, I've got big discussion on functional-language approach - &lt;code&gt;Either&lt;/code&gt;. For me this is natural step forward, after ditching Java Exceptions. I've always seen Exceptions as something unnatural, indicating something serious going on with JVM internals. When I've discovered &lt;code&gt;Either&lt;/code&gt; my life changed, and below you can find my view on why it is better than exceptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Either?
&lt;/h3&gt;

&lt;p&gt;Concept of &lt;code&gt;Either&lt;/code&gt; is widely used in Scala as first-class citizen. Basically, this is a Tuple where as a rule of thumb we consider left value as an error, and right value as an valid result. In Java we have no &lt;code&gt;Either&lt;/code&gt; by default, but it can be included through very popular &lt;code&gt;vavr&lt;/code&gt; library. Example of such construct realised by &lt;code&gt;vavr&lt;/code&gt; you can see below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Either&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Either&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;left&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not divide by 0"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Either&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;right&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isLeft&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLeft&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result of division is: "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  One-way comuunication between layers
&lt;/h3&gt;

&lt;p&gt;We are used to structure our application code in layers. No matter if it is Clean Architecture or classic MVC, we need to take care that communication is done only within one direction. Going with exceptions, we may miss that constraint.&lt;/p&gt;

&lt;p&gt;Let's take as an example simple method which divides two numbers. If user tries to divide by 0 we need to stop them from doing so. In classic Spring approach we will do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if value passed is 0&lt;/li&gt;
&lt;li&gt;Throw an &lt;code&gt;ArithmeticException&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Catch the exception either in &lt;code&gt;@Controller&lt;/code&gt; or &lt;code&gt;@ControllerAdvice&lt;/code&gt; through &lt;code&gt;@ExceptionHandler&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prepare response which is needed to be returned for the customer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If only someone will catch the same exception in other place, it can result by unexpected message recieved by consumer. We don't know which handler will take care of that. Also, such &lt;code&gt;@ExceptionHandler&lt;/code&gt; may be deleted by accident, and noone may even notice that something is wrong as compiler will not notify us. Main issue is, that exception handling is different flow than calling the method. In this case higher layer need to introduce separate part of code, which will be handling messages thrown from lower layer. This breaks one-direction rule.&lt;/p&gt;

&lt;p&gt;In oposition to that, we can try with &lt;code&gt;Either&lt;/code&gt; approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if value passed is 0&lt;/li&gt;
&lt;li&gt;Return left with defined response class containing error message&lt;/li&gt;
&lt;li&gt;Return directly from called method appropriate invalid state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The contract is clear from the beginning. We know upfront what type of parameters we need to pass, and what can we get in return. If ever will be any breaking changes in contract, we will see them explicitly in all classes which are using above method. We don't have to create separate place, to cover fail scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple points for handling one method
&lt;/h3&gt;

&lt;p&gt;When calling method, we expect it to return result. It is easier for us knowing, that such result could be either success or failure. Using &lt;code&gt;Either&lt;/code&gt; approach, we're able to determine which part of it was successful, and which was not. Someone new coming to the project, and looking at the method header is able to get to know what they can expect. By looking at below example, we know what type of success and error can we expect after calling function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Either&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;DivisionError&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;DivisionResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not so clear with exceptions. If we're facing checked exception being thrown, we still can know what to expect. It may be less elegant to handle (as we need to use &lt;code&gt;try {...} catch (...)&lt;/code&gt; block) but at least we know that such exception can be thrown and we need to handle it. With unchecked exceptions it is even worse. Using method we need to know that something can happen, and prepare for it. If we're exposing an endpoint, we need to remember to write appropriate &lt;code&gt;@ExceptionHandler&lt;/code&gt; which will cover such exception, and return human-readable result for the consumer. If we won't do that, it may lead to some strange messages being returned. Customer can come back angry, that we're returning them some crap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing method
&lt;/h3&gt;

&lt;p&gt;Again - unchecked exception is the hardest to handle here. Do you know about black-box testing technique? It is intended to check something only basing on the externals we can see. When method is throwing unchecked exception, we will not even know that something can go wrong. Explicit contract indicates that there might be negative and positive scenario (left and right part of &lt;code&gt;Either&lt;/code&gt;) which makes tests easier.&lt;/p&gt;

&lt;p&gt;Also, we can even test it farily easy without access to test helping frameworks. I know - JUnit is a standard nowadays. So by few simple assertions we can check if result was successful or not. In case of exceptions - we need to prepare test setup in a way that error is being caught. If we want to do it really precise, we need to know all types of exceptions which can be thrown.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code cleanness
&lt;/h3&gt;

&lt;p&gt;This is purely subjective topic, so this may not apply to everyone. &lt;/p&gt;

&lt;p&gt;When creating code, I like to read it from top to bottom. Like a book, you can expect what comes next. Having &lt;code&gt;try {...} catch (...)&lt;/code&gt; block some part of the story is moved to other place withing the page. Having unchecked exception being thrown, story is moved to some random place, where it is handled. &lt;/p&gt;

&lt;p&gt;In case of either, you have everything in one place. You can check straight away if the result is successful or not, process it in a pipeline like in Streams or fold the result to prepare return value.&lt;/p&gt;

&lt;h3&gt;
  
  
  So, should I drop every Exception in code and replace it with Either?
&lt;/h3&gt;

&lt;p&gt;No, definitely not! It is always bad idea to make big-bang change and do it everywhere. My recommendation is to try it out on small subset of new changes, and start introducing it bit by bit if you like it. Like I've mentioned, in Scala this construct is first-class citizen, so I hope one day we will not have to have separate library for it.&lt;/p&gt;

&lt;p&gt;If you want some code example with comparison of (unchecked) Exception and Either approach, you can find it &lt;a href="https://github.com/mtalaga/EitherException"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>vavr</category>
      <category>programming</category>
    </item>
    <item>
      <title>Connecting Micronaut to MongoDB database using Kotlin</title>
      <dc:creator>Michal Talaga</dc:creator>
      <pubDate>Tue, 21 Feb 2023 16:40:59 +0000</pubDate>
      <link>https://forem.com/michaltalaga/connecting-micronaut-to-mongodb-database-using-kotlin-5a95</link>
      <guid>https://forem.com/michaltalaga/connecting-micronaut-to-mongodb-database-using-kotlin-5a95</guid>
      <description>&lt;p&gt;MongoDB is really flexible in terms of what can it store. We don't have to tie to specific schema like it is with relational DBs. As our model changes in time, it is not a big deal for Mongo to adjust to it. It makes it easier to design application from the domain perspective, rather than from data perspective. Having this in mind, we would like to store different structures within our table through the code. Official Micronaut Guide is a good place to start, but it took me a while to learn how to store in Mongo objects containing other objects. Here is the solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Foundation
&lt;/h2&gt;

&lt;p&gt;In this case I will extend a bit application I've presented in my previous post on &lt;a href="https://dev.to/michaltalaga/integration-tests-with-micronaut-and-kotlin-5cal"&gt;integration testing&lt;/a&gt;. I would like to create dictionary structure, which will hold word in one language together with its translations. To achieve that I've prepared following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data class Word(val word: String, val translations: List&amp;lt;Translation&amp;gt;)  
data class Translation(val language: String, val translation: String)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we would like to store it within relational database, by default it would require two tables - one for &lt;code&gt;Word&lt;/code&gt; rows, and one for &lt;code&gt;Translation&lt;/code&gt; rows with reference to particular &lt;code&gt;Word&lt;/code&gt;. Mongo by default allow us to both of these objects within one table. It will contain a &lt;code&gt;Word&lt;/code&gt; together with list of &lt;code&gt;Translation&lt;/code&gt; in JSON format as a separate field.&lt;/p&gt;

&lt;p&gt;In terms of Mongo, above setup is easily achievable. We can create table with two fields &lt;code&gt;word&lt;/code&gt; and &lt;code&gt;translations&lt;/code&gt; where first one will be string value, and the latter one will be JSON containing list of objects having &lt;code&gt;language&lt;/code&gt; and &lt;code&gt;translation&lt;/code&gt; fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serde
&lt;/h2&gt;

&lt;p&gt;Micronaut comes with dedicated plugin called &lt;code&gt;micronaut-serde-processor&lt;/code&gt; enabling us to &lt;strong&gt;ser&lt;/strong&gt;ialize and &lt;strong&gt;de&lt;/strong&gt;serialize. We can annotate class with &lt;code&gt;@Serdeable&lt;/code&gt; annotation to mark it as the one which will be exchanged in the future. As we are not using &lt;code&gt;micronaut-data&lt;/code&gt; which can make things easier (but I was not able to achieve such nested serialization) we will need to rely on manual poinitng how to serialize to and from &lt;code&gt;BSON&lt;/code&gt; fields used by Mongo. To enable classes being manipulated such way, we also need to add &lt;code&gt;@Introspected&lt;/code&gt; annotation.&lt;/p&gt;

&lt;p&gt;As mentioned previously, we will have to point out how to convert our entities. The easiest way would be to do that through the constructor. For it to work, we need to mark our constructor with &lt;code&gt;@Creator&lt;/code&gt; and &lt;code&gt;@BsonCreator&lt;/code&gt; annotations. Our entity will be converted through the constructor, containing all required fields. For proper conversion, we need as well to show which fields will be taken into consideration. Each one of them needs to be annotated by &lt;code&gt;@field:BsonProperty("name")&lt;/code&gt; and &lt;code&gt;@param:BsonProperty("name")&lt;/code&gt; annotations. This is to mark the property as both class (&lt;code&gt;field&lt;/code&gt;) and constructor(&lt;code&gt;param&lt;/code&gt;) properties. Having such prepared class, we do not have to worry about declaration of setters and getters being by default key for serialization process. Our classes will look like that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MongoWord
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Introspected  
@Serdeable  
data class MongoWord @Creator @BsonCreator constructor(  
    @field:BsonProperty("word") @param:BsonProperty("word") val word: String,  
    @field:BsonProperty("translations") @param:BsonProperty("translations") val translations: List&amp;lt;MongoTranslation&amp;gt;  
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;MongoTranslation
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Introspected  
@Serdeable  
data class MongoTranslation @Creator @BsonCreator constructor(  
    @field:BsonProperty("language") @param:BsonProperty("language") val language: String,  
    @field:BsonProperty("translation") @param:BsonProperty("translation") val translation: String  
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Separation of Domain and Entity
&lt;/h2&gt;

&lt;p&gt;It is good practice to separate classes used within our domain logic from the ones being used to communicate with outer world. I like the ability to quickly convert each way eg. through &lt;em&gt;static factory method&lt;/em&gt;. In Kotlin we can achieve that using &lt;em&gt;companion object&lt;/em&gt;. Such object will look like following for our &lt;em&gt;Word&lt;/em&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;companion object {  
    fun fromWord(word: Word): MongoWord {  
        return MongoWord(word.word, word.translations.map { MongoTranslation.fromTranslation(it) })  
    }  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we want to create domain object straight out of our entity, we can use method being executed on the instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun toWord(): Word {  
    return Word(word, translations.map { it.toTranslation() })  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having this methods within transport classes will allow us to hide implementation details from domain &lt;em&gt;Word&lt;/em&gt; and &lt;em&gt;Translation&lt;/em&gt; object. Thanks to this we can focus on actual business logic, without thinking how our objects should be serialized and deserialized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;Having everything prepared there is nothing else than building an repository. This will be a Singleton, which will accept and return &lt;em&gt;Word&lt;/em&gt; object. As fields used to build it we need &lt;code&gt;MongoClient&lt;/code&gt; together with names of database and collection which we will operate on. Then all we have to do, is to implement methods responsible for storing and getting &lt;em&gt;Words&lt;/em&gt; from repository. Below is code showing how we can achieve that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Singleton  
class WordRepositoryMongo(  
    mongoClient: MongoClient,  
    @Property(name = "word.database") databaseName: String,  
    @Property(name = "word.collection") collectionName: String  
) : WordRepository {  

    private val collection: MongoCollection&amp;lt;MongoWord&amp;gt;  

    init {  
        val db = mongoClient.getDatabase(databaseName)  
        collection = db.getCollection(collectionName, MongoWord::class.java)  
    }  

    override fun findWord(word: String): Word? {  
        return collection.find(eq("word", word)).firstOrNull()?.toWord()  
    }  

    override fun putWord(word: Word) {  
        collection.insertOne(MongoWord.fromWord(word))  
    }  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Testcontainers&lt;/code&gt; are really powerful tool which allows us to test all the code we have just written against actual MongoDB instance. Thanks to micronaut &lt;code&gt;io.micronaut.test-resources&lt;/code&gt; plugin, the only thing we need to do is to provide dependency to &lt;code&gt;Testcontainers&lt;/code&gt; and everything would plug in out-of-the-box. No configuration needed. Before writing test, we need to make sure that with each execution the DB state will be cleared. To do this, we can do following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@BeforeEach  
fun beforeEach() {  
    mongoClient.getDatabase(databaseName)  
        .getCollection(collectionName)  
        .deleteMany(Document())  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It uses injected &lt;code&gt;MongoClient&lt;/code&gt; like we use it in &lt;code&gt;WordRepositoryMongo&lt;/code&gt; class. From collection declared as class field, we will delete all existing documents. When we have it prepared, then we can execute the sample test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test  
fun shouldStoreWordInRepository() {  
    //Given  
    val word = Word(  
        "hello", listOf(  
            Translation("polish", "czesc"),  
            Translation("deutsch", "hallo")  
        )  
    )  

    //When  
    repository.putWord(word)  

    //Then  
    val wordFromRepository = repository.findWord("hello")  
    Assertions.assertTrue(wordFromRepository != null)  
    Assertions.assertTrue(wordFromRepository!!.translations.size == 2)  
    Assertions.assertTrue(wordFromRepository!!.translations  
        .filter { it.language == "polish" &amp;amp;&amp;amp; it.translation == "czesc" }  
        .size == 1)  
    Assertions.assertTrue(wordFromRepository!!.translations  
        .filter { it.language == "deutsch" &amp;amp;&amp;amp; it.translation == "hallo" }  
        .size == 1)  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It tests if word put could be reached out later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It was not an easy job for me to find how to store object structure as parameter for Mongo table. Micronaut is still not so popular as Spring, so the community support is not yet so active. I hope that this article could help you design tables which will realise full potential of domain, without need to think about configuration nitpicks.&lt;/p&gt;

&lt;p&gt;All the code used in this article you can find &lt;a href="https://github.com/mtalaga/micronaut-kotlin-integration-test"&gt;here&lt;/a&gt; within &lt;code&gt;hello&lt;/code&gt; package.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>mongodb</category>
      <category>micronaut</category>
    </item>
    <item>
      <title>Integration Tests with Micronaut and Kotlin</title>
      <dc:creator>Michal Talaga</dc:creator>
      <pubDate>Wed, 02 Nov 2022 15:56:58 +0000</pubDate>
      <link>https://forem.com/michaltalaga/integration-tests-with-micronaut-and-kotlin-5cal</link>
      <guid>https://forem.com/michaltalaga/integration-tests-with-micronaut-and-kotlin-5cal</guid>
      <description>&lt;p&gt;MongoDB is really flexible in terms of what can it store. We don't have to tie to specific schema like it is with relational DBs. As our model changes in time, it is not a big deal for Mongo to adjust to it. It makes it easier to design application from the domain perspective, rather than from data perspective. Having this in mind, we would like to store different structures within our table through the code. Official Micronaut Guide is a good place to start, but it took me a while to learn how to store in Mongo objects containing other objects. Here is the solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Foundation
&lt;/h2&gt;

&lt;p&gt;In this case I will extend a bit application I've presented in my previous post on &lt;a href="https://dev.to/michaltalaga/integration-tests-with-micronaut-and-kotlin-5cal"&gt;integration testing&lt;/a&gt;. I would like to create dictionary structure, which will hold word in one language together with its translations. To achieve that I've prepared following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data class Word(val word: String, val translations: List&amp;lt;Translation&amp;gt;)  
data class Translation(val language: String, val translation: String)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we would like to store it within relational database, by default it would require two tables - one for &lt;code&gt;Word&lt;/code&gt; rows, and one for &lt;code&gt;Translation&lt;/code&gt; rows with reference to particular &lt;code&gt;Word&lt;/code&gt;. Mongo by default allow us to both of these objects within one table. It will contain a &lt;code&gt;Word&lt;/code&gt; together with list of &lt;code&gt;Translation&lt;/code&gt; in JSON format as a separate field.&lt;/p&gt;

&lt;p&gt;In terms of Mongo, above setup is easily achievable. We can create table with two fields &lt;code&gt;word&lt;/code&gt; and &lt;code&gt;translations&lt;/code&gt; where first one will be string value, and the latter one will be JSON containing list of objects having &lt;code&gt;language&lt;/code&gt; and &lt;code&gt;translation&lt;/code&gt; fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serde
&lt;/h2&gt;

&lt;p&gt;Micronaut comes with dedicated plugin called &lt;code&gt;micronaut-serde-processor&lt;/code&gt; enabling us to &lt;strong&gt;ser&lt;/strong&gt;ialize and &lt;strong&gt;de&lt;/strong&gt;serialize. We can annotate class with &lt;code&gt;@Serdeable&lt;/code&gt; annotation to mark it as the one which will be exchanged in the future. As we are not using &lt;code&gt;micronaut-data&lt;/code&gt; which can make things easier (but I was not able to achieve such nested serialization) we will need to rely on manual poinitng how to serialize to and from &lt;code&gt;BSON&lt;/code&gt; fields used by Mongo. To enable classes being manipulated such way, we also need to add &lt;code&gt;@Introspected&lt;/code&gt; annotation.&lt;/p&gt;

&lt;p&gt;As mentioned previously, we will have to point out how to convert our entities. The easiest way would be to do that through the constructor. For it to work, we need to mark our constructor with &lt;code&gt;@Creator&lt;/code&gt; and &lt;code&gt;@BsonCreator&lt;/code&gt; annotations. Our entity will be converted through the constructor, containing all required fields. For proper conversion, we need as well to show which fields will be taken into consideration. Each one of them needs to be annotated by &lt;code&gt;@field:BsonProperty("name")&lt;/code&gt; and &lt;code&gt;@param:BsonProperty("name")&lt;/code&gt; annotations. This is to mark the property as both class (&lt;code&gt;field&lt;/code&gt;) and constructor(&lt;code&gt;param&lt;/code&gt;) properties. Having such prepared class, we do not have to worry about declaration of setters and getters being by default key for serialization process. Our classes will look like that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MongoWord
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Introspected  
@Serdeable  
data class MongoWord @Creator @BsonCreator constructor(  
    @field:BsonProperty("word") @param:BsonProperty("word") val word: String,  
    @field:BsonProperty("translations") @param:BsonProperty("translations") val translations: List&amp;lt;MongoTranslation&amp;gt;  
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;MongoTranslation
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Introspected  
@Serdeable  
data class MongoTranslation @Creator @BsonCreator constructor(  
    @field:BsonProperty("language") @param:BsonProperty("language") val language: String,  
    @field:BsonProperty("translation") @param:BsonProperty("translation") val translation: String  
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Separation of Domain and Entity
&lt;/h2&gt;

&lt;p&gt;It is good practice to separate classes used within our domain logic from the ones being used to communicate with outer world. I like the ability to quickly convert each way eg. through &lt;em&gt;static factory method&lt;/em&gt;. In Kotlin we can achieve that using &lt;em&gt;companion object&lt;/em&gt;. Such object will look like following for our &lt;em&gt;Word&lt;/em&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;companion object {  
    fun fromWord(word: Word): MongoWord {  
        return MongoWord(word.word, word.translations.map { MongoTranslation.fromTranslation(it) })  
    }  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we want to create domain object straight out of our entity, we can use method being executed on the instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun toWord(): Word {  
    return Word(word, translations.map { it.toTranslation() })  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having this methods within transport classes will allow us to hide implementation details from domain &lt;em&gt;Word&lt;/em&gt; and &lt;em&gt;Translation&lt;/em&gt; object. Thanks to this we can focus on actual business logic, without thinking how our objects should be serialized and deserialized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;Having everything prepared there is nothing else than building an repository. This will be a Singleton, which will accept and return &lt;em&gt;Word&lt;/em&gt; object. As fields used to build it we need &lt;code&gt;MongoClient&lt;/code&gt; together with names of database and collection which we will operate on. Then all we have to do, is to implement methods responsible for storing and getting &lt;em&gt;Words&lt;/em&gt; from repository. Below is code showing how we can achieve that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Singleton  
class WordRepositoryMongo(  
    mongoClient: MongoClient,  
    @Property(name = "word.database") databaseName: String,  
    @Property(name = "word.collection") collectionName: String  
) : WordRepository {  

    private val collection: MongoCollection&amp;lt;MongoWord&amp;gt;  

    init {  
        val db = mongoClient.getDatabase(databaseName)  
        collection = db.getCollection(collectionName, MongoWord::class.java)  
    }  

    override fun findWord(word: String): Word? {  
        return collection.find(eq("word", word)).firstOrNull()?.toWord()  
    }  

    override fun putWord(word: Word) {  
        collection.insertOne(MongoWord.fromWord(word))  
    }  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Testcontainers&lt;/code&gt; are really powerful tool which allows us to test all the code we have just written against actual MongoDB instance. Thanks to micronaut &lt;code&gt;io.micronaut.test-resources&lt;/code&gt; plugin, the only thing we need to do is to provide dependency to &lt;code&gt;Testcontainers&lt;/code&gt; and everything would plug in out-of-the-box. No configuration needed. Before writing test, we need to make sure that with each execution the DB state will be cleared. To do this, we can do following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@BeforeEach  
fun beforeEach() {  
    mongoClient.getDatabase(databaseName)  
        .getCollection(collectionName)  
        .deleteMany(Document())  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It uses injected &lt;code&gt;MongoClient&lt;/code&gt; like we use it in &lt;code&gt;WordRepositoryMongo&lt;/code&gt; class. From collection declared as class field, we will delete all existing documents. When we have it prepared, then we can execute the sample test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test  
fun shouldStoreWordInRepository() {  
    //Given  
    val word = Word(  
        "hello", listOf(  
            Translation("polish", "czesc"),  
            Translation("deutsch", "hallo")  
        )  
    )  

    //When  
    repository.putWord(word)  

    //Then  
    val wordFromRepository = repository.findWord("hello")  
    Assertions.assertTrue(wordFromRepository != null)  
    Assertions.assertTrue(wordFromRepository!!.translations.size == 2)  
    Assertions.assertTrue(wordFromRepository!!.translations  
        .filter { it.language == "polish" &amp;amp;&amp;amp; it.translation == "czesc" }  
        .size == 1)  
    Assertions.assertTrue(wordFromRepository!!.translations  
        .filter { it.language == "deutsch" &amp;amp;&amp;amp; it.translation == "hallo" }  
        .size == 1)  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It tests if word put could be reached out later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It was not an easy job for me to find how to store object structure as parameter for Mongo table. Micronaut is still not so popular as Spring, so the community support is not yet so active. I hope that this article could help you design tables which will realise full potential of domain, without need to think about configuration nitpicks.&lt;/p&gt;

&lt;p&gt;All the code used in this article you can find &lt;a href="https://github.com/mtalaga/micronaut-kotlin-integration-test"&gt;here&lt;/a&gt; within &lt;code&gt;hello&lt;/code&gt; package.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>micronaut</category>
      <category>junit</category>
      <category>testing</category>
    </item>
    <item>
      <title>Tracing logs in GCP when exchanging message through PubSub in Java</title>
      <dc:creator>Michal Talaga</dc:creator>
      <pubDate>Tue, 06 Jul 2021 17:27:27 +0000</pubDate>
      <link>https://forem.com/michaltalaga/tracing-logs-in-gcp-when-exchanging-message-through-pubsub-in-java-b87</link>
      <guid>https://forem.com/michaltalaga/tracing-logs-in-gcp-when-exchanging-message-through-pubsub-in-java-b87</guid>
      <description>&lt;p&gt;Debugging application distributed across services may be hard. With multiple applications communicating through different sources, we're not easily able to track all logs for given source. I've faced this issue especially when exchanging messages through GCP PubSub. Solution for that is tracing messages. Whole mechanism could be very flexible, and allow to track multiple metrics connected to some execution flow. In this post I will focus only on tracing messages, which helps to gather all from all services in one place. Before solution, I would like introduce some background.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tracing
&lt;/h2&gt;

&lt;p&gt;Tracing is a process in which we are following some execution flow across whole application. In case where we have only one server, it is easy task. When the message comes (eg. as a HTTP Request) we can track all logs in scope of it by quickly seeking through all entries logged after initial one, or by filtering thread which was handling it. When we have multiple services this scenario could not be achieved. This is why to all log entries there are added special parameters, which helps to determine across all services if particular log entry belongs to group started by our trigger (again, it could be HTTP Request, JMS message or CRON). We can distinguish two main parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trace/Correlation ID - Depending on source the name differs. Microsoft prefers name Correlation ID, W3 calls it Trace ID. In the end it refers to same thing. It is added to each metric across some action. If we will send GET request to retrieve list of all our customers, and this call will trigger more services to fetch data from, each entry in each service in scope of this request will contain same trace id.&lt;/li&gt;
&lt;li&gt;Span ID - All log entries within particular service in scope of our execution flow, besides Trace/Correlation ID will contain also parameter called Span ID. It helps us to find all messages in scope of this Span in one service. Frequently we can see usage of it, to measure how long processing of task took in particular service.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Log4J
&lt;/h2&gt;

&lt;p&gt;Log4J is widely used library for creating and storing logs, with great amount of configuration. It enables us to define how log entry should look like, which information it should contian, where to pass logs so they could be stored and many more. We will use it to create logs, and add to them necessary parameters, which later on will be used in GCP Logging console to group multiple log entries basing on TraceId which they share.&lt;/p&gt;

&lt;h2&gt;
  
  
  MDC
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Mapped Diagnostic Context&lt;/em&gt; is special object in Log4J library which manages log entries coming from different contexts. It holds parameters for current context, which are added to log entry. MDC helds parameter about in scope of which TraceId and SpanId we're currently logging. It is assigned to thread, so if we will switch one, we have to remember to set parameters for new one as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make it real
&lt;/h2&gt;

&lt;p&gt;Before starting, please create PubSub topic and subscription to it in your GCP console. Make sure that account which you will be using when playing around will have following roles assigned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs Writer&lt;/li&gt;
&lt;li&gt;Pub/Sub Publisher&lt;/li&gt;
&lt;li&gt;Pub/Sub Subscriber&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under this &lt;a href="https://github.com/mtalaga/QueueTracing" rel="noopener noreferrer"&gt;link&lt;/a&gt; you can find repo where code is stored - both publisher and reciever application. They are not so complicated - in Readme there is instruction which parameters of your own you have to set to make it work with your account. Server application accepts an HTTP request, and passes it through PubSub to receiver one. Receiver simply receives message and logs it. We would like to see logs both from server and client under the same group in GCP. Of course methods which are outside of Trace scope should not have this group assigned. In the server application the most important part is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

var pubsubMessage = PubsubMessage.newBuilder()
                .setData(data)
                .putAttributes(MDC_FIELD_TRACE_ID, MDC.get(MDC_FIELD_TRACE_ID))
                .build();


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As one of attributes of our message, we're going to put MDC_FIELD_TRACE_ID parameter (which resolves to &lt;code&gt;traceId&lt;/code&gt;). This is constant from StackdriverTraceConstants class. It is used to group logs, and thanks to it GCP Logging will be able to diffrentiate between different ones.&lt;/p&gt;

&lt;p&gt;On the receiver side, after receiving message we need to do this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

MDC.put(MDC_FIELD_TRACE_ID, traceId);
MDC.put(MDC_FIELD_SPAN_ID, UUID.randomUUID().toString());


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;All logs inside thread where the message is handled, will have assigned traceId coming from message. This allows us to group messages through traceId across services which are exchanging messages through PubSub. This is unfortunately not available out-of-the-box. In logging console you can see messages only containing specific traceId which is shown in below screenshot&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nboi49zvhre470ph8lc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nboi49zvhre470ph8lc.png" alt="console_logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, this is not working with Tracing tool in GCP. Currently it supports only requests coming through the HTTP. Maybe some day they will introduce such feature, so we could stick only to Google tools, without requirement for installing other ones (like for example DataDog).&lt;/p&gt;

</description>
      <category>java</category>
      <category>trace</category>
      <category>gcp</category>
      <category>pubsub</category>
    </item>
  </channel>
</rss>
