{"id":1355,"date":"2024-05-22T14:31:16","date_gmt":"2024-05-22T14:31:16","guid":{"rendered":"https:\/\/adrianotanaka.com.br\/?p=1355"},"modified":"2024-05-22T21:00:54","modified_gmt":"2024-05-22T21:00:54","slug":"goldengate-23ai-with-asyncapi","status":"publish","type":"post","link":"https:\/\/adrianotanaka.com.br\/index.php\/2024\/05\/22\/goldengate-23ai-with-asyncapi\/","title":{"rendered":"GoldenGate 23ai with Data Stream and AsyncAPI"},"content":{"rendered":"\n<p>GoldenGate 23ai introduces a powerful new feature called Data Streams, which leverages the AsyncAPI specification and you publish your trail file directly from GoldenGate(and you can specify the CloudEvents format), according to the documentation:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Oracle GoldenGate Data Streams utilizes the AsyncAPI specification for defining asynchronous APIs. This approach enables applications to efficiently subscribe to data streams using a Publish or Subscribe model.&nbsp;<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.oracle.com\/en\/middleware\/goldengate\/core\/23\/coredoc\/distribute-data-streaming-service.html\">About Data Streams (oracle.com)<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>It was hard to me to understand the concept behind this but with the release of GoldenGate 23ai I had some time to play with it and here are my considerations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Producer<\/h2>\n\n\n\n<p>My producer is an extract capturing data from my 19c database, and here you don&#8217;t need anything special:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"506\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-1024x506.png\" alt=\"\" class=\"wp-image-1360\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-1024x506.png 1024w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-300x148.png 300w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-768x380.png 768w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image.png 1163w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"437\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-1.png\" alt=\"\" class=\"wp-image-1361\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-1.png 838w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-1-300x156.png 300w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-1-768x400.png 768w\" sizes=\"auto, (max-width: 838px) 100vw, 838px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>After your extract is up and running, go to Distribution Service &gt; Data Streams and create a new one selecting your trail file<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"585\" height=\"331\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-2.png\" alt=\"\" class=\"wp-image-1362\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-2.png 585w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-2-300x170.png 300w\" sizes=\"auto, (max-width: 585px) 100vw, 585px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"583\" height=\"562\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-3.png\" alt=\"\" class=\"wp-image-1363\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-3.png 583w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-3-300x289.png 300w\" sizes=\"auto, (max-width: 583px) 100vw, 583px\" \/><\/figure>\n\n\n\n<p>You can also apply some filters <\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-4.png\" alt=\"\" class=\"wp-image-1364\" width=\"567\" height=\"538\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-4.png 567w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-4-300x285.png 300w\" sizes=\"auto, (max-width: 567px) 100vw, 567px\" \/><\/figure>\n\n\n\n<p>Now that your Data Stream is up, the AsyncApi shows its power, all the specs are there to understand what you can do and what are the format available , the Data Stream reads the trail and publish it (using wss protocol).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"388\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-5-1024x388.png\" alt=\"\" class=\"wp-image-1366\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-5-1024x388.png 1024w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-5-300x114.png 300w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-5-768x291.png 768w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-5-1536x582.png 1536w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-5-2048x775.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In my case I&#8217;ve created some &#8220;endpoints&#8221;, each one to expose an specific operation type:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"391\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-6.png\" alt=\"\" class=\"wp-image-1369\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-6.png 730w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-6-300x161.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Consumer\/Subscribe<\/h2>\n\n\n\n<p>For the Consumer side I&#8217;m using the <a href=\"https:\/\/github.com\/vi\/websocat\/releases\" target=\"_blank\" rel=\"noopener\" title=\"\">websocat<\/a>, after the download you can run it from the command line with this syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/websocat.x86_64 wss:\/\/USER:'PASSWORD'@SERVER:9102\/services\/v2\/stream\/DATA_STREAM_NAME<\/code><\/pre>\n\n\n\n<p>In my case I had to use the -k parameter to ignore the certificate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/websocat.x86_64 wss:\/\/USER:'PASSWORD'@SERVER:9102\/services\/v2\/stream\/myExample?begin=earliest -k\n<\/code><\/pre>\n\n\n\n<p>Now my application can subscribe to the endpoints.<\/p>\n\n\n\n<p>If I would like to consume only the inserts:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/websocat.x86_64 wss:\/\/USER:'PASSWORD'@SERVER:9102\/services\/v2\/stream\/dsINSERT?begin=earliest -k -v -S | jq -r<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"666\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-7-1024x666.png\" alt=\"\" class=\"wp-image-1370\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-7-1024x666.png 1024w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-7-300x195.png 300w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-7-768x499.png 768w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-7.png 1207w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>And if i need to get only the updates<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/websocat.x86_64 wss:\/\/USER:'PASSWORD'@SERVER:9102\/services\/v2\/stream\/dsUPDATE?begin=earliest -k -v -S | jq -r<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"757\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-8-1024x757.png\" alt=\"\" class=\"wp-image-1371\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-8-1024x757.png 1024w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-8-300x222.png 300w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-8-768x568.png 768w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-8.png 1160w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>If your goal was to share your data in json format you can move from this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1012\" height=\"616\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-12.png\" alt=\"\" class=\"wp-image-1389\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-12.png 1012w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-12-300x183.png 300w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-12-768x467.png 768w\" sizes=\"auto, (max-width: 1012px) 100vw, 1012px\" \/><\/figure>\n\n\n\n<p>To this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"993\" height=\"373\" src=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-13.png\" alt=\"\" class=\"wp-image-1390\" srcset=\"https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-13.png 993w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-13-300x113.png 300w, https:\/\/adrianotanaka.com.br\/wp-content\/uploads\/2024\/05\/image-13-768x288.png 768w\" sizes=\"auto, (max-width: 993px) 100vw, 993px\" \/><\/figure>\n\n\n\n<p>As usual, there is no silver bullet, each project has specific details, but with this new option, your application\/consumer\/subscriber can go closer to the producer to get the data.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>GoldenGate 23ai introduces a powerful new feature called Data Streams, which leverages the AsyncAPI specification and you publish your trail file directly from GoldenGate(and you can specify the CloudEvents format), according to the documentation: Oracle GoldenGate Data Streams utilizes the AsyncAPI specification for defining asynchronous APIs. This approach enables applications to efficiently subscribe to data [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1375,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"material-hide-sections":[],"footnotes":""},"categories":[55,48,8,6],"tags":[],"class_list":["post-1355","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-api","category-goldengate","category-oci","category-oracle"],"_links":{"self":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts\/1355","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/comments?post=1355"}],"version-history":[{"count":15,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts\/1355\/revisions"}],"predecessor-version":[{"id":1391,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/posts\/1355\/revisions\/1391"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/media\/1375"}],"wp:attachment":[{"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/media?parent=1355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/categories?post=1355"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianotanaka.com.br\/index.php\/wp-json\/wp\/v2\/tags?post=1355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}