<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pauls Blog</title>
	<atom:link href="https://sterl.org/feed/" rel="self" type="application/rss+xml" />
	<link>https://sterl.org</link>
	<description></description>
	<lastBuildDate>Tue, 30 Dec 2025 15:18:26 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>A Bounded, Thread-Safe In-Memory Store for Java</title>
		<link>https://sterl.org/2025/12/java-simple-bound-memory-store/</link>
					<comments>https://sterl.org/2025/12/java-simple-bound-memory-store/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Tue, 30 Dec 2025 14:55:43 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[java test]]></category>
		<category><![CDATA[memory store]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[Unit Test]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1149</guid>

					<description><![CDATA[Problem In test scenarios or lightweight application components, there is a need for a simple, thread-safe, in-memory data store that can temporarily hold a limited number of objects. The store should be easy to use, avoid external dependencies (e.g., databases), support generation and use of unique identifiers as keys, and automatically evict the oldest entries&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>In test scenarios or lightweight application components, there is a need for a simple, thread-safe, in-memory data store that can temporarily hold a limited number of objects. The store should be easy to use, avoid external dependencies (e.g., databases), support generation and use of unique identifiers as keys, and automatically evict the oldest entries when a predefined capacity is exceeded. This enables predictable memory usage while providing fast access to recently stored data.</p>



<h2 class="wp-block-heading">Solution</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Java&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MemoryStore&lt;T&gt; {

    private final Lock lock = new ReentrantLock();
    private final int maxElements;

    private final Map&lt;String, T&gt; data = new LinkedHashMap&lt;&gt;() {
        // called during put and ensures the map doesn't grow
        @Override
        protected boolean removeEldestEntry(Map.Entry&lt;String, T&gt; eldest) {
            return size() &gt; maxElements;
        }
    };

    public MemoryStore(int maxElements) {
        if (maxElements &lt; 1) {
            throw new IllegalArgumentException(&quot;maxElements must be &gt; 1&quot;);
        }
        this.maxElements = maxElements;
    }
    
    public void store(T value) {
        this.store(UUID.randomUUID().toString(), value);
    }

    public void store(String key, T value) {
        lock.lock();
        try {
            data.put(key, value);
        } finally {
            lock.unlock();
        }
    }

    public T get(String key) {
        lock.lock();
        try {
            return data.get(key);
        } finally {
            lock.unlock();
        }
    }
    
    public int size() {
        lock.lock();
        try {
            return data.size();
        } finally {
            lock.unlock();
        }
    }
    
    public LinkedHashMap&lt;String, T&gt; data() {
        lock.lock();
        try {
            return new LinkedHashMap&lt;&gt;(this.data);
        } finally {
            lock.unlock();
        }
    }
}</pre></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2025/12/java-simple-bound-memory-store/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>REST SOAP API Client</title>
		<link>https://sterl.org/2025/08/rest-soap-api-client/</link>
					<comments>https://sterl.org/2025/08/rest-soap-api-client/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Tue, 05 Aug 2025 06:49:31 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Client]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[Testing]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1129</guid>

					<description><![CDATA[REST SOAP]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">REST</h2>



<ul class="wp-block-list">
<li><a href="https://insomnia.rest/">Insomnia</a> &#8212; offline possible</li>



<li><a href="https://www.postman.com/">Postman</a> &#8212; needs Login / data in the cloud</li>



<li><a href="https://scalar.com/">Scalar</a></li>



<li><a href="https://marketplace.visualstudio.com/items?itemName=humao.rest-client">REST Client &#8211; Visual Studio</a></li>



<li><a href="https://chromewebstore.google.com/detail/talend-api-tester-free-ed/aejoelaoggembcahagimdiliamlcdmfm">Talend API Tester</a> &#8212; Chrome Plugin</li>
</ul>



<h2 class="wp-block-heading">SOAP</h2>



<ul class="wp-block-list">
<li><a href="https://www.soapui.org/">SoapUI</a></li>
</ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2025/08/rest-soap-api-client/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Spring Persistent Tasks</title>
		<link>https://sterl.org/2025/04/spring-persistent-tasks/</link>
					<comments>https://sterl.org/2025/04/spring-persistent-tasks/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sun, 20 Apr 2025 07:16:43 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[dashboard]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Inbound Pattern]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Outbound Pattern]]></category>
		<category><![CDATA[Quartz]]></category>
		<category><![CDATA[quartz daschboard]]></category>
		<category><![CDATA[scheduled]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[task ui]]></category>
		<category><![CDATA[task-scheduling]]></category>
		<category><![CDATA[Transaction]]></category>
		<category><![CDATA[trigger]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1116</guid>

					<description><![CDATA[A simple task management framework designed to queue and execute asynchronous tasks with support for database persistence and a user-friendly interface. It can be used to implement scheduling patterns or outbound patterns. Focus is the usage with spring boot and JPA. https://github.com/sterlp/spring-persistent-tasks Key Features]]></description>
										<content:encoded><![CDATA[
<p>A simple task management framework designed to queue and execute asynchronous tasks with support for database persistence and a user-friendly interface. It can be used to implement scheduling patterns or outbound patterns.</p>



<p>Focus is the usage with spring boot and JPA.</p>



<p><a href="https://github.com/sterlp/spring-persistent-tasks">https://github.com/sterlp/spring-persistent-tasks</a></p>



<h2 class="wp-block-heading">Key Features</h2>



<ol class="wp-block-list">
<li><strong>JPA-Powered Persistence</strong>&nbsp;&#8211; Automatically persists tasks to your database</li>



<li><strong>Spring Boot Auto-Configuration</strong>&nbsp;&#8211; Simple setup with @EnableSpringPersistentTasks</li>



<li><strong>Clustering Support</strong>&nbsp;&#8211; Built-in lock management for distributed environments</li>



<li><strong>Type-Safe Tasks</strong>&nbsp;&#8211; Generic task definitions with state objects</li>



<li><strong>Retry Mechanisms</strong>&nbsp;&#8211; Automatic retry policies for failed executions</li>



<li><strong>Transactional Integration</strong>&nbsp;&#8211; Works with Spring&#8217;s transaction management</li>



<li><strong>Queue Management</strong> &#8211; Intelligent task queuing and prioritization</li>



<li><strong>Different DB Supports</strong> 
<ul class="wp-block-list">
<li>MsSQL</li>



<li>MariaDB</li>



<li>Postgres</li>
</ul>
</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2025/04/spring-persistent-tasks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Propagation REQUIRES_NEW &#038; NEVER &#124; Transaktionsmanagement mit Spring Boot, JPA &#038; Hibernate</title>
		<link>https://sterl.org/2025/01/propagation-requires_new-never-transaktionsmanagement-mit-spring-boot-jpa-hibernate/</link>
					<comments>https://sterl.org/2025/01/propagation-requires_new-never-transaktionsmanagement-mit-spring-boot-jpa-hibernate/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sun, 19 Jan 2025 20:17:00 +0000</pubDate>
				<category><![CDATA[YouTube]]></category>
		<category><![CDATA[@Transactional]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[NEVER]]></category>
		<category><![CDATA[propagation]]></category>
		<category><![CDATA[REQUIRES_NEW]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1119</guid>

					<description><![CDATA[In diesem Video tauchen wir tiefer in die Welt des Transaktionsmanagements ein und erklären die Unterschiede zwischen den Propagation-Einstellungen REQUIRES_NEW und NEVER in Spring Boot. Erfahre, wie du mit Spring Boot, Spring Data, JPA und Hibernate effektive Transaktionen in modernen Datenbanken steuerst. Lerne, wann und warum du REQUIRES_NEW nutzen solltest, um eine neue Transaktion zu&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In diesem Video tauchen wir tiefer in die Welt des Transaktionsmanagements ein und erklären die Unterschiede zwischen den Propagation-Einstellungen <code>REQUIRES_NEW</code> und <code>NEVER</code> in Spring Boot. Erfahre, wie du mit Spring Boot, Spring Data, JPA und Hibernate effektive Transaktionen in modernen Datenbanken steuerst.</p>



<p>Lerne, wann und warum du <code>REQUIRES_NEW</code> nutzen solltest, um eine neue Transaktion zu starten, und warum <code>NEVER</code> nützlich ist, um sicherzustellen, dass kein bestehender Transaktionskontext verwendet wird. Dieses Tutorial ist ideal für Entwickler, die fortgeschrittene Techniken des Transaktionsmanagements verstehen und in ihren Anwendungen umsetzen möchten.</p>



<p><a rel="noreferrer noopener" href="https://github.com/sterlp/youtube/blob/main/db-grundlagen/src/test/java/org/sterl/db_grundlagen/transaction/AuditServiceTest.java" target="_blank">Github</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Propagation REQUIRES_NEW &amp; NEVER | Transaktionsmanagement mit Spring Boot, JPA &amp; Hibernate" width="640" height="360" src="https://www.youtube.com/embed/_5JAer04v9M?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2025/01/propagation-requires_new-never-transaktionsmanagement-mit-spring-boot-jpa-hibernate/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React &#038; Spring Boot</title>
		<link>https://sterl.org/2024/12/react-spring-boot/</link>
					<comments>https://sterl.org/2024/12/react-spring-boot/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Wed, 11 Dec 2024 18:36:41 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[ReactJs]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[vite]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1095</guid>

					<description><![CDATA[Problem We want to combine Spring Boot with a simple React frontend. Use the React development features but also be able to use the Spring IDE. In the end, everything should be built using Maven and nicely packed into a JAR, just like any other Microservice. Let’s get started. Multi-Module project First we create a&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>We want to combine Spring Boot with a simple React frontend. Use the React development features but also be able to use the Spring IDE. In the end, everything should be built using Maven and nicely packed into a JAR, just like any other Microservice. Let’s get started.</p>



<h2 class="wp-block-heading">Multi-Module project</h2>



<p>First we create a spring project here <code>backend</code> folder and a react project in the <code>frontend</code> folder. The root pom should help us to build both projects in one run:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://sterl.org/wp-content/uploads/2024/12/image.png"><img fetchpriority="high" decoding="async" width="294" height="211" src="https://sterl.org/wp-content/uploads/2024/12/image.png" alt="" class="wp-image-1096"/></a></figure></div>


<h3 class="wp-block-heading">Root pom.xml</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;xml&quot;,&quot;mime&quot;:&quot;application/xml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;XML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;xml&quot;}">&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;groupId&gt;org.foo.bar&lt;/groupId&gt;
    &lt;artifactId&gt;project-root&lt;/artifactId&gt;
    &lt;version&gt;0.1.0-SNAPSHOT&lt;/version&gt;
    &lt;packaging&gt;pom&lt;/packaging&gt;

    &lt;properties&gt;
        &lt;java.version&gt;21&lt;/java.version&gt;
        &lt;maven.compiler.source&gt;${java.version}&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;${java.version}&lt;/maven.compiler.target&gt;
        &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
        &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
    &lt;/properties&gt;

    &lt;modules&gt;
        &lt;module&gt;frontend&lt;/module&gt;
        &lt;module&gt;backend&lt;/module&gt;
    &lt;/modules&gt;

  	&lt;!-- feel free to use spring as root instead of this --&gt;
    &lt;dependencyManagement&gt;
        &lt;dependencies&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-dependencies&lt;/artifactId&gt;
                &lt;version&gt;3.3.6&lt;/version&gt;
                &lt;type&gt;pom&lt;/type&gt;
                &lt;scope&gt;import&lt;/scope&gt;
            &lt;/dependency&gt;
        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;
&lt;/project&gt;</pre></div>



<h3 class="wp-block-heading">Backend pom.xml</h3>



<p>This is straight forward the generated pom from spring with just the dependency to the <code>frontend </code>project.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;xml&quot;,&quot;mime&quot;:&quot;application/xml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;XML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;xml&quot;}">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.foo.bar&lt;/groupId&gt;
        &lt;artifactId&gt;project-root&lt;/artifactId&gt;
        &lt;version&gt;0.1.0-SNAPSHOT&lt;/version&gt;
        &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
    &lt;/parent&gt;

    &lt;artifactId&gt;project-backend&lt;/artifactId&gt;

    &lt;dependencies&gt;
      	&lt;!-- thats the important part --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.foo.bar&lt;/groupId&gt;
            &lt;artifactId&gt;project-frontend&lt;/artifactId&gt;
            &lt;version&gt;${project.version}&lt;/version&gt;
        &lt;/dependency&gt;
      	&lt;!-- thats the important part end --&gt;
      
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
        &lt;/dependency&gt;  
        &lt;dependency&gt;
            &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
            &lt;artifactId&gt;lombok&lt;/artifactId&gt;
            &lt;optional&gt;true&lt;/optional&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;</pre></div>



<h3 class="wp-block-heading">Frontend pom.xml</h3>



<p>Now we have todo more stuff:</p>



<ol class="wp-block-list">
<li>Ensure the <code>dist</code> result is added to the JAR</li>



<li>Generate during the <code>generate-resources</code> phase also the content for the <code>dist</code> folder</li>



<li>Ensure that during a <code>mvn clean</code> all gets deleted</li>
</ol>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;xml&quot;,&quot;mime&quot;:&quot;application/xml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;XML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;xml&quot;}">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.foo.bar&lt;/groupId&gt;
        &lt;artifactId&gt;project-root&lt;/artifactId&gt;
        &lt;version&gt;0.1.0-SNAPSHOT&lt;/version&gt;
        &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
    &lt;/parent&gt;

    &lt;artifactId&gt;project-frontend&lt;/artifactId&gt;
    
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
    
    &lt;build&gt;
        &lt;!-- Ensure the dist result is added to the JAR --&gt;
        &lt;resources&gt;
            &lt;resource&gt;
                &lt;directory&gt;dist&lt;/directory&gt;
            &lt;/resource&gt;
        &lt;/resources&gt;

        &lt;plugins&gt;
          	&lt;!--
                Generate during the generate-resources phase 
                also the content for the dist folder 
            --&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
                &lt;artifactId&gt;exec-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;3.5.0&lt;/version&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;id&gt;npm install&lt;/id&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;exec&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;phase&gt;generate-resources&lt;/phase&gt;
                        &lt;configuration&gt;
                            &lt;executable&gt;npm&lt;/executable&gt;
                            &lt;arguments&gt;
                                &lt;argument&gt;install&lt;/argument&gt;
                                &lt;argument&gt;--prefer-offline&lt;/argument&gt;
                                &lt;argument&gt;--no-audit&lt;/argument&gt;
                                &lt;argument&gt;--progress=false&lt;/argument&gt;
                            &lt;/arguments&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;

                    &lt;execution&gt;
                        &lt;id&gt;npm build&lt;/id&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;exec&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;phase&gt;generate-resources&lt;/phase&gt;
                        &lt;configuration&gt;
                            &lt;executable&gt;npm&lt;/executable&gt;
                            &lt;arguments&gt;
                                &lt;argument&gt;run&lt;/argument&gt;
                                &lt;argument&gt;build&lt;/argument&gt;
                            &lt;/arguments&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;
            &lt;!-- Ensure that during a mvn clean all gets deleted --&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-clean-plugin&lt;/artifactId&gt;
                &lt;version&gt;3.4.0&lt;/version&gt;
                &lt;configuration&gt;
                    &lt;filesets&gt;
                        &lt;fileset&gt;
                            &lt;directory&gt;node_modules&lt;/directory&gt;
                        &lt;/fileset&gt;
                        &lt;fileset&gt;
                            &lt;directory&gt;dist&lt;/directory&gt;
                        &lt;/fileset&gt;
                    &lt;/filesets&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;</pre></div>



<h3 class="wp-block-heading">Ensure the result in the dist folder is compatible to Spring</h3>



<p>Spring will pick up automatically any static resources which are placed in the <code>static</code> folder. Here is an example for <a rel="noreferrer noopener" href="https://vite.dev/guide/" target="_blank">vite</a> to do so in the <code>vite.config.js</code>:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">export default defineConfig({
  plugins: [react()],
  build: {
    outDir: './dist/static',
    emptyOutDir: true, // also necessary
  }
})</pre></div>



<h2 class="wp-block-heading">Going beyond</h2>



<p>Sometime it is useful to host the UI in a sub path lets say <code>my-ui</code>, so the url would be <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color"><strong>http://localhost:8080/my-ui</strong></mark></p>



<p>For that we have to adjust the <code>vite.config.js</code>:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">export default defineConfig({
  plugins: [react()],
  base: 'my-ui',
  build: {
    outDir: './dist/static/my-ui',
    emptyOutDir: true,
  }
})</pre></div>



<p>Now it would also be helpful if we don&#8217;t have to directly type the <code>index.html</code> but tell Spring always to re-route.</p>



<p>For that we have to add a Spring Configuration Class:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">package org.foo.bar;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyFrontedConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController(&quot;/my-ui&quot;).setViewName(&quot;/my-ui/index.html&quot;);
        registry.addRedirectViewController(&quot;/my-ui/&quot;, &quot;/my-ui&quot;);
    }
}
</pre></div>



<h2 class="wp-block-heading">Add cache control to static react assets</h2>



<p>In the end int would also be nice that the generated static resources are cached by the client e.g. for a year. We will extend the <code>MyFrontedConfig</code> class with:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(&quot;/my-ui/assets/**&quot;) 
                .addResourceLocations(&quot;classpath:/static/my-ui/assets/&quot;) 
                .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));
    }</pre></div>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/12/react-spring-boot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Run Eclipse/STS on Windows WSL</title>
		<link>https://sterl.org/2024/09/run-eclipse-sts-on-windows-wsl/</link>
					<comments>https://sterl.org/2024/09/run-eclipse-sts-on-windows-wsl/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Thu, 26 Sep 2024 08:01:01 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[App Defender]]></category>
		<category><![CDATA[AppLocker]]></category>
		<category><![CDATA[ASR Block]]></category>
		<category><![CDATA[ASR Block Exception]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Spring STS]]></category>
		<category><![CDATA[VcXsrv]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[WSL]]></category>
		<category><![CDATA[x11]]></category>
		<category><![CDATA[Xlaunch]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1052</guid>

					<description><![CDATA[Problem In some companies, App Defender/AppLocker makes the entire Windows OS practically unusable. EXEs are blocked, and the virus scan slows any build to a crawl. Nevertheless, we still need to work, and WSL is often the only feasible solution. But how can we start, for example, Eclipse or any other application in WSL that&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>In some companies, App Defender/AppLocker makes the entire Windows OS practically unusable. EXEs are blocked, and the virus scan slows any build to a crawl. Nevertheless, we still need to work, and WSL is often the only feasible solution. But how can we start, for example, Eclipse or any other application in WSL that requires a screen?</p>



<h2 class="wp-block-heading">Solution</h2>



<p>We might wither build on x11 (steps 4 and 5) or use the build in <strong>WSLg</strong> which should run out of the box:</p>



<ol class="wp-block-list">
<li>Install eclipse or STS in Linux</li>



<li>Export the DISPLAY env variable export <code>DISPLAY=:0</code></li>



<li>Run <strong>eclipse </strong>or any other application in Linux</li>



<li>(optional) Install x11 in Linux <code>sudo apt install x11-xserver-utils</code></li>



<li>(optional) Install <a href="https://sourceforge.net/projects/vcxsrv/">VcXsrv </a>on windows</li>
</ol>



<h2 class="wp-block-heading">Install eclipse or Spring STS in Linux</h2>



<p>We might either install eclipse with <code>sudo</code> apt install eclipse or as many other of us choose to install a different IDE here an example for spring sts (update the URL as needed to the current version):</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;bash&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">wget https://cdn.spring.io/spring-tools/release/STS4/4.25.0.RELEASE/dist/e4.33/spring-tool-suite-4-4.25.0.RELEASE-e4.33.0-linux.gtk.x86_64.tar.gz
tar -xvf spring-tool-suite-4-4.25.0.RELEASE-e4.33.0-linux.gtk.x86_64.tar.gz
rm -rf spring-tool*
ln -s sts-4.25.0.RELEASE/SpringToolSuite4 sts</pre></div>



<h2 class="wp-block-heading">Export the DISPLAY env variable</h2>



<p>In order to find our windows screen we have to define the DISPLAY destination with the same named environment variable. The simplest way is to extend the .profile that it is automatically exported on each shell start (or .zprofile if zsh is used).</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;.profile&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">export DISPLAY=:0</pre></div>



<h2 class="wp-block-heading">Run <strong>eclipse </strong>or any other application</h2>



<p>Now we can either start eclipse using <code>./eclipse</code> or the spring STS using <code>./sts</code>. </p>



<p>In case of any issues the x11 app might help you e.g. using xeyes:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">sudo apt install x11-apps
xeyes</pre></div>



<h2 class="wp-block-heading">Install x11 in Linux</h2>



<p>x11 tools on Linux are responsible to send the screen information from our Linux system to windows and on the other hand receive mouse and keyboard commands. In ubuntu the tools can be installed by using:</p>



<p><code>sudo apt install x11-xserver-utils</code></p>



<p>This step is not need anymore on a newer WSL as by default windows support UI apps in the WSL using WSLg.</p>



<p>If x11 is used the DISPLAY variable has to be adjusted to point to the Windows Host machine.</p>



<h2 class="wp-block-heading">Install <a href="https://sourceforge.net/projects/vcxsrv/">VcXsrv </a>on windows</h2>



<p>In order to receive the screen information from Linux in Windows and to display the application started in Linux we need an x11 client here too. First we have to install <a href="https://sourceforge.net/projects/vcxsrv/">VcXsrv</a> and start it using <strong>XLaunch</strong> which will prompt us of the settings:</p>



<ol class="wp-block-list">
<li><strong>Multiple windows</strong> in the display settings, which allows us to start more than one app</li>



<li><strong>Start no client which</strong> of course requires us to start the app in Linux manually later on</li>
</ol>



<p>Everything else may stay in the default settings.</p>



<p>This step is not need anymore on a newer WSL as by default windows support UI apps in the WSL using WSLg.</p>



<h2 class="wp-block-heading">Alternatives</h2>



<ul class="wp-block-list">
<li><a href="https://github.com/microsoft/wslg">https://github.com/microsoft/wslg</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/09/run-eclipse-sts-on-windows-wsl/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Transaktionsmanagement mit Spring, JPA, Hibernate</title>
		<link>https://sterl.org/2024/08/transaktionsmanagement-mit-spring-jpa-hibernate/</link>
					<comments>https://sterl.org/2024/08/transaktionsmanagement-mit-spring-jpa-hibernate/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sat, 31 Aug 2024 15:02:17 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[@Transactional]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[Grundlagen Datenbanken]]></category>
		<category><![CDATA[Grundlagen Transaktionen]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Mandatory]]></category>
		<category><![CDATA[Read only transaction]]></category>
		<category><![CDATA[Required]]></category>
		<category><![CDATA[Spring Data]]></category>
		<category><![CDATA[Spring TransactionTemplate]]></category>
		<category><![CDATA[Transaction Timeout]]></category>
		<category><![CDATA[Transactions]]></category>
		<category><![CDATA[TransactionTemplate]]></category>
		<category><![CDATA[Transkationen]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1032</guid>

					<description><![CDATA[Lerne die Grundlagen des Transaktionsmanagements in modernen Datenbanken kennen, und erfahre, wie du mit Spring Boot, Spring Data, JPA und Hibernate effektiv arbeitest. In diesem Tutorial starten wir mit den Grundlagen der Datenbanktransaktionen in deiner Anwendung: &#8211; Transaktionen starten: Dieses Video ist perfekt für Entwickler, die ihre Fähigkeiten in Spring Framework erweitern und transaktionssichere Anwendungen&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Lerne die Grundlagen des Transaktionsmanagements in modernen Datenbanken kennen, und erfahre, wie du mit Spring Boot, Spring Data, JPA und Hibernate effektiv arbeitest.</p>



<p>In diesem Tutorial starten wir mit den Grundlagen der Datenbanktransaktionen in deiner Anwendung: &#8211; Transaktionen starten: </p>



<ul class="wp-block-list">
<li><strong>Transaktion starten</strong>: Verstehe, wie Du Transaktionen in Spring Boot richtig initialisierst.</li>



<li><strong>Rollback-Strategien:</strong> Erlerne die wichtigsten Methoden, um Transaktionen bei Fehlern sicher zurückzusetzen. </li>



<li><strong>Annotations</strong>: Setze Annotations gezielt ein, um Transaktionen zu steuern. </li>



<li><strong>Programmatische Transaktionen</strong>: Implementiere Transaktionen programmatisch und gewinne maximale Kontrolle. </li>



<li><strong>Read Only</strong>: Transaktionen für GET Operationen </li>



<li><strong>Timeouts</strong>: Wie stelle ich bei einer Transaktion einen Timeout ein, was muss ich beachten?</li>
</ul>



<p>Dieses Video ist perfekt für Entwickler, die ihre Fähigkeiten in Spring Framework erweitern und transaktionssichere Anwendungen erstellen möchten.</p>



<ul class="wp-block-list">
<li><a href="https://github.com/sterlp/youtube/commit/24f1d4e1576be803ec32142ffb84f438dcd30623">Git Commit</a></li>



<li><a href="https://github.com/sterlp/youtube/tree/main/db-grundlagen">Git Projekt</a></li>
</ul>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Transaktionsmanagement | Datenbanken | Spring Boot &amp; Data, JPA &amp; Hibernate | @Transactional" width="640" height="360" src="https://www.youtube.com/embed/9cY73uCj5wA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/08/transaktionsmanagement-mit-spring-jpa-hibernate/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Java Jobs and Trigger Frameworks</title>
		<link>https://sterl.org/2024/05/java-jobs-and-trigger-frameworks/</link>
					<comments>https://sterl.org/2024/05/java-jobs-and-trigger-frameworks/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Mon, 06 May 2024 07:45:53 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1026</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[
<ul class="wp-block-list">
<li><a href="https://www.quartz-scheduler.org/">Quartz</a></li>



<li><a href="https://github.com/kagkarlsson/db-scheduler">db-scheduler</a></li>



<li><a href="https://github.com/jobrunr/jobrunr">jobrunr</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/05/java-jobs-and-trigger-frameworks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Outbound-Pattern Microservices Architektur: Sichere Datenübergabe in verteilten Systemen</title>
		<link>https://sterl.org/2024/03/outbound-pattern-microservices-architektur-sichere-datenuebergabe-in-verteilten-systemen/</link>
					<comments>https://sterl.org/2024/03/outbound-pattern-microservices-architektur-sichere-datenuebergabe-in-verteilten-systemen/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Fri, 08 Mar 2024 12:08:51 +0000</pubDate>
				<category><![CDATA[Pattern & Best Practice]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Micro Services]]></category>
		<category><![CDATA[Outbound Pattern]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[software architektur]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1020</guid>

					<description><![CDATA[In verteilten Systemen, wie Microservice-Architekturen, stellen sich unweigerlich folgende Fragen: Das Outbound-Pattern kann uns hierbei helfen, dieses Problem zu lösen. Es handelt sich um eine bewährte Methode, um Datenkonsistenz und Transaktionen in verteilten Systemen zu gewährleisten.]]></description>
										<content:encoded><![CDATA[
<p>In verteilten Systemen, wie Microservice-Architekturen, stellen sich unweigerlich folgende Fragen:</p>



<ol class="wp-block-list">
<li>Wie können wir Daten/Updates sicher bzw. transaktional zwischen den Services übergeben?</li>



<li>Wie schaffen wir es, dass die unterschiedlichen Services nicht auseinanderlaufen?</li>
</ol>



<p>Das Outbound-Pattern kann uns hierbei helfen, dieses Problem zu lösen. Es handelt sich um eine bewährte Methode, um Datenkonsistenz und Transaktionen in verteilten Systemen zu gewährleisten.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Outbound-Pattern Microservices Architektur: Sichere Datenübergabe in verteilten Systemen" width="640" height="360" src="https://www.youtube.com/embed/Nzdpcuk5GdQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/03/outbound-pattern-microservices-architektur-sichere-datenuebergabe-in-verteilten-systemen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Setup Spring Boot Azure OAuth2 with CORS</title>
		<link>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/</link>
					<comments>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Thu, 01 Feb 2024 09:03:03 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[CORS error]]></category>
		<category><![CDATA[oauth2Login]]></category>
		<category><![CDATA[OAuth2UserService]]></category>
		<category><![CDATA[strict-origin-when-cross-origin]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=993</guid>

					<description><![CDATA[What is needed Setup an Azure AAD Application First we need an Azure AAD application which gives us the access to our AD users. The important part are the client id and the tenant id here: Add the web URIs which are allowed to use the OAuth2 login In the next step we have to&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">What is needed</h2>



<ol class="wp-block-list">
<li>Setup an Azure AAD Application</li>



<li>Add the web URIs which are allowed to use the OAuth2 login</li>



<li>Add a client secret for your application</li>



<li>Add API Permission to read the profile</li>



<li>Add needed Azure dependencies</li>



<li>Setup Spring OAuth config</li>



<li>Adjust the CORS settings in Spring to ensure token refreshes</li>



<li>Configure spring security</li>
</ol>



<h2 class="wp-block-heading">Setup an Azure AAD Application</h2>



<p>First we need an Azure AAD application which gives us the access to our AD users. The important part are the client id and the tenant id here:</p>



<figure class="wp-block-image size-full is-resized"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png"><img loading="lazy" decoding="async" width="810" height="243" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png" alt="" class="wp-image-1004" style="aspect-ratio:3.3333333333333335;width:840px;height:auto" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png 810w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-300x90.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-768x230.png 768w" sizes="auto, (max-width: 810px) 100vw, 810px" /></a></figure>



<h2 class="wp-block-heading">Add the web URIs which are allowed to use the OAuth2 login</h2>



<p>In the next step we have to allow &#8222;applications&#8220; based on their &#8222;DNS&#8220; name to access and login through this AAD. Ensure to remember the yellow part, which is later needed in the configutation.</p>



<p>The URLs are basically the one you whitelist for a login. If you setup the &#8222;test&#8220; AAD application you may want also add sometimes the localhost for testing. Ensure to remove it again later on.</p>



<figure class="wp-block-image size-large"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication.png"><img loading="lazy" decoding="async" width="1024" height="493" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-1024x493.png" alt="" class="wp-image-1006" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-1024x493.png 1024w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-300x144.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-768x369.png 768w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication.png 1368w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">Add a client secret for your application</h2>



<p>Next we have to create a secret for our application, we only require later the value of it. Please make sure you provide a new one after the expiration period.</p>



<p>You can have multiple secrets for multiple apps here.</p>



<figure class="wp-block-image size-large"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret.png"><img loading="lazy" decoding="async" width="1024" height="317" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-1024x317.png" alt="" class="wp-image-1009" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-1024x317.png 1024w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-300x93.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-768x238.png 768w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret.png 1439w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">Setup Spring OAuth config</h2>



<p>In this configuration we have to enter all the collected data <strong>azure-dev</strong> as name is here the suffix provided in the authentication section of the Azure AAD application. You can choose what ever name you like.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;yaml&quot;,&quot;mime&quot;:&quot;text/x-yaml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;YAML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;yaml&quot;}">spring:
  security:
    oauth2:
      client:
        provider:
          azure:
            issuer-uri: https://login.microsoftonline.com/&lt;Directory (tenant) ID&gt;/v2.0
            user-name-attribute: name
        registration:
          azure-dev:
            provider: azure
            client-id: &lt;Application (client) ID&gt;
            client-secret: &lt;the secret value you created for your app&gt;
            client-authentication-method: client_secret_post
            scope:
              - openid
              - email
              - profile</pre></div>



<h2 class="wp-block-heading">Spring Security</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">  @Bean
  SecurityFilterChain filterChain(HttpSecurity http, OptionalYourUserService userService) throws Exception {
    // @formatter:off
    http
      .authorizeHttpRequests(authorizeHttpRequests -&gt;
        authorizeHttpRequests
          // public URLs
          .requestMatchers(antMatcher(&quot;/actuator/health/readiness&quot;)).permitAll()
          // secure actuator
          .requestMatchers(antMatcher(&quot;/actuator/**&quot;)).hasRole(UserGroup.ADMIN)
          // app urls
          .requestMatchers(&quot;/api/**&quot;).authenticated()
          // default; recommended to use .authenticated()
          .anyRequest().permitAll()
      ).headers(headers -&gt; headers.frameOptions(FrameOptionsConfig::sameOrigin))
      .oauth2Login( oauth2 -&gt; oauth2
          .userInfoEndpoint(userInfo -&gt; userInfo
            .oidcUserService(oidcUserService(userService)))
      )
      .headers(headers -&gt; headers.frameOptions(FrameOptionsConfig::sameOrigin));
    // @formatter:on
    return http.build();
  }

  private OAuth2UserService&lt;OidcUserRequest, OidcUser&gt; oidcUserService(
    OptionalYourUserService userService) {
    return userRequest -&gt; {
      var oidcUser = new OidcUserService().loadUser(userRequest); // Delegate to the default
                                                                  // implementation
      
      // add any custom user service integration here, if required.

      return oidcUser;
    };
  }</pre></div>



<h2 class="wp-block-heading">Add CORS Config</h2>



<p>To avoid any <code>CORS error</code> / <code>strict-origin-when-cross-origin</code> in your application we have to whitelist the OAuth2 provider for any redirect, in this example login.microsoft:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">  @Bean
  protected CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList(&quot;https://login.microsoftonline.com/**&quot;));
    configuration.addAllowedHeader(&quot;*&quot;);
    configuration.addAllowedMethod(&quot;*&quot;);
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration(&quot;/**&quot;, configuration);
    return source;
  }</pre></div>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list">
<li>https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
