<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Rapid Programmer - Get Tasks Done</title>
    <description>Tech blog by Jarno Tuovinen
</description>
    <link>http://rapidprogrammer.com/</link>
    <atom:link href="http://rapidprogrammer.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 17 Feb 2026 09:51:06 +0000</pubDate>
    <lastBuildDate>Tue, 17 Feb 2026 09:51:06 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Kotlin basics</title>
        <description>&lt;p&gt;I wanted to refresh my Kotlin skills and the best way to do that is to list main things the language has to offer and play around those.&lt;/p&gt;

&lt;p&gt;So this &lt;a href=&quot;https://github.com/spedepekka/KotlinBasics&quot;&gt;KotlinBasics repo&lt;/a&gt; was born.&lt;/p&gt;

&lt;p&gt;There is not much more to add to this than the code and README.md.&lt;/p&gt;
</description>
        <pubDate>Tue, 17 Feb 2026 08:48:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/kotlin-basics</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/kotlin-basics</guid>
        
        
      </item>
    
      <item>
        <title>More about AOP</title>
        <description>&lt;p&gt;Here is the original &lt;a href=&quot;/from-interview-to-learn-aop-and-openapi&quot;&gt;AOP post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And here is couple words about &lt;a href=&quot;/toying-with-correlation-id&quot;&gt;correlation ID&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code is in this &lt;a href=&quot;https://github.com/spedepekka/soon-i-know-aop&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-aop-is-usually-used-for&quot;&gt;What AOP is usually used for&lt;/h2&gt;

&lt;p&gt;Logging is one aspect AOP can tackle nicely.&lt;/p&gt;

&lt;p&gt;Anothed good on is user authentication&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Aspect&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserAuthenticationAspect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;UserAuthenticationAspect:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;@annotation(fi.kranu.servicea.aop.CustomAuthentication)&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;authenticate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RequestContextHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRequestAttributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ServletRequestAttributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)?.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;request&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getHeader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-User-Id&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isNullOrBlank&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Authentication failed: X-User-Id header is missing&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnauthorizedException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dirty-hack&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// This is just a dirty hack for testing purposes. Don&apos;t do this in production.&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Wrong secret&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnauthorizedException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;User $userId authenticated successfully&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-1-transaction-management&quot;&gt;Example 1. Transaction Management&lt;/h3&gt;

&lt;p&gt;One of the most important and widely used applications of AOP.&lt;/p&gt;

&lt;p&gt;It ensures that database operations are automatically wrapped in a transaction boundary.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Atomic business operations&lt;/li&gt;
  &lt;li&gt;Automatic rollback on failure&lt;/li&gt;
  &lt;li&gt;Consistent data integrity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Transactional&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transferFunds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;debit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;credit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-2-performance-monitoring--metrics&quot;&gt;Example 2. Performance Monitoring &amp;amp; Metrics&lt;/h3&gt;

&lt;p&gt;AOP is commonly used to measure execution time and feed observability systems.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;API latency tracking&lt;/li&gt;
  &lt;li&gt;Slow query detection&lt;/li&gt;
  &lt;li&gt;SLA/SLO monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Timed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;payment.processing.time&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Payment&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-3-retry-logic-for-resilience&quot;&gt;Example 3. Retry Logic for Resilience&lt;/h3&gt;

&lt;p&gt;Essential in distributed systems where downstream services can fail temporarily.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Network timeouts&lt;/li&gt;
  &lt;li&gt;Transient database failures&lt;/li&gt;
  &lt;li&gt;External API instability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Retryable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxAttempts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backoff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@Backoff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delay&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PaymentResponse&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;callExternalService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-4-rate-limiting--throttling&quot;&gt;Example 4. Rate Limiting / Throttling&lt;/h3&gt;

&lt;p&gt;Used to prevent abuse and control system load.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Public APIs&lt;/li&gt;
  &lt;li&gt;Multi-tenant SaaS quotas&lt;/li&gt;
  &lt;li&gt;DoS protection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@RateLimited&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user-api&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserProfile&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getProfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-5-multi-tenancy-enforcement&quot;&gt;Example 5. Multi-Tenancy Enforcement&lt;/h3&gt;

&lt;p&gt;Ensures data isolation between tenants automatically.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SaaS applications&lt;/li&gt;
  &lt;li&gt;Tenant-specific data filtering&lt;/li&gt;
  &lt;li&gt;Automatic query scoping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@TenantScoped&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findOrders&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-6-audit-trail-generation&quot;&gt;Example 6. Audit Trail Generation&lt;/h3&gt;

&lt;p&gt;Critical for compliance and traceability.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Financial systems&lt;/li&gt;
  &lt;li&gt;Healthcare applications&lt;/li&gt;
  &lt;li&gt;Regulatory reporting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Auditable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;UPDATE_CUSTOMER&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;updateCustomer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Customer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-7-idempotency-enforcement&quot;&gt;Example 7. Idempotency Enforcement&lt;/h3&gt;

&lt;p&gt;Prevents duplicate processing of the same request.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Payment processing&lt;/li&gt;
  &lt;li&gt;Order creation&lt;/li&gt;
  &lt;li&gt;Event handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Idempotent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;#request.transactionId&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PaymentResult&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;processPayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PaymentRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-8-caching&quot;&gt;Example 8. Caching&lt;/h3&gt;

&lt;p&gt;Used to avoid repeated expensive computations or database calls.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Read-heavy endpoints&lt;/li&gt;
  &lt;li&gt;Reference data lookup&lt;/li&gt;
  &lt;li&gt;External API results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Cacheable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;products&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getProduct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-9-distributed-tracing&quot;&gt;Example 9. Distributed Tracing&lt;/h3&gt;

&lt;p&gt;Automatically creates trace spans for observability platforms.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Microservice request tracking&lt;/li&gt;
  &lt;li&gt;Performance bottleneck analysis&lt;/li&gt;
  &lt;li&gt;Dependency mapping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@NewSpan&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;order-processing&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;processOrder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Order&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-10-method-validation-enforcement&quot;&gt;Example 10. Method Validation Enforcement&lt;/h3&gt;

&lt;p&gt;Ensures input constraints before method execution.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DTO validation&lt;/li&gt;
  &lt;li&gt;Service-level input checks&lt;/li&gt;
  &lt;li&gt;Contract enforcement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Validated&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@NotNull&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@Email&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-11-feature-flags--conditional-execution&quot;&gt;Example 11. Feature Flags / Conditional Execution&lt;/h3&gt;

&lt;p&gt;Allows dynamic behavior toggling without changing business logic.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A/B testing&lt;/li&gt;
  &lt;li&gt;Gradual rollout&lt;/li&gt;
  &lt;li&gt;Experimental features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@FeatureToggle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;new-pricing-engine&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Price&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;calculatePrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Order&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-12-automatic-event-publishing&quot;&gt;Example 12. Automatic Event Publishing&lt;/h3&gt;

&lt;p&gt;Triggers domain events after method execution.&lt;/p&gt;

&lt;p&gt;Typical use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Event-driven architecture&lt;/li&gt;
  &lt;li&gt;CQRS systems&lt;/li&gt;
  &lt;li&gt;Asynchronous workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@PublishEvent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ORDER_CREATED&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Order&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createOrder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;CreateOrderRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;afterwords&quot;&gt;Afterwords&lt;/h2&gt;

&lt;p&gt;When you are learning these, there is no need to test and see how you could do all of these. In my opinion you just need to practice couple of them and then the rest are easy enough to implement when needed. Learn ideas behind the system.&lt;/p&gt;
</description>
        <pubDate>Mon, 16 Feb 2026 07:55:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/more-about-aop</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/more-about-aop</guid>
        
        
      </item>
    
      <item>
        <title>Toying with correlation ID</title>
        <description>&lt;p&gt;This sums it up nicely: Make correlation ID a first-class citizen in your microservice design.&lt;/p&gt;

&lt;p&gt;I stole it from this &lt;a href=&quot;https://medium.com/@anil.goyal0057/understanding-and-implementing-correlation-id-in-microservices-2900518954a0&quot;&gt;Medium post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you missed my &lt;a href=&quot;/from-interview-to-learn-aop-and-openapi&quot;&gt;previous post&lt;/a&gt; how I got here, check it out.&lt;/p&gt;

&lt;h2 id=&quot;what-is-correlation-id&quot;&gt;What is correlation ID&lt;/h2&gt;

&lt;p&gt;It is just a unique string that can be followed across a log file or multiple log files.&lt;/p&gt;

&lt;p&gt;So put that damn thing everywhere and if you cannot find it from the request in the request chain, create it. Of course if you can find it from headers or other meta data, use the existing id.&lt;/p&gt;

&lt;h2 id=&quot;why-should-i-do-it&quot;&gt;Why should I do it?&lt;/h2&gt;

&lt;p&gt;Because these days the stuff is all over the place and it is nearly impossible to track requests across microservices. There are tools like grep and even some fancy stuff with UIs that can cobble these “threads” and give you real information how the system is working.&lt;/p&gt;

&lt;h2 id=&quot;how-i-can-do-it&quot;&gt;How I can do it?&lt;/h2&gt;

&lt;p&gt;Just generate the UUID, if not found. When the service contacts another service, pass that id to that other service. To make it work, it doesn’t matter what is the id/string and how you pass it. To make it work elegantly, generate and pass it in more automated fashion.&lt;/p&gt;

&lt;h2 id=&quot;kotlin-and-spring-boot-example&quot;&gt;Kotlin and Spring Boot example&lt;/h2&gt;

&lt;p&gt;The code is in this &lt;a href=&quot;https://github.com/spedepekka/soon-i-know-aop&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this example the first service A creates the correlation ID with request filter&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CorrelationIdFilter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OncePerRequestFilter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;CorrelationIdFilter:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Throws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;ServletException:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IOException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doFilterInternal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;request:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;response:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;filterChain:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FilterChain&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// NOTE: User can inject correlationId as a header&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getHeader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HEADER_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;randomUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Generated new correlation ID $correlationId&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Using existing correlation ID $correlationId&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;no&quot;&gt;MDC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;correlationId&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setHeader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HEADER_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;filterChain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;doFilter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;no&quot;&gt;MDC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;companion&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HEADER_NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;X-Correlation-Id&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then service A passes the id to service B&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@PostMapping&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handleUserTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@RequestBody&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;transaction:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Transaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Transaction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MDC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;correlationId&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;handleUserTransaction called with correlationId: $correlationId, transaction: $transaction&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpHeaders&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-Correlation-Id&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correlationId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpEntity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;restTemplate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;postForObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://service-b-lol:8080/internal-transaction&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;Transaction:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;e:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Failed to call service-b&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And service B has similar filter than A, so the logs can be followed for a single transaction between services A and B.&lt;/p&gt;

&lt;p&gt;The pattern would be the same for service C. Feel free to do this the way you like, but the idea should be clear now.&lt;/p&gt;

</description>
        <pubDate>Sun, 15 Feb 2026 13:22:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/toying-with-correlation-id</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/toying-with-correlation-id</guid>
        
        
      </item>
    
      <item>
        <title>From interview to learn AOP and OpenAPI</title>
        <description>&lt;h2 id=&quot;preface&quot;&gt;Preface&lt;/h2&gt;

&lt;p&gt;The idea behind this post is to demonstrate how I learn, who I am and how I operate. I have a lot of confidence on my own skills to learn, but it works sometimes in a bit weird way. There is quite a lot of humor in this post, at least I laugh at myself and many times to what I’m learning. The humor makes learning easier and more memorable. Also it is possible to see that I don’t really like to read the docs and I get sometimes a bit frustrated to just trying to undestand plain text. I learn by doing. Eventually the acronyms and ideas behind the tech thing I’m learning about will click.&lt;/p&gt;

&lt;h2 id=&quot;why-i-wanted-to-learn-aop&quot;&gt;Why I wanted to learn AOP&lt;/h2&gt;

&lt;p&gt;I’m a consultant and I was in an interview with a potential fintech client. They asked me about AOP, how have I’ve used it in the past and what do I know about it. I didn’t really know what AOP is and how to use it. Many times I’ve used something without really knowing the real terms or deeper ideas, but it later turned out that I didn’t know anything about AOP and I had not used it anywhere. Not knowing in interviews hits me hard. I know that nobody knows everything, but in this context not knowing might eventually give me a lot of headache in the form of not employing myself. In retrospective, I figured out that AOP is something important in this position, because there were not many technical questions and the questions were broader than just some random technical details. This also puts more weight to know this kind of acronym. You shouldn’t make the same mistake twice.&lt;/p&gt;

&lt;p&gt;I’m very curious person. Usually when I stumble into something that I don’t know or understand, I dig deeper into that and try to learn it. In other contexts than tech, the learning might take years, but tech or software related stuff are eventually quite easy and logical, if you have a good and broad base knowledge. I learn mainly by doing and thinking, so let’s do and think in the form of a blog post.&lt;/p&gt;

&lt;h2 id=&quot;aop-itself&quot;&gt;AOP itself&lt;/h2&gt;

&lt;p&gt;Let’s see what the documentation says&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Aspect-oriented Programming (&lt;a href=&quot;https://docs.spring.io/spring-framework/reference/core/aop.html&quot;&gt;AOP&lt;/a&gt;) complements Object-oriented Programming (OOP) by providing another way of thinking about program structure. The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects enable the modularization of concerns (such as transaction management) that cut across multiple types and objects. (Such concerns are often termed “crosscutting” concerns in AOP literature.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What a bunch of mumbo jambo that tells me nothing I can grasp on. I use Merriam Webster and other dictionaries to understand words and take a look what it says about &lt;a href=&quot;https://www.merriam-webster.com/dictionary/aspect&quot;&gt;aspect&lt;/a&gt;. I know the word ‘aspect’, but in this context from that explanation the documentation gives, I have no idea.&lt;/p&gt;

&lt;p&gt;The page says&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;AOP is used in the Spring Framework to: Provide declarative enterprise services. The most important such service is declarative transaction management.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My brains pick that word &lt;em&gt;enterprise&lt;/em&gt; and of course &lt;em&gt;the most important&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I click the link and open the page for &lt;a href=&quot;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative.html&quot;&gt;declarative transaction management&lt;/a&gt; thinking &lt;em&gt;wtf is this mumbo jumbo again&lt;/em&gt;. I’m already feeling my action oriented &lt;em&gt;aspect&lt;/em&gt; (pun intented) screaming for action instead of reading and then it hits me…this page tells &lt;em&gt;“AOP concepts do not generally have to be understood to make effective use of this code.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I laugh out loud.&lt;/p&gt;

&lt;p&gt;A quick scan to the rest of the mumbo and I click back and go for the next page of the documentation.&lt;/p&gt;

&lt;p&gt;The next page of the docs explains &lt;a href=&quot;https://docs.spring.io/spring-framework/reference/core/aop/introduction-defn.html&quot;&gt;key consepts of AOP&lt;/a&gt;. This seems to be a bit more readable page and maybe I can come back to this later. I quickly glance couple more pages, but there is too much text for now and too little use cases I understand and know where to use this. It is time to read some code and examples since I’m done with aspects and advices for now.&lt;/p&gt;

&lt;h2 id=&quot;breaktrough&quot;&gt;Breaktrough&lt;/h2&gt;

&lt;p&gt;I search for “AOP examples” and get the Spring doc examples. Seems cool, but doesn’t yet connect in my mind. I continue searching for something that breaks the ice. Software is not rocket science when the problems are broken down to simple pieces. Then I land on a &lt;a href=&quot;https://medium.com/@sharmapraveen91/mastering-spring-aop-the-ultimate-guide-for-2025-55a146c8204c&quot;&gt;Medium post about AOP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And there it is…&lt;strong&gt;Use cases for AOP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This mofo can be used to hook something and print something to log!&lt;/p&gt;

&lt;p&gt;Now we are talking. Finally something real I can build on. Then I find out &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Before&lt;/code&gt; so there must be at least &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@After&lt;/code&gt; and eventually I find out &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Around&lt;/code&gt;. At the same time my brain is going full speed with infinite threads running and the rest of the post happens very quickly.&lt;/p&gt;

&lt;p&gt;From some place I learn that AOP can be used to make prints to logs without touching the contents of the method. Then I remember that this was said somewhere in the mumbo. The original pattern - how to calculate how long it takes to execute a function/method - has been there for ages and in my books that is called &lt;em&gt;Just save current time in the beginning of the execution and decrease that in the end of the execution&lt;/em&gt; -pattern. Maybe there is a cool acronym for this as well, but I’m this kind of pattern guy.&lt;/p&gt;

&lt;p&gt;The dots are connecting. They talked about microservices in the interview and it is fintech, so most likely it is god damn crucial to know how long it takes something to execute. And because it is a microservice, the logs might not be in the same place. And because the fintech is complex there can be quite a many dependencies, calculations and points to monitor.&lt;/p&gt;

&lt;p&gt;Now it is time to build something with this. I want to replicate similar environment. I don’t care where else AOP can be used for now.&lt;/p&gt;

&lt;p&gt;…&lt;em&gt;few moments later&lt;/em&gt;…&lt;/p&gt;

&lt;p&gt;The project is in &lt;a href=&quot;https://github.com/spedepekka/soon-i-know-aop&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Couple of notes I want to write here for similar people to me:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;To track the times across multiple platforms the word is actually &lt;em&gt;trace&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;To trace something between multiple places or services one needs something to trace&lt;/li&gt;
  &lt;li&gt;That something is just something unique like UUID…who would have thought :D&lt;/li&gt;
  &lt;li&gt;That something is called sometimes correlation ID&lt;/li&gt;
  &lt;li&gt;There is a nice Medium post about &lt;a href=&quot;https://medium.com/@anil.goyal0057/understanding-and-implementing-correlation-id-in-microservices-2900518954a0&quot;&gt;correlation ID&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;To get that UUID across services it must be attached to system and whatever call go between the services&lt;/li&gt;
  &lt;li&gt;Correlation ID is usually transferred from place A to place B via HTTP headers with something like X-Correlation-ID&lt;/li&gt;
  &lt;li&gt;If some sort of queue mechanism is used, then the correlation ID must be in the meta data&lt;/li&gt;
  &lt;li&gt;There is a new post from me about &lt;a href=&quot;/toying-with-correlation-id&quot;&gt;correlation id with Kotlin and Spring&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And now I have the basics for the logging thingamagick ready and it is just building from this moment on. It depends on the system how to calculate the times and there is no point to go there in this context. I’ll just say that the timings can be written from the code itself or they can be calculated with external tools that scoop up the logs and visualise stuff on Grafana or whatever. When the values are there, it is easy to create sort of alarm mechanism to watch how the system operates.&lt;/p&gt;

&lt;p&gt;Alright…now it is easier to learn what else can AOP do. Apparently it is used in transactional code as well like:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Around&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;execution(* com.example.aopDemo.service.*.*(..))&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;manageTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ProceedingJoinPoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;joinPoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Throwable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;beginTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;joinPoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;proceed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Proceed with the method call&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;commitTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rollbackTransaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now this is easy and readable. I think I cracked the gibberish and I don’t need a dictionary to realize ‘around’ means ‘wrapping around the method’, instead ‘somewhere around there’. This thing just pauses the execution of the method and one can continue executing it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;joinPoint.proceed()&lt;/code&gt;, which I mistakenly read at some point as ‘jointPoint’ (that actually is quite close, but I had my knee joints in my mind). Even the ‘join point’ means the ‘point to join “back” to original code’… like why was it so hard again to tell it simply in the beginning?&lt;/p&gt;

&lt;p&gt;But seriously, it is really hard to explain things to other people when the concept is something abstract and the reader doesn’t have anything real where to connect. So I’m not really saying that write better docs, because I don’t know how anybody else could understand the way I learn. So maybe it is better to try to write the mumbo jumbo, because after all it will make much more sense - even for me.&lt;/p&gt;

&lt;p&gt;Back to the example…there is some transaction going on, which can be anything. This example must be also quite used in fintech, because there are money transactions and most like a thousand other transactions going all over the place. Not to forget that in Spring there can be SQL-related transactions and of course these can overlap more or less in fintech context.&lt;/p&gt;

&lt;p&gt;Oh yeah…I forgot to mention that AOP can keep the business logic clean, which should mean less bugs. One doesn’t need to print timestamps to logs in the middle of some fancy state machine or similar full blown logical master piece. This might be actually one of the key motivations to create AOP, but I’m too lazy to check that from the docs, even though I like the idea of a clean code/function/method.&lt;/p&gt;

&lt;h2 id=&quot;how-does-test-related-annotations-work&quot;&gt;How does test related annotations work?&lt;/h2&gt;

&lt;p&gt;At some point I thought, “Isn’t this the same system than in tests like @Before/@BeforeEach/@After/@AfterEach and those annotations?” The answer is: Yes, these are similar, but annotations related to tests do not use AOP. They have their own ways of handling things that are not using AOP.&lt;/p&gt;

&lt;h2 id=&quot;openapi&quot;&gt;OpenAPI&lt;/h2&gt;

&lt;p&gt;There was a quick question about OpenAPI. In retrospective - All I can do is to laugh at my “I don’t know what that is” answer. The truth is that it didn’t ring any bells, but eventually it took a few seconds to figure out, because OpenAPI stuff is more basic stuff than AOP. I just have worked in projects where standards and definitions haven’t been so high priority. So, to be honest…not knowing OpenAPI might tell more about the past projects than me.&lt;/p&gt;

&lt;p&gt;I also said at some point that I would set up Swagger before doing any serious API-stuff. Swagger is not the same as OpenAPI, but they are somewhat related.&lt;/p&gt;

&lt;p&gt;By basic stuff in this context I mean: OpenAPI makes sense and one can do many of the aspects of OpenAPI without realising the thing is part of OpenAPI ideology. For example one can write APIs in similar manner related to others and not scribble any word that comes to mind when writing the code or designing the API. Another thing is to make sure two components speak the same language with each other.&lt;/p&gt;

&lt;p&gt;So I would define OpenAPI “Yet another tool to describe something (in this case HTTP API) to avoid broken connections and misconfigurations and providing easier testing”. If we use that definition and ask the same question again, the answer would be something like “There have been numerous cases where I’ve configured/coded/defined a step in the pipeline or made programmatically sure something is like it should be.”&lt;/p&gt;

&lt;p&gt;So I kinda can say I’ve almost used OpenAPI, because it is so simple and straightforward, but I didn’t know what OpenAPI stands for at the time.&lt;/p&gt;

&lt;h2 id=&quot;afterwords&quot;&gt;Afterwords&lt;/h2&gt;

&lt;p&gt;When I was writing this texts I figured out that here is a story to tell if I don’t know something in the future in interviews. This post hopefully proves that I can learn something quickly and I’m good at connecting the dots, when there is something to connect to. Maybe people can get I bit better grasp who I am and who they are paying to do stuff.&lt;/p&gt;

&lt;p&gt;There are other things one can do with AOP and my Github code for this project doesn’t really cover much yet, but for this Friday this is enough.&lt;/p&gt;

&lt;p&gt;It is hard to know as an interviewer who can deliver and who cannot, who fits the team and who doesn’t. I don’t know how it goes with this assignment, but I know - I can deliver and I can fit.&lt;/p&gt;

&lt;h2 id=&quot;post-script-story&quot;&gt;Post script story&lt;/h2&gt;

&lt;p&gt;When I was proofreading this text I remembered one time in earlier company where a good friend of mine had a problem. He asked for help and he knew I might not be able to actually help, but everybody knows the rubberduck effect. I took a look over his shoulder and I was figuring out what he was doing. Then I asked “Does this system work like this: X is the goal. A connects to C through B and it is quite hard to catch all events because of Z.” He silently looked at me over his shoulder and said stunningly “That is exatcly like it works.”&lt;/p&gt;

</description>
        <pubDate>Fri, 13 Feb 2026 09:38:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/from-interview-to-learn-aop-and-openapi</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/from-interview-to-learn-aop-and-openapi</guid>
        
        
      </item>
    
      <item>
        <title>BSD here I come</title>
        <description>&lt;p&gt;I somehow stumbled to BSD-world again and thought that maybe I would have some use cases for it. I’ve installed some BSD-variant long time ago, but not really used it for anything.&lt;/p&gt;

&lt;h2 id=&quot;backstory&quot;&gt;Backstory&lt;/h2&gt;

&lt;p&gt;This time I had an oops-moment, when I configured Wireguard and accidentally opened router/firewall to world. I saw failed login attempt from router logs, which should not have been there, because it was external IP-address. My heart skipped a beat, because I didn’t have too much logs for my router. First I thought the router has been open to world a long time and I would have to assume it was compromised and reinstall everything. Then I thought a moment and realized this might be because I updated firmware and configured Wireguard. Of course…I disabled one rule from firewall and it exposed too much to the world. So it was like tens of minutes open with good password, so perhaps I can rule out hacking.&lt;/p&gt;

&lt;p&gt;I was cathing my breath while fixing the rules. What went wrong?&lt;/p&gt;

&lt;p&gt;First of all, I didn’t have proper logging propagation in place and the firmware upgrades removed old logs, so if I would have had to find out traces from hacking I wouldn’t have anything to dig. So I needed a way to save the logs to other place from the router. Of course I learned a lot from firewalls and Wireguard on the way, but this post is about BSD. This would be the perfect use case to try it out.&lt;/p&gt;

&lt;h2 id=&quot;which-variant-to-choose&quot;&gt;Which variant to choose?&lt;/h2&gt;

&lt;p&gt;There are two main BSD variants: &lt;a href=&quot;https://www.openbsd.org/&quot;&gt;OpenBSD&lt;/a&gt; and &lt;a href=&quot;https://www.freebsd.org/&quot;&gt;FreeBSD&lt;/a&gt;. Of course there are more, but those are the ones suitable for my needs. It seems that OpenBSD is more security oriented and it uses UFS as filesystem. FreeBSD seems to have a bit more “modern stuff” in it like &lt;a href=&quot;https://en.wikipedia.org/wiki/ZFS&quot;&gt;ZFS&lt;/a&gt;. This is not really about which variant is better or what filesystem is better. It’s more about what I want to do and learn. So I went for FreeBSD to make things rapid.&lt;/p&gt;

&lt;h2 id=&quot;fixing-the-logging-problem&quot;&gt;Fixing the logging problem&lt;/h2&gt;

&lt;p&gt;The installation of FreeBSD was quite pleasant experience. Nothing too fancy and everything worked smoothly. The only hiccups were my knowdledge base on BSD and mainly the commands etc.&lt;/p&gt;

&lt;p&gt;I decided to run syslog-ng in the BSD to catch the logs from router and save the logs to safe place. There are many things to improve here like automate this with Ansible and make it possible to easily add a new host that can send logs to my logging server. My VM-setup doesn’t really have too much free space or processing power so I decided not to go for ElasticSearch this time. I just want to fix this problem quickly and move to other things I want to do.&lt;/p&gt;

&lt;p&gt;Setting up FreeBSD configurations was a bit hard, because things are configured a bit differently what I’m used to, but at the same time things were more organized. This got my attention. It seems that in BSD there are more single files in BSD than Linux that configure the system, like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/rc.conf&lt;/code&gt; and I like it. I have to mention that &lt;a href=&quot;https://docs.freebsd.org/en/books/handbook/&quot;&gt;BSD has very cool manual or handbook&lt;/a&gt; where you need to start instead of ChatGPT or similar. The page for &lt;a href=&quot;https://man.freebsd.org/cgi/man.cgi?rc.conf&quot;&gt;rc.conf&lt;/a&gt; is very long and I assume it covers pretty much everything. Also &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pf&lt;/code&gt; (&lt;a href=&quot;https://man.freebsd.org/cgi/man.cgi?pf&quot;&gt;BSD firewall&lt;/a&gt;) syntax was something to learn, but it is much easier that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iptables&lt;/code&gt; rules.&lt;/p&gt;

&lt;p&gt;The final boss was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Address already in use&lt;/code&gt; problem. First I made sure my firewall rules and router configurations were correct with Netcat. But strangely, I was able to run Netcat in logging host without getting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Address already in use&lt;/code&gt;. It seemed that my syslog-ng wasn’t running at all. Configuring services and init-stuff is also quite pleasant in BSD. One doesn’t have to select what init-system to use. There is just the BSD-way and that’s it. It is also very easy to run a service with default configurations.&lt;/p&gt;

&lt;p&gt;I restarted the service and it still kept giving me the problem. Maybe syslog-ng is conflicting with syslogd, which have similar capabilities? That wasn’t the case, because the default setting was to run syslogd with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-ss&lt;/code&gt; which disabled UDP-listener on port 514. Finally I figured out that my configurations were wrong. I had the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;udp()&lt;/code&gt; earlier in the configuration and I tried to open it again. The easy fix was to remove the default one and go on.&lt;/p&gt;

&lt;p&gt;Now I get my logs from the router to FreeBSD’s syslog-ng at least. I could continue improving this system, but it is good enough for now.&lt;/p&gt;

&lt;p&gt;P.s. I heard that there are “own” beard styles for Linux and BSD people. I don’t know about that, but yeah, I have beard.&lt;/p&gt;

</description>
        <pubDate>Wed, 04 Feb 2026 06:08:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/bsd-here-i-come</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/bsd-here-i-come</guid>
        
        
      </item>
    
      <item>
        <title>How to Run sample.war in a Tomcat Docker Container</title>
        <description>&lt;p&gt;Running a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sample.war&lt;/code&gt; file in a Tomcat Docker container is straightforward with the right configuration. Here’s a step-by-step guide:&lt;/p&gt;

&lt;h2 id=&quot;1-prepare-your-project&quot;&gt;1. Prepare Your Project&lt;/h2&gt;

&lt;p&gt;Ensure you have the following ready:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sample.war&lt;/code&gt; file (your Java web application archive - &lt;a href=&quot;https://tomcat.apache.org/tomcat-11.0-doc/appdev/sample/sample.war&quot;&gt;for example Tomcat doc sample&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; to configure the Docker container.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2-dockerfile-configuration&quot;&gt;2. Dockerfile Configuration&lt;/h2&gt;

&lt;p&gt;Create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; in the same directory as your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sample.war&lt;/code&gt; file with the following content:&lt;/p&gt;

&lt;div class=&quot;language-dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; tomcat:11.0.2&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; sample.war /usr/local/tomcat/webapps/&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;EXPOSE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; 8080&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CMD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;catalina.sh&quot;, &quot;run&quot;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FROM tomcat:11.0.2&lt;/code&gt; Uses the official Tomcat 11.0.2 image as the base.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ADD sample.war /usr/local/tomcat/webapps/&lt;/code&gt; Adds the sample.war file to the Tomcat webapps directory for deployment.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPOSE 8080&lt;/code&gt; Exposes port 8080 for accessing the application.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMD [&quot;catalina.sh&quot;, &quot;run&quot;]&lt;/code&gt; Starts Tomcat in the foreground.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;3-build-the-docker-image&quot;&gt;3. Build the Docker Image&lt;/h2&gt;

&lt;p&gt;Run the following command to build the Docker image:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker build &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; tomcat-sample &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t tomcat-sample&lt;/code&gt; specifies the name of the image.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;4-run-the-docker-container&quot;&gt;4. Run the Docker Container&lt;/h2&gt;

&lt;p&gt;Start the container using:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8080:8080 &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; tomcat-sample-container tomcat-sample
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-d&lt;/code&gt; Runs the container in detached mode.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-p 8080:8080&lt;/code&gt; Maps port 8080 of the container to port 8080 on the host.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--name tomcat-sample-container&lt;/code&gt; Assigns a name to the container.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tomcat-sample&lt;/code&gt; Specifies the image to use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;5-access-the-application&quot;&gt;5. Access the Application&lt;/h2&gt;

&lt;p&gt;Once the container is running, access your application in a web browser at: &lt;a href=&quot;http://localhost:8080/sample&quot;&gt;http://localhost:8080/sample&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost&lt;/code&gt; with the appropriate IP address if running on a remote server.&lt;/p&gt;

&lt;h2 id=&quot;6-verify-the-deployment&quot;&gt;6. Verify the Deployment&lt;/h2&gt;

&lt;p&gt;You should see your application’s homepage or a Tomcat message confirming successful deployment.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;This is how browser should look like when Tomcat and sample application is running&quot; src=&quot;assets/tomcat-hello-world.png&quot; /&gt;&lt;/p&gt;

</description>
        <pubDate>Mon, 20 Jan 2025 09:06:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/how-to-run-sample-war-in-a-tomcat-docker-container</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/how-to-run-sample-war-in-a-tomcat-docker-container</guid>
        
        
      </item>
    
      <item>
        <title>Ubuntu or Kubuntu 23.10 ADB connection to OnePlus 8T</title>
        <description>&lt;p&gt;The first time I did this udev rules fix for Android ADB connection was around 2012. Today I had to do it again for my Kubuntu 23.10.&lt;/p&gt;

&lt;h2 id=&quot;1-enable-developer-mode&quot;&gt;1. Enable developer mode&lt;/h2&gt;

&lt;p&gt;Go to &lt;em&gt;Settings / About Device / Version&lt;/em&gt; and tap Build number 10 times.&lt;/p&gt;

&lt;p&gt;Go to &lt;em&gt;Settings / System Settings / Developer options&lt;/em&gt; and make sure USB debugging is turned on.&lt;/p&gt;

&lt;p&gt;For some reason I wasn’t developer in my main device so I had to do this to make the device even visible into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adb devices&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;2-plug-the-device-in&quot;&gt;2. Plug the device in&lt;/h2&gt;

&lt;p&gt;After connecting the device and running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adb devices&lt;/code&gt; I got following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;List of devices attached
c6342f8c        no permissions (missing udev rules? user is in the plugdev group); see [http://developer.android.com/tools/device.html]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This indicates that the udev rules are not properly set up.&lt;/p&gt;

&lt;h2 id=&quot;3-fix-udev-rules&quot;&gt;3. Fix udev rules&lt;/h2&gt;

&lt;p&gt;Instead of trying to find the correct values from search engines just use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsusb&lt;/code&gt;. It should tell the vendor and product ID for your device.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Bus 001 Device 012: ID 2abc:4def OnePlus Technology ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Open udev rules&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo vim /etc/udev/rules.d/51-android.rules
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and put the values from lsusb into it like this&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SUBSYSTEM==&quot;usb&quot;, ATTR{idVendor}==&quot;2abc&quot;, ATTR{idProduct}==&quot;4def&quot;, MODE=&quot;0666&quot;, GROUP=&quot;plugdev&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember to make sure your user is part of group &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugdev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then reload the rules.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo udevadm control --reload-rules
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
        <pubDate>Thu, 07 Mar 2024 07:36:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/ubuntu-23-10-adb-connection-to-oneplus-8t</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/ubuntu-23-10-adb-connection-to-oneplus-8t</guid>
        
        
      </item>
    
      <item>
        <title>Getting back to NeoVim</title>
        <description>&lt;p&gt;For some reason I bumped into streamer called &lt;a href=&quot;https://www.twitch.tv/theprimeagen&quot;&gt;Primeagen&lt;/a&gt;. He uses Vim as his editor and I’ve used Vim in the past quite a lot. When I came back to software industry, I didn’t get back to using Vim for some reason. I’ve used quite a lot of time honing my Vim skills and plugin setup, but clearly Prime (let’s call &lt;a href=&quot;https://youtube.fandom.com/wiki/ThePrimeagen&quot;&gt;Primeagen/Michael&lt;/a&gt; Prime for now) is magnitudes faster than I’ve been. He uses tmux as well and dvorak. Dvorak has been my dream for years, but I haven’t given the time to learn that.&lt;/p&gt;

&lt;p&gt;So I dug deeper into question ‘Who is this Prime guy?’. I found out that he has been very open with his setup and he also has couple of courses about the topic: &lt;a href=&quot;https://frontendmasters.com/courses/developer-productivity&quot;&gt;Developer productivity&lt;/a&gt; and &lt;a href=&quot;https://frontendmasters.com/courses/vim-fundamentals&quot;&gt;Vim fundamentals&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also liked his streams based on a quick glance. The one I watched for a while was a stream about &lt;a href=&quot;https://turso.tech/&quot;&gt;Turso&lt;/a&gt;. Turso is some sort of SQLite-cloud and I need to dig deeper into Turso, but that is for later.&lt;/p&gt;

&lt;p&gt;It took quite a while clean my old Vim plugins, because there was many broken ones and ones that I don’t use. The current setup is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ack.vim&lt;/li&gt;
  &lt;li&gt;bufexlorer&lt;/li&gt;
  &lt;li&gt;ctrlp.vim&lt;/li&gt;
  &lt;li&gt;nerdcommenter&lt;/li&gt;
  &lt;li&gt;nerdtree&lt;/li&gt;
  &lt;li&gt;tabular&lt;/li&gt;
  &lt;li&gt;tagbar&lt;/li&gt;
  &lt;li&gt;vim-fugitive&lt;/li&gt;
  &lt;li&gt;vim-gist&lt;/li&gt;
  &lt;li&gt;vim-markdown&lt;/li&gt;
  &lt;li&gt;vim-substitute&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I still need to deepen my understanding of these plugins and re-remember the hotkeys etc.&lt;/p&gt;
</description>
        <pubDate>Thu, 07 Mar 2024 05:40:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/getting-back-to-neovim</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/getting-back-to-neovim</guid>
        
        
      </item>
    
      <item>
        <title>How I Finally Enabled SSL Certificates on My GitHub Pages Websites</title>
        <description>&lt;p&gt;For many years, my websites hosted on GitHub Pages lacked the crucial HTTPS protocol. Initially, it seemed like a feature that wasn’t available, but a recent encounter with a GitHub-hosted site using Jekyll piqued my curiosity. I decided it was time to explore whether I could also add the SSL magic to my websites. Surprisingly, the process turned out to be quite simple.&lt;/p&gt;

&lt;h2 id=&quot;the-old-a-records&quot;&gt;The Old A Records:&lt;/h2&gt;

&lt;p&gt;Previously, my A records looked like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;192.30.252.153&lt;/li&gt;
  &lt;li&gt;192.30.252.154&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-new-a-records&quot;&gt;The New A Records:&lt;/h2&gt;

&lt;p&gt;To enable SSL, I had to update the A records to the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;185.199.108.153&lt;/li&gt;
  &lt;li&gt;185.199.109.153&lt;/li&gt;
  &lt;li&gt;185.199.110.153&lt;/li&gt;
  &lt;li&gt;185.199.111.153&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-aaaa-records&quot;&gt;The AAAA Records:&lt;/h2&gt;

&lt;p&gt;Additionally, I needed to add AAAA records:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2606:50c0:8000::153&lt;/li&gt;
  &lt;li&gt;2606:50c0:8001::153&lt;/li&gt;
  &lt;li&gt;2606:50c0:8002::153&lt;/li&gt;
  &lt;li&gt;2606:50c0:8003::153&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This task was particularly cumbersome because GoDaddy, my domain registrar, insisted on verifying multiple times that it was indeed me making the DNS changes.&lt;/p&gt;

&lt;h2 id=&quot;enforcing-https&quot;&gt;Enforcing HTTPS&lt;/h2&gt;

&lt;p&gt;The setting to enforce HTTPS can be found in the repository settings under Pages and Custom Domain. All it took was a simple tick of the box, and I was good to go—once GitHub figured out the updated DNS records.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Enabling SSL certificates on my GitHub Pages websites was a long-overdue task that turned out to be much simpler than I anticipated. With a few DNS record updates and a checkbox tick, I finally joined the ranks of secure website owners. If you’re in a similar situation, don’t hesitate to make the switch—it’s easier than you think and well worth the effort in terms of security and user trust.&lt;/p&gt;

</description>
        <pubDate>Wed, 06 Mar 2024 20:33:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/how-i-finally-enabled-ssl-certificates-on-my-github-pages-websites</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/how-i-finally-enabled-ssl-certificates-on-my-github-pages-websites</guid>
        
        
      </item>
    
      <item>
        <title>Back to software</title>
        <description>&lt;p&gt;I came back to software business couple years ago, because that SEO-thing didn’t go eventually so well. I worked for &lt;a href=&quot;https://boogiesoftware.com/&quot;&gt;Boogie&lt;/a&gt; again for couple of years and now I’m a freelancer.&lt;/p&gt;

&lt;p&gt;I learned marketing isn’t really my thing. I use SEO for own sites, but not really besides that.&lt;/p&gt;

&lt;p&gt;So soon there should be some improvements here as well.&lt;/p&gt;

</description>
        <pubDate>Tue, 05 Mar 2024 15:45:00 +0000</pubDate>
        <link>http://rapidprogrammer.com/back-to-software</link>
        <guid isPermaLink="true">http://rapidprogrammer.com/back-to-software</guid>
        
        
      </item>
    
  </channel>
</rss>
