Skip to content

Commit 4fede5d

Browse files
[CI] Publish Preview for PR #1 22b4008
1 parent 4c4c814 commit 4fede5d

File tree

2 files changed

+231
-31
lines changed

2 files changed

+231
-31
lines changed

pull-1/sitemap.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@
22
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
33
<url>
44
<loc>https://redhat-solution-patterns.github.io/solution-patterns/solution-pattern-event-mesh-for-microservices/01-pattern.html</loc>
5-
<lastmod>2025-01-30T13:22:17.017Z</lastmod>
5+
<lastmod>2025-02-04T11:41:02.800Z</lastmod>
66
</url>
77
<url>
88
<loc>https://redhat-solution-patterns.github.io/solution-patterns/solution-pattern-event-mesh-for-microservices/02-architecture.html</loc>
9-
<lastmod>2025-01-30T13:22:17.017Z</lastmod>
9+
<lastmod>2025-02-04T11:41:02.800Z</lastmod>
1010
</url>
1111
<url>
1212
<loc>https://redhat-solution-patterns.github.io/solution-patterns/solution-pattern-event-mesh-for-microservices/03-demo.html</loc>
13-
<lastmod>2025-01-30T13:22:17.017Z</lastmod>
13+
<lastmod>2025-02-04T11:41:02.800Z</lastmod>
1414
</url>
1515
<url>
1616
<loc>https://redhat-solution-patterns.github.io/solution-patterns/solution-pattern-event-mesh-for-microservices/04-workshop.html</loc>
17-
<lastmod>2025-01-30T13:22:17.017Z</lastmod>
17+
<lastmod>2025-02-04T11:41:02.800Z</lastmod>
1818
</url>
1919
<url>
2020
<loc>https://redhat-solution-patterns.github.io/solution-patterns/solution-pattern-event-mesh-for-microservices/developer-resources.html</loc>
21-
<lastmod>2025-01-30T13:22:17.017Z</lastmod>
21+
<lastmod>2025-02-04T11:41:02.800Z</lastmod>
2222
</url>
2323
<url>
2424
<loc>https://redhat-solution-patterns.github.io/solution-patterns/solution-pattern-event-mesh-for-microservices/index.html</loc>
25-
<lastmod>2025-01-30T13:22:17.017Z</lastmod>
25+
<lastmod>2025-02-04T11:41:02.800Z</lastmod>
2626
</url>
2727
</urlset>

pull-1/solution-pattern-event-mesh-for-microservices/03-demo.html

Lines changed: 225 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,226 @@ <h4 id="_bundling_of_different_logical_domains"><a class="anchor" href="#_bundli
307307
<h3 id="_refactoring"><a class="anchor" href="#_refactoring"></a><a class="link" href="#_refactoring">1.2. Refactoring</a></h3>
308308
<div class="paragraph">
309309
<p>In this section, we&#8217;ll refactor the Cabs application.
310-
The refactoring will be limited to make the process easy to understand.</p>
310+
The refactoring will be limited to make the process easy to understand.
311+
The scope of the refactoring will be the extraction of drivers module, which is already a separate domain in the codebase.
312+
Within the scope of the <code>completeTransit</code> method, we&#8217;ll need to shift the way we calculate the fee for the driver.
313+
The calculation will be done asynchronously, and when the driver module publishes the calculation result, it will be saved back into the database.</p>
314+
</div>
315+
<div class="paragraph">
316+
<p>The base for the refactoring is the <em>Event Mesh</em> pattern, and the asynchronous communication will be done with <em>Cloud Events</em>.</p>
317+
</div>
318+
<div class="sect3">
319+
<h4 id="_drivers_module"><a class="anchor" href="#_drivers_module"></a><a class="link" href="#_drivers_module">1.2.1. Drivers module</a></h4>
320+
<div class="paragraph">
321+
<p>The functionality around drivers is already quite separated in the codebase, so it is a good staring point to extract into a separate module.
322+
The drivers module will become a standalone web service, deployed on the <em>Kubernetes</em> cluster.
323+
The implementation of the drivers module will be done with <em>Rust</em> for this example.</p>
324+
</div>
325+
<div class="paragraph">
326+
<p>Here&#8217;s the <em>Rust</em> code for calculate fee functionality.
327+
The entrypoint is the <em>Cloud Event</em> of type <code>cabs.drivers.calculate-fee</code> we are expecting the <em>Event Mesh</em> will route.</p>
328+
</div>
329+
<div class="listingblock">
330+
<div class="content">
331+
<pre class="highlightjs highlight"><code class="language-rust hljs" data-lang="rust">impl Service {
332+
pub async fn calculate_fee(&amp;mut self, ce: Event) -&gt; Result&lt;()&gt; {
333+
let fee_event = Self::parse_fee_event(ce)?; <i class="conum" data-value="1"></i><b>(1)</b>
334+
let subject = fee_event.id.clone();
335+
336+
let drv = self.repo.get(&amp;fee_event.entity.driver_id).await?;
337+
338+
let fee = drv.calculate_fee(&amp;fee_event.entity.transit_price); <i class="conum" data-value="2"></i><b>(2)</b>
339+
340+
let fee_event = DriverFeeEvent {
341+
driver_id: fee_event.entity.driver_id,
342+
fee,
343+
}; <i class="conum" data-value="3"></i><b>(3)</b>
344+
345+
let mut builder = fee_event.to_builder(); <i class="conum" data-value="3"></i><b>(3)</b>
346+
if let Some(id) = subject {
347+
builder = builder.subject(id);
348+
} <i class="conum" data-value="3"></i><b>(3)</b>
349+
let ce = builder.build().map_err(error::ErrorInternalServerError)?; <i class="conum" data-value="3"></i><b>(3)</b>
350+
351+
Sender::new(&amp;self.config).send(ce).await?; <i class="conum" data-value="4"></i><b>(4)</b>
352+
353+
Ok(())
354+
}
355+
// [..]
356+
}</code></pre>
357+
</div>
358+
</div>
359+
<div class="paragraph">
360+
<p>In the above code, we are doing the following:</p>
361+
</div>
362+
<div class="colist arabic">
363+
<table>
364+
<tr>
365+
<td><i class="conum" data-value="1"></i><b>1</b></td>
366+
<td>We are parsing the internal, business logic, fee event from the <em>Cloud Events</em> envelope.</td>
367+
</tr>
368+
<tr>
369+
<td><i class="conum" data-value="2"></i><b>2</b></td>
370+
<td>We are calculating the fee for this event, using some business logic.</td>
371+
</tr>
372+
<tr>
373+
<td><i class="conum" data-value="3"></i><b>3</b></td>
374+
<td>We are wrapping the calculated fee into the <em>Cloud Events</em> envelope.</td>
375+
</tr>
376+
<tr>
377+
<td><i class="conum" data-value="4"></i><b>4</b></td>
378+
<td>We are sending the fee back to the <em>Event Mesh</em> using <em>HTTP REST</em> client.</td>
379+
</tr>
380+
</table>
381+
</div>
382+
<div class="paragraph">
383+
<p>Of course, in order for this method to be called, we need to route the event from the HTTP listener:</p>
384+
</div>
385+
<div class="listingblock">
386+
<div class="content">
387+
<pre class="highlightjs highlight"><code class="language-rust hljs" data-lang="rust">pub fn routes() -&gt; impl HttpServiceFactory + 'static {
388+
web::resource("/").route(web::post().to(recv))
389+
}
390+
391+
async fn recv(
392+
ce: Event,
393+
state: web::Data&lt;State&gt;,
394+
binding: web::Data&lt;Binding&gt;,
395+
) -&gt; Result&lt;HttpResponse&gt; {
396+
log::info!("Received event:\n{}", ce);
397+
398+
let mut svc = service::new(state, binding).await?;
399+
400+
match ce.ty() {
401+
"cabs.drivers.calculate-fee" =&gt; svc.calculate_fee(ce).await,
402+
_ =&gt; Err(error::ErrorBadRequest("unsupported event type")),
403+
}?;
404+
405+
Ok(HttpResponse::Ok().finish())
406+
}</code></pre>
407+
</div>
408+
</div>
409+
<div class="paragraph">
410+
<p>Let&#8217;s see also the <em>Cloud Event</em> sender, that uses the <em>HTTP REST</em> client to send events to the <em>Event Mesh</em>:</p>
411+
</div>
412+
<div class="listingblock">
413+
<div class="content">
414+
<pre class="highlightjs highlight"><code class="language-rust hljs" data-lang="rust">impl Sender {
415+
pub async fn send(&amp;self, ce: Event) -&gt; Result&lt;()&gt; {
416+
log::debug!("sending {} event to {}:\n{:?}", ce.ty(), &amp;self.sink, ce,);
417+
418+
let response = self
419+
.client
420+
.post(&amp;self.sink) <i class="conum" data-value="1"></i><b>(1)</b>
421+
.event(ce)
422+
.map_err(error::ErrorInternalServerError)?
423+
.send()
424+
.await
425+
.map_err(error::ErrorInternalServerError)?;
426+
427+
match response.status().is_success() {
428+
true =&gt; Ok(()),
429+
false =&gt; {
430+
log::error!("failed to send event: {:#?}", response);
431+
Err(error::ErrorInternalServerError(format!(
432+
"failed to send event: {}",
433+
response.status()
434+
)))
435+
}
436+
}
437+
}
438+
}</code></pre>
439+
</div>
440+
</div>
441+
<div class="admonitionblock note">
442+
<table>
443+
<tr>
444+
<td class="icon">
445+
<i class="fa icon-note" title="Note"></i>
446+
</td>
447+
<td class="content">
448+
<div class="colist arabic">
449+
<table>
450+
<tr>
451+
<td><i class="conum" data-value="1"></i><b>1</b></td>
452+
<td>The client uses <em>POST</em> method, to send the <em>JSON</em> representation of the event to the sink.
453+
The <em>sink</em> is the URL of the target, in this case the url of the <em>Event Mesh</em>.</td>
454+
</tr>
455+
</table>
456+
</div>
457+
</td>
458+
</tr>
459+
</table>
460+
</div>
461+
</div>
462+
<div class="sect3">
463+
<h4 id="_event_mesh"><a class="anchor" href="#_event_mesh"></a><a class="link" href="#_event_mesh">1.2.2. Event Mesh</a></h4>
464+
<div class="paragraph">
465+
<p>In this section, we&#8217;ll use the <em>Event Mesh</em> setup to communication between the different parts of refactored code.</p>
466+
</div>
467+
<div class="paragraph">
468+
<p>Here&#8217;s the <em>Event Mesh</em> central component configuration, the <em>Broker</em>, which will be used in this example.
469+
The <em>Broker</em> here is the <em>Knative</em> component, and will be deployed in the <em>Kubernetes</em> cluster.</p>
470+
</div>
471+
<div class="listingblock">
472+
<div class="content">
473+
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">apiVersion: eventing.knative.dev/v1
474+
kind: Broker
475+
metadata:
476+
name: default
477+
namespace: demo
478+
spec:
479+
delivery:
480+
backoffDelay: PT0.2S <i class="conum" data-value="1"></i><b>(1)</b>
481+
backoffPolicy: exponential <i class="conum" data-value="2"></i><b>(2)</b>
482+
retry: 10 <i class="conum" data-value="3"></i><b>(3)</b></code></pre>
483+
</div>
484+
</div>
485+
<div class="colist arabic">
486+
<table>
487+
<tr>
488+
<td><i class="conum" data-value="1"></i><b>1</b></td>
489+
<td>The <code>backoffDelay</code> is the delay between retries, and us use <code>200ms</code> initially.</td>
490+
</tr>
491+
<tr>
492+
<td><i class="conum" data-value="2"></i><b>2</b></td>
493+
<td>The <code>backoffPolicy</code> is set to <code>exponential</code>, which means that the delay will be doubled each time.</td>
494+
</tr>
495+
<tr>
496+
<td><i class="conum" data-value="3"></i><b>3</b></td>
497+
<td>The <code>retry</code> is the number of times we retry before giving up.</td>
498+
</tr>
499+
</table>
500+
</div>
501+
<div class="admonitionblock important">
502+
<table>
503+
<tr>
504+
<td class="icon">
505+
<i class="fa icon-important" title="Important"></i>
506+
</td>
507+
<td class="content">
508+
<div class="paragraph">
509+
<p>Because the policy is <code>exponential</code>, the maximum time the <em>Broker</em> will be retrying is 6 min and 49 sec.
510+
In the above configuration, after that time is reached, the event will be dropped.</p>
511+
</div>
512+
</td>
513+
</tr>
514+
</table>
515+
</div>
516+
<div class="admonitionblock note">
517+
<table>
518+
<tr>
519+
<td class="icon">
520+
<i class="fa icon-note" title="Note"></i>
521+
</td>
522+
<td class="content">
523+
<div class="paragraph">
524+
<p>A <code>deadLetterSink</code> could be configured for the <em>Broker</em> to send the events that failed to be delivered in time to a back-up location.
525+
Events captured in a back-up location can be re-transmitted into the <em>Event Mesh</em> later.</p>
526+
</div>
527+
</td>
528+
</tr>
529+
</table>
311530
</div>
312531
<div class="imageblock">
313532
<div class="content">
@@ -318,7 +537,7 @@ <h3 id="_refactoring"><a class="anchor" href="#_refactoring"></a><a class="link"
318537
<p>The diagram illustrates the flow of events between the legacy application, the Knative <em>Event Mesh</em>, the fee calculator service, and the datastore.</p>
319538
</div>
320539
<div class="paragraph">
321-
<p>In this video you can see xpto:</p>
540+
<p>In this video you can see the above example presented by Red Hat' employee <a href="https://github.com/cardil">Chris Suszynski</a>:</p>
322541
</div>
323542
<div class="videoblock">
324543
<div class="content">
@@ -331,40 +550,21 @@ <h3 id="_refactoring"><a class="anchor" href="#_refactoring"></a><a class="link"
331550
</div>
332551
</div>
333552
</div>
553+
</div>
334554
<div class="sect1">
335555
<h2 id="_run_the_demonstration"><a class="anchor" href="#_run_the_demonstration"></a><a class="link" href="#_run_the_demonstration">2. Run the demonstration</a></h2>
336556
<div class="sectionbody">
337557
<div class="sect2">
338558
<h3 id="_before_getting_started"><a class="anchor" href="#_before_getting_started"></a><a class="link" href="#_before_getting_started">2.1. Before getting started</a></h3>
339-
<div class="paragraph">
340-
<p>To run this demo, you will need xpto.
341-
Adding to that, make sure to have:</p>
342-
</div>
343-
<div class="ulist">
344-
<ul>
345-
<li>
346-
<p>ABC</p>
347-
</li>
348-
<li>
349-
<p>XYZ</p>
350-
</li>
351-
<li>
352-
<p>XPTO</p>
353-
</li>
354-
</ul>
355-
</div>
559+
356560
</div>
357561
<div class="sect2">
358562
<h3 id="_installing_the_demo"><a class="anchor" href="#_installing_the_demo"></a><a class="link" href="#_installing_the_demo">2.2. Installing the demo</a></h3>
359-
<div class="paragraph">
360-
<p>Installation guide and basic test of the demo installation if needed</p>
361-
</div>
563+
362564
</div>
363565
<div class="sect2">
364566
<h3 id="_walkthrough_guide"><a class="anchor" href="#_walkthrough_guide"></a><a class="link" href="#_walkthrough_guide">2.3. Walkthrough guide</a></h3>
365-
<div class="paragraph">
366-
<p>How to run through the demo</p>
367-
</div>
567+
368568
</div>
369569
</div>
370570
</div>

0 commit comments

Comments
 (0)