<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marc DiPasquale</title>
    <description>The latest articles on DEV Community by Marc DiPasquale (@mrc0113).</description>
    <link>https://dev.to/mrc0113</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F205353%2Feb855162-0912-470d-8751-f92fade661e2.jpg</url>
      <title>DEV Community: Marc DiPasquale</title>
      <link>https://dev.to/mrc0113</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mrc0113"/>
    <language>en</language>
    <item>
      <title>Publishing Github Java Packages to Maven Central for a New Domain</title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Fri, 19 Mar 2021 18:41:05 +0000</pubDate>
      <link>https://dev.to/mrc0113/publishing-github-java-packages-to-maven-central-for-a-new-domain-10d2</link>
      <guid>https://dev.to/mrc0113/publishing-github-java-packages-to-maven-central-for-a-new-domain-10d2</guid>
      <description>&lt;h1&gt;
  
  
  Overview
&lt;/h1&gt;

&lt;p&gt;🎉 The &lt;a href="//solace.com"&gt;Solace&lt;/a&gt; Developer Relations team recently launched our &lt;a href="//github.com/SolaceCommunity"&gt;SolaceCommunity github organization&lt;/a&gt; as a home for open source projects that are authored, maintained and supported by the amazing &lt;a href="//solace.community"&gt;Solace Community&lt;/a&gt;. If you're interested in joining our community you can read more about it &lt;a href="https://solace.com/blog/announcing-new-solacecommunity-github-organization/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, but that won't be the focus of the rest of this blog. &lt;strong&gt;The focus of this blog is how I enabled publishing of Java packages to Maven Central&lt;/strong&gt; for this new github community and &lt;strong&gt;how you can do so for your own domain&lt;/strong&gt;. Since Java is one of our most used languages, and most Java projects now leverage Maven or Gradle, I wanted to enable developers contributing their Java projects to be able to easily publish to Maven Central to make it easier for everyone in the community to easily use them.&lt;/p&gt;

&lt;p&gt;Over the past few weeks I went through the steps necessary to setup publishing of Java packages to Maven Central for the &lt;a href="https://solace.community" rel="noopener noreferrer"&gt;https://solace.community&lt;/a&gt; domain. This was trickier than I thought so I figured I'd share what I did to hopefully help others :)&lt;/p&gt;

&lt;p&gt;I'm going to try to keep this short and to the point but feel free to let me know if you have any questions.&lt;br&gt;
I used the following resources when figuring out these steps so props to their creators!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://central.sonatype.org/pages/ossrh-guide.html" rel="noopener noreferrer"&gt;OSSRH Guide&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/guides/publishing-java-packages-with-maven" rel="noopener noreferrer"&gt;Publishing Java packages with Maven&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c" rel="noopener noreferrer"&gt;How to Sign and Release to The Central Repository with GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Setting up OSSRH (The Repository)
&lt;/h2&gt;

&lt;p&gt;There are a handful of approved repository hosting options specified by Maven Central. You can find the entire list &lt;a href="https://maven.apache.org/repository/guide-central-repository-upload.html#approved-repository-hosting" rel="noopener noreferrer"&gt;here&lt;/a&gt;, but the easiest approach seems to leverage &lt;a href="http://central.sonatype.org/pages/ossrh-guide.html" rel="noopener noreferrer"&gt;Open Source Software Repository Hosting (OSSRH)&lt;/a&gt; so that's the approach I decided to take. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that if you're just trying to publish a few personal projects on github and are fine publishing under &lt;code&gt;io.github&lt;/code&gt; then you don't need to follow all of these steps so I'd suggest heading over to google and doing a few more searches :)&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Get An Account
&lt;/h3&gt;

&lt;p&gt;The first step down this road is to register a OSSRH account. This account will be used to prove ownership of your domain (for publishing packages), but also to manage your repositories in the future. &lt;a href="https://issues.sonatype.org/secure/Signup!default.jspa" rel="noopener noreferrer"&gt;Sign up for an account here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Account Created&lt;/p&gt;
&lt;h3&gt;
  
  
  Prove Domain Ownership
&lt;/h3&gt;

&lt;p&gt;Now that you have an account the next step in the process is to prove ownership of the domain that matches the group that you'd like to publish to. Usually this is your domain name in reverse, so something like &lt;code&gt;com.company&lt;/code&gt; if your domain is &lt;code&gt;company.com&lt;/code&gt;. Since our developer community is at &lt;code&gt;solace.community&lt;/code&gt; this meant we would publish to the &lt;code&gt;community.solace&lt;/code&gt; group.   &lt;/p&gt;

&lt;p&gt;To prove that we own this domain I had to execute a few simple steps: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a &lt;a href="https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&amp;amp;pid=10134" rel="noopener noreferrer"&gt;New Project Ticket&lt;/a&gt; with OSSRH. &lt;/li&gt;
&lt;li&gt;Follow the instructions request in the ticket to addd a DNS TXT record to our domain. &lt;/li&gt;
&lt;li&gt;Wait a few hours (it says it could take up to 2 business days) for the DNS TXT record to be verified. &lt;/li&gt;
&lt;li&gt;Check the ticket for confirmation that domain ownership has been confirmed.&lt;/li&gt;
&lt;li&gt;Make a note to comment on this ticket after your first release to enable syncing to maven central!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Domain ownership proven &lt;/p&gt;
&lt;h3&gt;
  
  
  Create Your User Token
&lt;/h3&gt;

&lt;p&gt;Now that we have permission to publish to our domain we need to create a user token for publishing. This token will be used as part of the publishing process. &lt;/p&gt;

&lt;p&gt;To get this token do the following: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login to the &lt;a href="https://s01.oss.sonatype.org/#welcome" rel="noopener noreferrer"&gt;OSSRH Nexus Repository Manager&lt;/a&gt; w/ your OSSRH account&lt;/li&gt;
&lt;li&gt;Go to your profile using the menu under your username at the top right.&lt;/li&gt;
&lt;li&gt;You should see a list menu that is on the &lt;code&gt;Summary&lt;/code&gt; page; change it to &lt;code&gt;User Token&lt;/code&gt;. You can create your token on this page. &lt;/li&gt;
&lt;li&gt;Copy &amp;amp; Paste this token info so you can use it later! &lt;strong&gt;(Keep it private!)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ OSSRH is now ready to go and we have the info we need &lt;/p&gt;
&lt;h2&gt;
  
  
  Configuring the Maven pom
&lt;/h2&gt;

&lt;p&gt;The next step is to setup our maven pom for publishing. Note that I used copy and paste programming to figure this out so I'm by no means an expert here :) &lt;br&gt;
If you are reading this and think I should include more detail here or my explanations are confusing please drop a comment and let me know.&lt;/p&gt;

&lt;p&gt;An entire example pom can be found &lt;a href="https://github.com/solacecommunity/spring-solace-leader-election/blob/master/pom.xml" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is what I did: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Ensured that my &lt;code&gt;groupId&lt;/code&gt; starts with the reverse domain that we have approval to publish to! For example this is what we used, note that the &lt;code&gt;groupId&lt;/code&gt; starts with &lt;code&gt;community.solace&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;community.solace.spring.integration&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;solace-spring-integration-leader&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.1.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;What to know about the version! Okay &lt;strong&gt;this is important&lt;/strong&gt;. When publishing maven projects you have releases and you have snapshots. A "release" is the final build for a version which does not change whereas a "snapshot" is a temporary build which can be replaced by another build with the same name. Go ahead and google this if you want to learn more :)&lt;br&gt;&lt;br&gt;&lt;br&gt;
Once you know the difference you're ready to set your version. Use a version ending in a number, e.g: &lt;code&gt;1.1.0&lt;/code&gt;, for a "release" and end it in &lt;code&gt;-SNAPSHOT&lt;/code&gt;, e.g: &lt;code&gt;1.1.0-SNAPSHOT&lt;/code&gt; for a snapshot. &lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Include a description name, description and url pointing to your repository. For example,&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Solace Spring Integration Leader&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;This project allows for Spring Integration Leader Election using Solace Exclusive Queues&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://github.com/solacecommunity/spring-solace-leader-election&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Include a license, source control info &lt;code&gt;scm&lt;/code&gt;, developers and organization(I believe this is optional) information.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;licenses&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;license&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;MIT License&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://github.com/solacecommunity/spring-solace-leader-election/blob/master/LICENSE&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;distribution&amp;gt;&lt;/span&gt;repo&lt;span class="nt"&gt;&amp;lt;/distribution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/license&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/licenses&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;developers&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;developer&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Solace Community&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;email&amp;gt;&lt;/span&gt;community-github@solace.com&lt;span class="nt"&gt;&amp;lt;/email&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;organization&amp;gt;&lt;/span&gt;Solace Community&lt;span class="nt"&gt;&amp;lt;/organization&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;organizationUrl&amp;gt;&lt;/span&gt;https://solace.community&lt;span class="nt"&gt;&amp;lt;/organizationUrl&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/developer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/developers&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;organization&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Solace Community&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://solace.community&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/organization&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;scm&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://github.com/solacecommunity/solace-spring-integration-leader.git&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;connection&amp;gt;&lt;/span&gt;scm:git:git://github.com/solacecommunity/solace-spring-integration-leader.git&lt;span class="nt"&gt;&amp;lt;/connection&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;developerConnection&amp;gt;&lt;/span&gt;scm:git:git@github.com:solacecommunity/solace-spring-integration-leader.git&lt;span class="nt"&gt;&amp;lt;/developerConnection&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tag&amp;gt;&lt;/span&gt;HEAD&lt;span class="nt"&gt;&amp;lt;/tag&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/scm&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Add a profile for OSSRH which includes the &lt;code&gt;snapshotRepository&lt;/code&gt; info, the &lt;code&gt;nexus-staging-maven-plugin&lt;/code&gt;, and the &lt;code&gt;maven-gpg-plugin&lt;/code&gt;. Note in the example below I have this profile &lt;code&gt;activeByDefault&lt;/code&gt; so you don't have to specify it when running maven commands, however you may not want to do this. Depends on your use case :)&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;profile&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;ossrh&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;activation&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;activeByDefault&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/activeByDefault&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/activation&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;gpg.executable&amp;gt;&lt;/span&gt;gpg&lt;span class="nt"&gt;&amp;lt;/gpg.executable&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;distributionManagement&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;snapshotRepository&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;ossrh&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Central Repository OSSRH&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://s01.oss.sonatype.org/content/repositories/snapshots&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/snapshotRepository&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/distributionManagement&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.sonatype.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;nexus-staging-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.6.7&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;extensions&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/extensions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;serverId&amp;gt;&lt;/span&gt;ossrh&lt;span class="nt"&gt;&amp;lt;/serverId&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;nexusUrl&amp;gt;&lt;/span&gt;https://s01.oss.sonatype.org/&lt;span class="nt"&gt;&amp;lt;/nexusUrl&amp;gt;&lt;/span&gt;
                        &lt;span class="c"&gt;&amp;lt;!--  Change to true once we're good! --&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;autoReleaseAfterClose&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/autoReleaseAfterClose&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-gpg-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.5&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;sign-artifacts&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;verify&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;sign&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;gpgArguments&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;--pinentry-mode&lt;span class="nt"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;loopback&lt;span class="nt"&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;/gpgArguments&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/profile&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Include the &lt;code&gt;maven-release-plugin&lt;/code&gt;, the &lt;code&gt;maven-javadoc-plugin&lt;/code&gt;, the &lt;code&gt;maven-source-plugin&lt;/code&gt; and the &lt;code&gt;flatten-maven-plugin&lt;/code&gt; plugin.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-release-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.5.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;tagNameFormat&amp;gt;&lt;/span&gt;@{project.version}&lt;span class="nt"&gt;&amp;lt;/tagNameFormat&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.shared&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-invoker&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-javadoc-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.10.4&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;attach-javadocs&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;source&amp;gt;&lt;/span&gt;8&lt;span class="nt"&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;detectJavaApiLink&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/detectJavaApiLink&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-source-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;attach-sources&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codehaus.mojo&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;flatten-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;updatePomFile&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/updatePomFile&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;flattenMode&amp;gt;&lt;/span&gt;oss&lt;span class="nt"&gt;&amp;lt;/flattenMode&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;pomElements&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;distributionManagement&amp;gt;&lt;/span&gt;remove&lt;span class="nt"&gt;&amp;lt;/distributionManagement&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;repositories&amp;gt;&lt;/span&gt;remove&lt;span class="nt"&gt;&amp;lt;/repositories&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/pomElements&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- enable flattening --&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;flatten&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;process-resources&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;flatten&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- ensure proper cleanup --&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;flatten.clean&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;clean&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;clean&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;✅ The maven pom is now ready to go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Create GPG Keys
&lt;/h2&gt;

&lt;p&gt;The next step is to create a GPG key for signing the published packages. This allows for users of your project to verify the published package's authenticity and trust using it in their own projects. In order to create a GPG key you will need to execute a few steps. &lt;/p&gt;

&lt;h2&gt;
  
  
  Create Your Key
&lt;/h2&gt;

&lt;p&gt;The first step is to &lt;strong&gt;Create Your Key&lt;/strong&gt;. You can do this locally using a tool such as gpg. Be sure to keep your &lt;strong&gt;private&lt;/strong&gt; key private. If others get ahold of this they can become a trusted publisher of your packages. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install the gpg tool; on mac you can do this by executing the command below. If you aren't using a mac check out the instructions &lt;a href=""&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate your key pair. You will be prompted for a "Real Name" and "Eamil Address" that you want to use with the key&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--gen-key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ GPG key created!&lt;/p&gt;

&lt;h2&gt;
  
  
  Share Your Public Key
&lt;/h2&gt;

&lt;p&gt;Now that you've generated your key pair, which consists of a private and a public key, you need to share the public piece. The public key will be used by developers to verify the package's authenticity. You can also do this with the &lt;code&gt;gpg&lt;/code&gt; command. It will share your key to a keyserver which tools such as maven know how to query to retrieve the keys for automated verification. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your keypair identifier.
To do this you need to list your keys. The key will have an identifier that looks like a random string of characters, something like &lt;em&gt;C48B6G0D63B854H7943892DF0C753FEC18D3F855&lt;/em&gt;. In the command below I've replaced it with &lt;code&gt;MYIDENTIFIER&lt;/code&gt; to show it's location.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;MJD-MacBook-Pro.local:~&lt;span class="nv"&gt;$ &lt;/span&gt;gpg &lt;span class="nt"&gt;--list-keys&lt;/span&gt;
/path/to/keyring/pubring.kbx
&lt;span class="nt"&gt;----------------------------------------&lt;/span&gt;
pub   rsa3072 2021-03-11 &lt;span class="o"&gt;[&lt;/span&gt;SC] &lt;span class="o"&gt;[&lt;/span&gt;expires: 2023-03-11]
      MYIDENTIFIER
uid           &lt;span class="o"&gt;[&lt;/span&gt;ultimate] solacecommunity &amp;lt;community-github@solace.com&amp;gt;
sub   rsa3072 2021-03-11 &lt;span class="o"&gt;[&lt;/span&gt;E] &lt;span class="o"&gt;[&lt;/span&gt;expires: 2023-03-11]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Distribute to a key server using the identifier found in the previous step. Note that you may want to publish to a different keyserver. The one that worked for me was &lt;code&gt;hkp://keyserver.ubuntu.com:11371&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--keyserver&lt;/span&gt; hkp://pool.sks-keyservers.net &lt;span class="nt"&gt;--send-keys&lt;/span&gt; MYIDENTIFIER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ We've now shared our public key!&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure the Github Secrets
&lt;/h2&gt;

&lt;p&gt;Okay at this point our project is looking pretty good and we could run a deployment locally using the &lt;code&gt;mvn --batch-mode clean deploy&lt;/code&gt; command, however we actually want to perform our releases via a Github action. Shoutout to &lt;a href="https://gist.github.com/sualeh" rel="noopener noreferrer"&gt;sualeh&lt;/a&gt; for creating &lt;a href="https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c" rel="noopener noreferrer"&gt;this gist&lt;/a&gt; which helps me navigate the next few steps! In order to make the release from a Github Action we need to make our GPG private key and OSSRH user information available to the Github actions while also keeping it private. We can do this using &lt;a href="https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets" rel="noopener noreferrer"&gt;Github Action Secrets&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I created secrets at the Github Organization level so I followed the steps below to keep my &lt;code&gt;OSSRH_GPG_SECRET_KEY&lt;/code&gt;,&lt;code&gt;OSSRH_GPG_SECRET_KEY_PASSWORD&lt;/code&gt;,&lt;code&gt;OSSRH_USERNAME&lt;/code&gt; and &lt;code&gt;OSSRH_PASSWORD&lt;/code&gt; secret. If not clear by the name these are my GPG Secret Key, my GPG Secret Key password, my OSSRH Username (from the token we generated earlier) and the OSSRH password (from the token we generated earlier).If that screenshot feels out of date you can find the &lt;a href="https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-an-organization" rel="noopener noreferrer"&gt;docs here&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw0p6tkm3tf70g7ne1wuv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw0p6tkm3tf70g7ne1wuv.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Secrets configured!&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the Github Action
&lt;/h2&gt;

&lt;p&gt;Now that the Github Action Secrets are available let's go ahead and configure the Github Action itself. To give credit where credit is due, I created this github action using this &lt;a href="https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c" rel="noopener noreferrer"&gt;gist&lt;/a&gt; as a starting point. You can find the Github Action &lt;a href="https://github.com/solacecommunity/spring-solace-leader-election/actions/runs/645154320/workflow" rel="noopener noreferrer"&gt;workflow file here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You'll see below that this Github Action will run on the latest ubuntu and execute the &lt;code&gt;publish&lt;/code&gt; job which has several steps. The steps will setup the maven central repository info, install the secret key and then run the command to publish to OSSRH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish package to the Maven Central Repository&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Maven Central Repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;11&lt;/span&gt;
          &lt;span class="na"&gt;server-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ossrh&lt;/span&gt;
          &lt;span class="na"&gt;server-username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MAVEN_USERNAME&lt;/span&gt;
          &lt;span class="na"&gt;server-password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MAVEN_PASSWORD&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install-secret-key&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install gpg secret key&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
         &lt;span class="s"&gt;cat &amp;lt;(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import&lt;/span&gt;
         &lt;span class="s"&gt;gpg --list-secret-keys --keyid-format LONG&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publish-to-central&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish to Central Repository&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;MAVEN_USERNAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.OSSRH_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;MAVEN_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.OSSRH_PASSWORD }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;mvn \&lt;/span&gt;
            &lt;span class="s"&gt;--no-transfer-progress \&lt;/span&gt;
            &lt;span class="s"&gt;--batch-mode \&lt;/span&gt;
            &lt;span class="s"&gt;-Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} \&lt;/span&gt;
            &lt;span class="s"&gt;clean deploy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Github Action ready to go&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Github Action - let's test it with a Snapshot release
&lt;/h2&gt;

&lt;p&gt;Now you're ready to run the Github Action. I'd recommend testing out the publishing of a snapshot release first. To ensure you do this make sure your &lt;code&gt;version&lt;/code&gt; in the pom ends in &lt;code&gt;-SNAPSHOT&lt;/code&gt; as discused earlier. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once the version on your &lt;code&gt;main&lt;/code&gt; branch includes &lt;code&gt;-SNAPSHOT&lt;/code&gt; go ahead and run the github action workflow. You should see the &lt;code&gt;publish&lt;/code&gt; job successed in a few minutes depending on how long your build takes. Ours took 1m 20s the first time. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the deploy job successfully runs you can head over to &lt;a href="https://s01.oss.sonatype.org/content/repositories/snapshots/" rel="noopener noreferrer"&gt;https://s01.oss.sonatype.org/content/repositories/snapshots/&lt;/a&gt; and navigate to your project to verify that the snapshot has successfully deployed. It should look something like this: &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;✅ Snapshot published!&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Github Action - now let's make an actual release
&lt;/h2&gt;

&lt;p&gt;Now that the snapshot has successfully deployed let's go ahead and make a real release. Make sure your code is ready before doing this part of course :)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change your version in the pom to remove the &lt;code&gt;-SNAPSHOT&lt;/code&gt;, so it should end in a number. Something like &lt;code&gt;1.1.0&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Re-Run the Github Action workflow. Wait for the publish job to succeed :) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ At this point our project will be staged for release. There is just one more step! &lt;/p&gt;

&lt;h3&gt;
  
  
  Approve the Deployment in Nexus
&lt;/h3&gt;

&lt;p&gt;Now that our project is staged for release we need to login to the OSSRH Nexus Repository Manager to promote the release. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login to the &lt;a href="https://s01.oss.sonatype.org/#welcome" rel="noopener noreferrer"&gt;OSSRH Sonatype Nexus Repository Manager&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;code&gt;Staging Repositories&lt;/code&gt; in the menu on the left hand side. &lt;/li&gt;
&lt;li&gt;Examine the contents of the release and if everything looks good &lt;code&gt;close&lt;/code&gt; the release. More information is available &lt;a href="https://central.sonatype.org/pages/releasing-the-deployment.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;The OSSRH deployment is now complete, but if this is your first release remember to go back and comment on your "New Project Ticket" we created earlier so your project will sync to Maven Central.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Deployment Complete!&lt;/p&gt;

&lt;h3&gt;
  
  
  Check out the deployed project!
&lt;/h3&gt;

&lt;p&gt;After ~24 hours head over to &lt;a href="https://search.maven.org/search" rel="noopener noreferrer"&gt;Maven Central's search&lt;/a&gt; and you should be able to find our project by typing in your groupId or artifactId. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5qv9l4mytvi5hv0nbjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5qv9l4mytvi5hv0nbjv.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Hope this was useful! Feel free to leave a comment if you have any questions :) &lt;/p&gt;

</description>
      <category>java</category>
      <category>maven</category>
      <category>github</category>
      <category>developers</category>
    </item>
    <item>
      <title>Getting Started with Spring Cloud Stream using Spring Initializr</title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Fri, 11 Sep 2020 15:02:04 +0000</pubDate>
      <link>https://dev.to/solacedevs/getting-started-with-spring-cloud-stream-using-spring-initializr-jnp</link>
      <guid>https://dev.to/solacedevs/getting-started-with-spring-cloud-stream-using-spring-initializr-jnp</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U_V0GPaC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/spring-cloud-featured-image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U_V0GPaC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/spring-cloud-featured-image.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://spring.io/projects/spring-cloud-stream"&gt;Spring Cloud Stream&lt;/a&gt; and Spring Initializr it is easier than ever to develop event-driven microservices. Even with partner-maintained binders like Solace PubSub+! If you’re not familiar with Spring Cloud Stream or Spring Initializr, this post will provide some quick background info as well as a tutorial so you can try it yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Spring Cloud Stream Framework&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There are a number of &lt;a href="https://spring.io/projects"&gt;Spring projects&lt;/a&gt; for building applications of all types. When developing scalable event-driven microservices, Spring Cloud Stream is often the framework of choice as it provides a flexible programming model and allows developers to create event-driven microservices without having to learn messaging APIs. Instead of learning messaging APIs, Spring Cloud Stream just requires developers to learn basic message-driven concepts such as publish-subscribe and consumer groups. The framework leverages cloud stream binders, which exist for several message brokers including Solace PubSub+, Apache Kafka, and RabbitMQ.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;PubSub+ and Spring Initializr&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Solace PubSub+ Spring Cloud Stream binder is automatically added to &lt;a href="https://start.spring.io/#!dependencies=solace,cloud-stream"&gt;Spring Initializr&lt;/a&gt; projects when you choose both the &lt;em&gt;Solace PubSub+&lt;/em&gt; and &lt;em&gt;Cloud Stream&lt;/em&gt; dependencies. For those who are not familiar with start.spring.io, it allows developers to generate Spring Boot projects pre-populated with the dependencies they need to get started quickly.&lt;/p&gt;

&lt;p&gt;There are a couple scenarios that could play out when generating a project with Solace PubSub+ as a dependency using Spring Initializr:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your dependencies include Solace PubSub+, but do not require a binder.&lt;/li&gt;
&lt;li&gt;Your dependencies include Solace PubSub+ AND Cloud Stream, which states that it requires a binder.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In scenario 1, Spring Initializr adds the solace-spring-boot-starter to your project. This starter allows you to use Spring Boot with either the Solace JMS API or the Solace Java API (JCSMP).&lt;/p&gt;

&lt;p&gt;In scenario 2, Spring Initializr realizes you’re trying to create a Spring Cloud Stream microservice and automatically includes the Solace Spring Cloud Stream Binder Starter in your project.&lt;/p&gt;

&lt;p&gt;Using Solace with Spring enables microservices created using the Spring ecosystem to communicate with both Spring and non-Spring applications across multi-cloud, hybrid-cloud, and no-cloud environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5-Minute Tutorial&lt;/strong&gt; &lt;strong&gt;(seriously, only 5 minutes)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Do you already have a JDK, Maven, and Docker installed? If so, it will only take you 5 minutes. &lt;strong&gt;Video evidence in this youtube video!&lt;/strong&gt; So, why not give it a try for yourself!&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/FWgkl3S1zA4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If for some reason you can’t use Docker, check out &lt;a href="https://codelabs.solace.dev/codelabs/spring-cloud-stream-basics/#0"&gt;this codelab&lt;/a&gt; for how to do it using PubSub+ Cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s Begin…
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Deploy a Solace PubSub+ Event Broker via Docker&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d -p 8080:8080 -p 55555:55555 -p:8008:8008 -p:1883:1883 
-p:8000:8000 -p:5672:5672 -p:9000:9000 -p:2222:2222 --shm-size=2g 
--env username\_admin\_globalaccesslevel=admin 
--env username\_admin\_password=admin 
--name=solace solace/solace-pubsub-standard
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;a href="https://start.spring.io/#!dependencies=solace,cloud-stream"&gt;start.spring.io&lt;/a&gt; and add the &lt;em&gt;Solace PubSub+&lt;/em&gt; and &lt;em&gt;Cloud Stream&lt;/em&gt; dependencies. Yes, that link added them for you 😜.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;em&gt;Generate&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unzip the downloaded zip file and import into your IDE as a Maven project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open &lt;em&gt;DemoApplication.java&lt;/em&gt; and add the following Spring bean&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Uppercasing: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;*&lt;/strong&gt;Save and Run &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to the &lt;em&gt;Try-Me!&lt;/em&gt; menu item in your local PubSub+ Manager which deployed with the Docker container in Step 1. Your username/password are admin/admin by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the Subscriber side, click &lt;em&gt;Connect&lt;/em&gt;, type &lt;code&gt;uppercase-out-0&lt;/code&gt; in the &lt;em&gt;Subscribe to a topic to receive direct messages&lt;/em&gt; box and click &lt;em&gt;Subscribe&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the Publisher side click &lt;em&gt;Connect&lt;/em&gt;, type &lt;code&gt;uppercase-in-0&lt;/code&gt; as the topic to publish to and click the &lt;em&gt;Publish&lt;/em&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boom! You’re done! Was that simple enough?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;*&lt;/strong&gt;You may be thinking, “What! No connection info needed?!” That is correct. By default, the Solace Binder knows how to automatically connect to the local docker container!&lt;/p&gt;

&lt;h2&gt;
  
  
  Behind the Scenes
&lt;/h2&gt;

&lt;p&gt;Okay, so you followed the steps above, but what exactly happened? Let me explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You deployed a Spring Boot microservice which contained a &lt;code&gt;java.util.function.Function&lt;/code&gt; bean in your code and both the cloud stream and a cloud stream binder as dependencies. This told Spring Boot that you wanted to create an event-driven microservice using Spring Cloud Stream.&lt;/li&gt;
&lt;li&gt;After Spring Boot realized you wanted a Cloud Stream microservice it knew it needed to create cloud stream bindings to exchange events with the available broker. So, based on your function name of &lt;em&gt;uppercase&lt;/em&gt;, it created the default input binding of &lt;code&gt;uppercase-in-0&lt;/code&gt;. The Solace Cloud Stream binder then subscribed to the &lt;code&gt;uppercase-in-0&lt;/code&gt; topic on the Solace PubSub+ Event Broker.&lt;/li&gt;
&lt;li&gt;When you published an event in the &lt;em&gt;Try-Me!&lt;/em&gt; tool, you published an event to the &lt;code&gt;uppercase-in-0&lt;/code&gt; topic on the Solace Broker that contained a payload of “Hello world!”&lt;/li&gt;
&lt;li&gt;Your microservice received this event via the binding previously set-up, identified the payload as a String type, and called your uppercase bean for processing which converted the payload of “Hello world!” to “HELLO WORLD!” and returned a String.&lt;/li&gt;
&lt;li&gt;Spring Cloud Stream included that returned String as the payload in an outbound message to the Solace Binder which in turn published it to the &lt;code&gt;uppercase-out-0&lt;/code&gt; topic on the Solace Broker.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;Try-Me!&lt;/em&gt; tool was then able to receive the processed message and display it to the screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What should you try next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Read about &lt;a href="https://solace.com/blog/asyncapi-codegen-microservices-using-spring-cloud-stream/"&gt;how to use AsyncAPI to generate a Cloud Stream app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn &lt;a href="https://www.solace.dev/start-spring-io-help/"&gt;how Solace works with Spring Initializr at start.spring.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Check out this &lt;a href="https://codelabs.solace.dev/codelabs/spring-cloud-stream-basics/#0"&gt;codelab&lt;/a&gt; for some more Cloud Stream Fundamentals and to extend what you did here with Function Composition:
&lt;/li&gt;
&lt;li&gt;Code for the open source Solace PubSub+ Spring Cloud Stream Binder can be found in the github repository.
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SolaceProducts"&gt;
        SolaceProducts
      &lt;/a&gt; / &lt;a href="https://github.com/SolaceProducts/solace-spring-cloud"&gt;
        solace-spring-cloud
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Supports all solace spring cloud products
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Watch &lt;a href="https://youtu.be/3iUGQL6Zc7U?t=1155"&gt;our recent Live Coding session&lt;/a&gt; featuring Oleg, a lead developer on the Spring Cloud Stream project.
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3iUGQL6Zc7U"&gt;
&lt;/iframe&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/getting-started-spring-cloud-stream-and-spring-initializr/"&gt;Getting Started with Spring Cloud Stream using Spring Initializr&lt;/a&gt; appeared first on the &lt;a href="https://solace.com"&gt;Solace Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>tutorial</category>
      <category>coding</category>
    </item>
    <item>
      <title>AsyncAPI Code Generation: Microservices Using Spring Cloud Stream</title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Tue, 28 Apr 2020 17:39:34 +0000</pubDate>
      <link>https://dev.to/solacedevs/asyncapi-code-generation-microservices-using-spring-cloud-stream-4cj2</link>
      <guid>https://dev.to/solacedevs/asyncapi-code-generation-microservices-using-spring-cloud-stream-4cj2</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Md8T8eTj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/blog-featured-image-asyncapi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Md8T8eTj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/blog-featured-image-asyncapi.jpg" alt=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Code generation is no simple feat. There are a lot of complexities when it comes to generating useful application code. In this post, I am going to walk you through generating your own microservices using Spring Cloud Stream and the AsyncAPI Code Generator. These tools should help to simplify things when defining and implementing your asynchronous applications. I explained the same idea in a video you can &lt;a href="https://solace.com/resources/pubsub-event-portal/asyncapi-code-generation-with-spring-cloud-stream"&gt;watch here&lt;/a&gt;, and all of the artifacts are &lt;a href="https://github.com/Mrc0113/asyncapi-codegen-scst"&gt;available in GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;AsyncAPI: What Is It?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before we dive into code generation let’s start with the basics – what is AsyncAPI? Over the past few years, &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI&lt;/a&gt; has emerged as the industry standard for defining asynchronous, event-driven APIs; you can think of it as OpenAPI for the asynchronous world. It is an open source initiative that provides &lt;u&gt;both&lt;/u&gt; a specification to describe and document your asynchronous applications in a machine-readable format, and tooling (such as code generators) to make life easier for developers tasked with implementing them.&lt;/p&gt;

&lt;p&gt;I’m not going to go into great detail about the specification, but for context you should know that it defines metadata about your asynchronous API, the channels available for sending/receiving messages, and components – such as schemas – that define the messages that are being exchanged. For more information about the specification you can read about it &lt;a href="https://www.asyncapi.com/docs/specifications/2.0.0/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Defining the Application That You Want to Develop: The  AsyncAPI Document&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The first step in doing code generation with AsyncAPI is obtaining an AsyncAPI document that defines the application that you want to develop. Per the specification, this document is represented as JSON objects and must conform to the JSON standards. YAML, being a superset of JSON, can also be used. There are two main ways of going about obtaining this document: manually create the document or use an event portal.&lt;/p&gt;

&lt;p&gt;If you decide to manually create the document after familiarizing yourself with the specification, don’t worry – you won’t be starting with a blank slate. The AsyncAPI initiative has provided a handy, interactive tool called the &lt;a href="https://playground.asyncapi.io"&gt;AsyncAPI playground&lt;/a&gt; to make this easier. On the left side of the playground you can familiarize yourself with the specification and make changes to a real AsyncAPI document, and as you do so the right side of the screen updates to show how the document is parsed into a more human-readable format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-01.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e0NiWDVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-01-1024x499.png" alt="asyncapi playground for creating microservices using spring cloud stream"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second way is to use an event portal. Solace PubSub+ Event Portal, for example, allows for architects and developers to collaborate using a GUI to design your event-driven architecture. The team would define the applications that exist in the system, as well as the events that are exchanged and the schemas which define them. Having a catalog of well-organized channels and events for reuse will also save you both time and headaches while collaborating, instead of having to comb through a bunch of files in various locations.&lt;/p&gt;

&lt;p&gt;Once the design is in place, PubSub+ Event Portal allows the developer to choose the application they are responsible for developing and download the AsyncAPI document in JSON or YAML.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;&lt;a href="https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-02.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z7oLuk1u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-02-1024x503.png" alt=""&gt;&lt;/a&gt; *&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Create Event-Driven Microservices Using Spring Cloud Stream Without Learning Messaging APIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have our AsyncAPI document that describes our application it’s time to develop the application. The AsyncAPI &lt;a href="https://github.com/asyncapi/generator"&gt;Code Generator&lt;/a&gt; supports templates to generate code for a variety of different languages and protocols, but for this example we’re going to use the &lt;a href="https://github.com/asyncapi/java-spring-cloud-stream-template"&gt;Spring Cloud Stream template&lt;/a&gt;. One should note that the template generates a Maven project.&lt;/p&gt;

&lt;p&gt;The Spring Cloud Stream framework provides an easy way to get started with event-driven microservices by providing binders that allow the developer to create their microservices without having to learn messaging APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Download and Run the AsyncAPI Generator&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The first step is of course to install the AsyncAPI generator itself. If you have NodeJS installed this takes just one easy &lt;code&gt;npm&lt;/code&gt; command as seen below. You can find the required versions in the &lt;a href="https://github.com/asyncapi/generator"&gt;Code Generator&lt;/a&gt; on github.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @asyncapi/generator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once you have the generator installed you can run it using the &lt;code&gt;ag&lt;/code&gt; command. At a minimum you must specify the AsyncAPI document to run it against and the template to use as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ag ~/AsyncApiDocument.yaml https://github.com/asyncapi/java-spring-cloud-stream-template.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In most cases you’ll want to take advantage of the parameters and specification extensions that are specified by the template being used. For example, the Spring Cloud Stream template that I’m using in this example allows me to &lt;a href="https://github.com/asyncapi/java-spring-cloud-stream-template#configuration-options"&gt;configure many options&lt;/a&gt;, including the Spring Cloud Stream binder I want to use – for example, the Solace binder.&lt;/p&gt;

&lt;p&gt;Other parameters include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maven information: &lt;code&gt;artifactId&lt;/code&gt; and &lt;code&gt;groupId&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Java package: &lt;code&gt;javaPackage&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Broker connection Info: &lt;code&gt;host&lt;/code&gt;, &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt; and &lt;code&gt;msgVpn&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using these options, my &lt;code&gt;ag&lt;/code&gt; command might look something like this, where &lt;code&gt;-o&lt;/code&gt; specifies the output directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ag -o ExpenseIntegration -p binder=solace -p view=provider -p actuator=true -p artifactId=ExpenseIntegration -p groupId=acme.rideshare -p javaPackage=acme.rideshare.expense -p host=localhost:55555 -p username=default -p password=default -p msgVpn=default ~/Downloads/ExpenseIntegration.yaml @asyncapi/java-spring-cloud-stream-template
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After running, the output will look something like this:&lt;br&gt;&lt;br&gt;
&lt;a href="https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-03.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TqMsS4iI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-03-1024x152.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Add Your Business Logic
&lt;/h2&gt;

&lt;p&gt;At this point the generator has created an &lt;code&gt;ExpenseIntegration&lt;/code&gt; directory that contains the Maven project. We can use the IDE of choice and import the Maven project to add business logic.&lt;/p&gt;

&lt;p&gt;As seen in the image below, once imported, the project looks like a regular Spring Boot Java project with generated classes under the &lt;code&gt;javaPackage&lt;/code&gt; that was defined earlier and an &lt;code&gt;application.yml&lt;/code&gt; file for configuration. Generated classes under &lt;code&gt;javaPackage&lt;/code&gt; include Plain Old Java Objects (POJOs) defined from the schemas in the AsyncAPI document and &lt;code&gt;Application.java&lt;/code&gt; which contains the actual Spring Cloud Functions where we’ll add our business logic.&lt;br&gt;&lt;br&gt;
&lt;a href="https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-04.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H5KL6r9m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/asyncapi-codegen_pic-04.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The generated POJOs, like &lt;code&gt;RideReceipt&lt;/code&gt; in the image above, define your data model per the schemas included in the AsyncAPI document. These POJOs contains variables with getters and setters for each attribute defined to allow both for developers to get coding quickly without having to manually create the objects themselves, but also for Spring Cloud Stream to automatically convert messages directly to POJOs.&lt;/p&gt;

&lt;p&gt;Then we have the &lt;code&gt;Application.java&lt;/code&gt; class, which can be renamed using the &lt;code&gt;javaClass&lt;/code&gt; parameter. The generator will add functions to handle messages delivered on the channels defined in the AsyncAPI document &lt;a href="https://github.com/asyncapi/java-spring-cloud-stream-template#how-it-works"&gt;as described in the template&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the example below we can see a single &lt;code&gt;java.util.function.Consumer&lt;/code&gt; bean since our AsyncAPI document describes our application as a subscriber to messages whose payload is defined by the &lt;code&gt;RideReceipt&lt;/code&gt; schema. Note the comment that states // Add business logic here; this is where the developer can add their business logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplicationpublic class Application {private static final Logger logger = LoggerFactory.getLogger(Application.class);public static void main(String[] args) {SpringApplication.run(Application.class);}@Beanpublic Consumer&amp;lt;RideReceipt&amp;gt; acmeRideshareBillingReceiptCreated001Consumer() {// Add business logic here.return null;}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You might say: “Marc, that’s great, but how the heck is that function actually binding to the messaging channels!?” This is where the &lt;code&gt;application.yml&lt;/code&gt; file comes into play.&lt;/p&gt;

&lt;p&gt;The generated &lt;code&gt;application.yml&lt;/code&gt; file defines several things as specified in the AsyncAPI document or from the parameters passed into the generator. First, it defines the list of functions it wants Spring Cloud Stream aware of under &lt;code&gt;spring.cloud.stream.function.definition&lt;/code&gt;. Second, it tells Spring Cloud Stream which channels to bind those functions to under &lt;code&gt;spring.cloud.streams.bindings&lt;/code&gt;. Lastly, it contains connection information to the messaging system. The connection info is specified by different parameters depending on the binder you choose but, in this case, it’s defined under &lt;code&gt;solace.java&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring: cloud: stream: function: definition: acmeRideshareBillingReceiptCreated001Consumer bindings: acmeRideshareBillingReceiptCreated001Consumer-in-0: destination: acme/rideshare/billing/receipt/created/0.0.1solace: java: host: 'localhost:55555' msgVpn: default clientUsername: default clientPassword: defaultlogging: level: root: info org: springframework: info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that all of this was done for the developer so they didn’t have to track down which SCSt parameters needed to be set, map the functions to the bindings, etc. They just have to add their business logic in place of the project and hit run! In this case since it’s a Spring Boot project you can “run as a Spring Boot app” in your IDE or even run from the command line using &lt;code&gt;mvn spring-boot:run&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Helpful Parameters and Specification Extensions for Creating Microservices Using the AsyncAPI Spring Cloud Stream Template&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As I mentioned, there are a lot of complexities when it comes to generating useful application code from a microservice. Because of these complexities, I thought I’d call out some tips, tricks, and painpoints of using the AsyncAPI Spring Cloud Stream template.&lt;/p&gt;

&lt;p&gt;There are a bunch of different parameters and specification extensions that you should consider when generating your code. All of them can be found &lt;a href="https://github.com/asyncapi/java-spring-cloud-stream-template#configuration-options"&gt;here&lt;/a&gt;, but I’ll go over a few of the parameters that I use quite often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;binder&lt;/code&gt; parameter&lt;/strong&gt; allows you to specify the Spring Cloud Stream binder that you’d like to use. Currently the generator supports &lt;code&gt;kafka&lt;/code&gt;, &lt;code&gt;rabbit&lt;/code&gt; and &lt;code&gt;solace&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;info.x-view&lt;/code&gt; specification extension&lt;/strong&gt; can be set at the info level in your AsyncAPI document. This extension allows for you to define how the document should be viewed from an application perspective. By default an AsyncAPI specification takes a &lt;code&gt;client&lt;/code&gt; view where operations (publish/subscribe) defined in a document represent what an application accepts (or how you would communicate with that application). However, for code generation you may want to  generate what an application actually does. This is where setting the &lt;code&gt;view&lt;/code&gt; parameter comes in. If you set &lt;code&gt;view&lt;/code&gt; to a value of &lt;code&gt;provider&lt;/code&gt;  the operations defined in the document will be treated as what an application actually does. Note that this extension can also be set using the &lt;code&gt;view&lt;/code&gt; parameter on some generator templates, such as the Java Spring Cloud Stream one. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;operation.x-scs-function-name&lt;/code&gt; specification extension&lt;/strong&gt; can be set on your &lt;code&gt;publish&lt;/code&gt; or &lt;code&gt;subscribe&lt;/code&gt; operations in the AsyncAPI document, allowing you not only to name the generated function, but also tie two operations together to form a function that subscribes to one channel and publishes to another when the same name is used. For example, if your AsyncAPI document looked like the image below a &lt;code&gt;java.util.function.Function&lt;/code&gt; bean called “calculatePercentage” would be generated which subscribes to the input channel and publishes to the output channel.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;channels: 'input': subscribe: x-scs-function-name: calculatePercentage message: $ref: '#/components/messages/CovidTracking\_SingleStateCurrentDataUpdate' 'output': publish: x-scs-function-name: calculatePercentage message: $ref: '#/components/messages/CovidTracking\_SingleStateTestPercentagesUpdate'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;x-scs-destination&lt;/code&gt; specification extension&lt;/strong&gt; can be specified on a &lt;code&gt;subscribe&lt;/code&gt; operation, allowing you to override the default destination value which usually matches the channel. This is useful when you are using the Solace binder and you are following the Solace pattern of publishing to topics and consuming from queues. In this case the &lt;code&gt;x-scs-destination&lt;/code&gt; value would be treated as the name of the queue which your microservice will consume from and the channel name in the AsyncAPI document will be added as a topic subscription to that queue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;x-scs-group&lt;/code&gt; specification extension&lt;/strong&gt; can also be specified on a &lt;code&gt;subscribe&lt;/code&gt; operation, allowing for the addition of a &lt;code&gt;group&lt;/code&gt; to the generated Spring Cloud Stream &lt;code&gt;binding&lt;/code&gt;. This allows for the use of consumer groups and will end up in a &lt;a href="https://dev.to/solacedevs/understanding-solace-endpoints-durable-vs-non-durable-53gd"&gt;durable queue&lt;/a&gt; being created when using the Solace binder.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Tips For Using The Code Generator To Create Event-Driven Microservices Using Spring Cloud Stream&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Besides configuration options there are a few more things to keep in mind when using the generator to create event-driven microservices using Spring Cloud Stream.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make sure generated POJOs have the Java types you would expect for generated variables!&lt;/strong&gt; For example, if your JSON schema defines an attribute type as a &lt;code&gt;number&lt;/code&gt; or &lt;code&gt;integer&lt;/code&gt; those are being mapped to a &lt;code&gt;Double&lt;/code&gt; or &lt;code&gt;Integer&lt;/code&gt; in Java respectively. If you would like another type, such as a float or long, you’ll want to make that change. It is also important to make sure you pay close attention to data that represents dates and/or times as those will likely end up just being represented by a &lt;code&gt;String&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;Dynamic topics are not yet supported by the AsyncAPI SCSt Code Generator. We’ll be looking to enhance them both to support dynamic topics in the future but for now you’ll want to remove dynamic pieces of the topic from your channels in the AsyncAPI document and add them into the code afterwards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When creating a Spring Cloud Stream microservice that does &lt;em&gt;not&lt;/em&gt; contain a &lt;code&gt;java.util.function.Supplier&lt;/code&gt; include a web server so the microservice continues running and listening for messages to process.&lt;/strong&gt; This can be done by including the &lt;code&gt;-p actuator=true&lt;/code&gt; parameter to include Spring Actuator functionality which itself requires a web server, and also provides some cool management and monitoring capabilities. Alternatively, you can just add the &lt;code&gt;spring-boot-starter-web&lt;/code&gt; starter to your pom after it’s been generated. Note this is not an issue with the AsyncAPI generator template, but just a bug with the Solace Spring Cloud Stream binder which will be relevant to people using the generator.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope those tips are helpful and save you some troubleshooting time!&lt;/p&gt;

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

&lt;p&gt;I hope this post was useful and you’re able to quickly dive in to generating your own event-driven microservices using Spring Cloud Stream and the AsyncAPI Code Generator after exploring the example described above.&lt;/p&gt;

&lt;p&gt;You can get started right away and use the Solace PubSub+ Event Portal to generate your AsyncAPI document for FREE by signing up for a &lt;a href="https://console.solace.cloud/login/new-account"&gt;new cloud account&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;If you have more questions or want to share your experience with the tools, you can let us know in the &lt;a href="http://solace.community/"&gt;Solace Community Forum&lt;/a&gt; or consider joining us in contributing directly to the AsyncAPI initiative.&lt;/p&gt;

&lt;p&gt; &lt;a href="" class="article-body-image-wrapper"&gt;&lt;img alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/asyncapi-codegen-microservices-spring-cloud-stream/"&gt;AsyncAPI Code Generation: Microservices Using Spring Cloud Stream&lt;/a&gt; appeared first on &lt;a href="https://solace.com"&gt;Solace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>solace</category>
      <category>asyncapi</category>
      <category>java</category>
      <category>spring</category>
    </item>
    <item>
      <title>Why Developers Need an Event Portal; Creating Applications that Disseminate Real-Time COVID-19 Data</title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Fri, 03 Apr 2020 13:24:27 +0000</pubDate>
      <link>https://dev.to/solacedevs/why-developers-need-an-event-portal-creating-applications-that-disseminate-real-time-covid-19-data-1864</link>
      <guid>https://dev.to/solacedevs/why-developers-need-an-event-portal-creating-applications-that-disseminate-real-time-covid-19-data-1864</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---nTo3Opo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/blog-featured-image-pubsubplus-event-portal.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---nTo3Opo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/04/blog-featured-image-pubsubplus-event-portal.jpg" alt=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As developers, we are asked to create software that solves hard problems in a way that’s scalable, secure, and can be modified as needs evolve – all with deadlines expressed in terms of how long ago they wish they’d had this. Does “We need this yesterday!” ring a bell? Things change so quickly these days, in business and the world at large, that the applications we deliver need to help people achieve positive outcomes very quickly, based on the latest information. That’s where event-driven architecture comes in.&lt;/p&gt;

&lt;p&gt;Letting applications produce, consume, and act on information that’s sent to and fro based on user actions and changes in condition (i.e. “events”) instead of periodic request/reply polling, makes it possible to identify and act on opportunities as they emerge, in real-time, instead of looking at them in the rear-view mirror.&lt;/p&gt;

&lt;p&gt;Event driven architecture presents developers with some interesting challenges throughout the development process. These challenges include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to capture the design and collaborate with the architects&lt;/li&gt;
&lt;li&gt;How to implement the design in a simple and consistent way&lt;/li&gt;
&lt;li&gt;How to understand the flow of information from an operational perspective in order to alert and solve problems&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’d like to explain these challenges in terms of how they’re addressed today, and how they can be dealt with now, thanks to our new product &lt;a href="https://solace.com/products/portal/"&gt;PubSub+ Event Portal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I find that using an example is the best way to expose challenges and solutions, so I’ll frame my explanation in terms of a project some colleagues and I took on last week. Simply put, we used PubSub+ Event Portal to create event streams related to the COVID-19 pandemic so those looking to report on, track, or help with the pandemic could do so with access to real-time information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an Application to Provide Real-Time COVID-19 Data
&lt;/h2&gt;

&lt;p&gt;Lots of developers out there are looking to do their part by helping government agencies, journalists, and – most importantly – scientists and public health authorities process and analyze data related to the COVID-19 pandemic. We decided to help them do so by making it easier to overcome the first challenge each of them faces – how to access the data and understand what it looks like.&lt;/p&gt;

&lt;p&gt;Historically, architects have used tools like Confluence and PowerPoint, etc. to describe and document the design of events, applications, and data flow we’re being asked to implement. This can be challenging for a variety of reasons, leaving us asking questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where do I connect?&lt;/li&gt;
&lt;li&gt;What are the payload schemas so I can serialize/deserialize the data?&lt;/li&gt;
&lt;li&gt;Where do I send the output of my newly created application/microservice?&lt;/li&gt;
&lt;li&gt;If I’m using an event generated outside of my team, who do I contact for more info?&lt;/li&gt;
&lt;li&gt;What do I do if the documentation gets stale?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;API Management solutions like Mulesoft provide a great experience for Synchronous RESTful interactions, but there isn’t an equivalent for event-driven or streaming interactions. Well, there &lt;em&gt;wasn’t&lt;/em&gt;, anyway. We at Solace felt your pain and have come up with a solution that overcomes some of the challenges described above so developers like us can get the answers we need. Our product PubSub+ Event Portal is the first solution that lets you collaboratively create and manage events and event-driven applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Collaborative Design and Documentation
&lt;/h3&gt;

&lt;p&gt;Getting back to the COVID-19 project, our first step was to document the design. Our Architect colleague (Jonathan Schabowsky, who wrote about his experiences here), kicked off the project by identifying the data source we would access (Johns Hopkins &lt;a href="https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6"&gt;CSSE&lt;/a&gt;) and the applications we would need to acquire the raw data, look for changes, and publish smaller, more fine-grained events that represent changes to regions or cases so the community can consume just the state changes they‘re interested in.&lt;/p&gt;

&lt;p&gt;They design the system they envisioned with Solace PubSub+ Event Portal so we, as developers, could understand and make comments. For example, we had some interesting discussions around how the topic hierarchy would work and how to apply &lt;a href="https://solace.com/blog/topic-hierarchy-best-practices/"&gt;best practices&lt;/a&gt;. In addition, we collectively decided to split up the logic into different Spring Boot microservices so they were more purpose-specific and manageable. All these changes were decided upon in Slack meetings, and updates were made in the event portal. It was awesome to be able to collaborate, make updates, and be in sync before we even started to write code.&lt;/p&gt;

&lt;p&gt;The architecture was kept up to date in the event portal as we implemented it so we could easily provide the COVID-19 data feeds to the technical community. Collaboration and design documentation: Check!&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple, Consistent Development
&lt;/h3&gt;

&lt;p&gt;Moving beyond collaboration and documentation, one of the biggest pains I experience as a developer advocate at Solace is taking the design, topic hierarchy, asynchronous API (JMS, Solace, Spring Cloud Stream, Paho, etc.) and consistently developing applications.&lt;/p&gt;

&lt;p&gt;These problems don’t come up with REST because OpenAPI provides a machine-readable API specification that lets code generators create a client (API consumer) or server (API provider) that adheres to the spec. This ensures consistent code, conformance to the design, and a simple development experience. Once again, the event-driven world hasn’t had anything like this… until now!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI&lt;/a&gt; is a machine-readable specification for event-driven applications that also provides code generators. We at Solace recently contributed a Spring Cloud Stream code generator for AsyncAPI and PubSub+ Event Portal supports the exportation of AsyncAPI files that represent the asynchronous application interfaces.&lt;/p&gt;

&lt;p&gt;Going back to the usage, our architect designed the event-driven interactions within our event portal and assigned us different microservices to implement. Once we exported the AsyncAPI file for each application, we ran the code generator, reviewed the data models, made small tweaks, and added the business logic (like splitting the data by cases or regions) we had running.&lt;/p&gt;

&lt;p&gt;Consistent and scalable microservices within minutes –a huge step forward for developers!&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s going on with my application?
&lt;/h3&gt;

&lt;p&gt;It’s not all sunshine and roses though, and as the philosophy of DevOps has become the norm we as developers increasingly own the applications throughout their lifecycle. Not only do we design and implement applications, but we also have a hand in deploying, monitoring, and managing them. This includes troubleshooting and resolving problems when the inevitable rainy day occurs. Although we try to avoid bugs, they always seem to show up eventually. The challenge is that when problems pop up we need to be able to efficiently identify the cause and push out a fix.&lt;/p&gt;

&lt;p&gt;This has been a problem with event driven architecture for ages. The decoupling of applications, while it provides many advantages, makes it hard to trace the flow of events through the system. All we hear is, “Where did my message go?” and we have to start tracking and tracing to figure out where the “hose” got kinked – application failed, data parsing issue, what have you.&lt;/p&gt;

&lt;p&gt;So, it’s after hours and you’re hunting down that pesky design document you last reviewed 6 months ago… #badmoment. You find it, realize it has not been updated, and wonder if it’s even up to date: #worsemoment! The point is, we can now use PubSub+ Event Portal to understand the implementation, know where to look for problems, and diagnose them without the stress and anxiety of having to “reverse engineer” the implementation.&lt;/p&gt;

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

&lt;p&gt;I get that sometimes it feels like you could add another tool to your development environment every day, but if you’re developing event-driven applications development, Solace PubSub+ Event Portal is a no brainer. Seeing as how it helps with documentation (which isn’t personally my favorite part of being a developer), automates code generation, and lets you see what’s going on in the production environment, the benefits for developers like you and me are enormous. Take it for a spin on your next event-driven application project and see for yourself! I’m confident you’ll be glad you did.&lt;/p&gt;

&lt;p&gt;From everyone at Solace, we would like to thank everyone out there working to alert and inform the public during this pandemic. You are truly our heroes!&lt;/p&gt;

&lt;p&gt;If there is a project or event-driven application you have in mind, we encourage you to &lt;a href="https://console.solace.cloud/login/new-account"&gt;try PubSub+ Event Portal&lt;/a&gt;. We’d love to see what you can do with this toolset and are eager to receive any feedback you may have on our product.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zu3zZEuq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://play.vidyard.com/1Jj1gVkqNwZRWF7oVwoJgA.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zu3zZEuq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://play.vidyard.com/1Jj1gVkqNwZRWF7oVwoJgA.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/why-developers-need-event-portal/"&gt;Why Developers Need an Event Portal; Creating Applications that Disseminate Real-Time COVID-19 Data&lt;/a&gt; appeared first on &lt;a href="https://solace.com"&gt;Solace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>solace</category>
      <category>pubsub</category>
      <category>eventportal</category>
      <category>asyncapi</category>
    </item>
    <item>
      <title>Reflecting on my First Hackathon</title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Thu, 20 Feb 2020 20:16:59 +0000</pubDate>
      <link>https://dev.to/mrc0113/reflecting-on-my-first-hackathon-4g9g</link>
      <guid>https://dev.to/mrc0113/reflecting-on-my-first-hackathon-4g9g</guid>
      <description>&lt;h2&gt;
  
  
  The Hackathon: MakeUofT
&lt;/h2&gt;

&lt;p&gt;This past weekend I attended my first hackathon (well a make-a-thon in this case) as a sponsor and mentor since starting my role as a Developer Advocate. I have to admit that going in I had pretty low expectations. I was traveling from Orlando, FL to Toronto, Ontario on a holiday weekend to what I thought would be a pretty boring booth duty gig, and then to judge some projects that after only 24 hours of work would be half thought out and &lt;em&gt;maybe&lt;/em&gt; partially working, if at all. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gOtCLFWr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/vp56rg9vnniea5jr9ahv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gOtCLFWr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/vp56rg9vnniea5jr9ahv.png" alt="Makeathon" width="719" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, the weekend has come and gone and wow was I wrong. MakeUofT not only surprised me, but it absolutely blew my mind and reminded me how far technology has come in the past decade. All while being a blast to participate in. According to their website, MakeUofT, at the University of Toronto, is Canada's Largest Makeathon and is a Major League Hacking member event. It brought together teams of students from across North America for a weekend of hacking and creativity. And not just software hacking, the event had a wide variety of hardware available for participants to use which ranged from Raspberry PIs to Qualcomm Dragonboards, sensors, cameras, 3D printers and more. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H_cKRvPi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/bk2gfdrtbamgjcwj7nm9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H_cKRvPi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/bk2gfdrtbamgjcwj7nm9.jpg" alt="Raspberry PI" width="525" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  My Reflection
&lt;/h3&gt;

&lt;p&gt;So why was I so surprised? As a software engineer for the past decade I knew in my mind that we have had many technological advances, but I think it's natural to see and assess them one by one as they happen. Raspberry PI became a thing, the cloud became the way to go, software as a service became the new norm, etc. And I started to research and use subsets of each of the advances one at a time as my projects called for it, e.g:  at my previous company my team replaced physical racks of servers with AWS, used the Atlassian SaaS ecosystem to manage and track the software development process and went from installing &amp;amp; configuring proven software, such as the Elastic Stack and MongoDB to using their SaaS offerings. However, seeing how quickly the hackathon teams were able to go from idea to architecture to mostly working proof of concepts made me step back and really see all the technological advances as a whole. What many teams accomplished would have been nearly impossible just 10 short years ago.  &lt;/p&gt;

&lt;p&gt;Of course it helps that the students were super tech savvy. With most of them probably being born after the dot-com bubble in the late 1990s they likely never knew a time without computers and it showed. All of the teams that I helped mentor were really sharp: they knew their way around their IDEs and code in general, were able to quickly pick up on new technical concepts, slap together some code and see it run. On top of the extra tech savviness, the advancements that I mentioned above are the &lt;em&gt;baseline&lt;/em&gt; for them. They expect to be able to just sign up for a service like Solace PubSub+, have it "just running", and use it to stream events immediately; whereas my first experience with that same Solace technology about ~9 years ago was to navigate the website, contact the sales team, have some meetings to determine feasibility, have hardware shipped, rack and stack the hardware, cable it up and get it added to the network, configure security &amp;amp; access control, and probably some other steps I'm forgetting about before I could even get around to using it. What took me probably a few weeks at an absolute minimum now takes them 5 minutes!&lt;/p&gt;

&lt;p&gt;And why was my mind blown? The projects were amazing. Way better than I expected. And in many cases they actually worked 🤯!? Not just the software, but the hardware as well. The students really took advantage of the speed of technology in 2020. They knew that they could develop their proof of concepts quickly so they took their time at the beginning of the event to create well thought out ideas and a feasible architecture instead of just diving into the implementation. A large percentage of the teams even started to think about a potential business plan for where they could take their ideas beyond the event itself! At the end of the 24 straight hours of hacking (yes, very few of the students took time out to sleep) teams set up their projects in the main auditorium where they hosted science fair style demonstrations and judges, mentors and participants got to go around and see what the teams came up with. Seeing the demos was an absolute blast and there was definitely excitement in the air as you looked around and saw everything from drones and rovers to robotic arms and intelligent trash receptacles. If you want to check out some of the projects you can find them on DevPost &lt;a href="https://makeuoft-2020.devpost.com/submissions/search?utf8=%E2%9C%93&amp;amp;prize_filter%5Bprizes%5D%5B%5D=35080"&gt;here&lt;/a&gt; which I've also shown an image of below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xWECCA75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/jue4sy4ld7nhefn3g68u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xWECCA75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/jue4sy4ld7nhefn3g68u.png" alt="MakeUofT Projects" width="638" height="1014"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Business Value of a Hackathon
&lt;/h3&gt;

&lt;p&gt;At the end of the weekend it's great that I had a good time this weekend, but let's face it, our companies don't sponsor events for us to have a good time. So what do companies get out of sponsoring hackathons? &lt;/p&gt;

&lt;p&gt;First and foremost we get to support the up and coming developer community while raising awareness at the same time. It was a pleasure to work with these students and see them begin to bring their ideas to life while also helping them learn about event-driven development and using our companies' product to do so. &lt;/p&gt;

&lt;p&gt;This awareness has multiple benefits: It shows students that your company not only exists, but that it cares about the developer community. These types of events attract the best and brightest up and coming students and this is an excellent away to help identify them and hopefully add them to your team. The awareness also gets students using your technology, and hopefully, pending a good experience, they will continue to use your companies' technology for future projects as well. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UUKKEuHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/vs2uw3yc3f856odo8ohn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UUKKEuHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/vs2uw3yc3f856odo8ohn.jpg" alt="MakeUofT Booth" width="600" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another great reason for companies to sponsor hackathons is to get candid developer feedback. The students participating in these hackathons are there to have fun and learn, but most of them also want to win. This means they have a short period of time to create something really awesome that will help set their project apart. As sponsors they are going to use your companies' technology and they expect it to work. They expect to get started fast and be able to use it to accomplish what you told them it is meant to achieve. They aren't just going to take a look at some sample code, walk through a tutorial and nod their head. They're going to really dig into the code, pull pieces out and use it to create their project. If there is confusion or speed bumps in your getting started experience they'll find it! &lt;/p&gt;

&lt;p&gt;For this reason alone I would highly recommend any Developer Advocate or for that matter anyone who "owns" an API get your company to sponsor a hackathon. On this note, don't be afraid to ask for feedback. When going around to judge the "Best use of Solace PubSub+" prize I asked each team that used our technology about their experience. Was it enjoyable? Would they use it again? Did they have any pain points? It's not everyday that you get a chance to collect this much feedback in person so don't pass it up!&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank You!
&lt;/h3&gt;

&lt;p&gt;After such a great weekend I'm definitely looking forward to the next time I'll get to participate in a hackathon! &lt;strong&gt;Thank you to the University of Toronto IEEE and Major League Hacking for putting on MakeUofT, as well as to the sponsors that made it possible: &lt;a href="https://solace.com"&gt;Solace&lt;/a&gt;, Telus, Qualcomm and Huawei, among others. And last, but definitely not least, thank you to the students for coming out with such great energy and dedication.&lt;/strong&gt;  &lt;/p&gt;

</description>
      <category>devrel</category>
      <category>community</category>
      <category>hackathon</category>
    </item>
    <item>
      <title>Spring Initializr, Meet Your Perfect Match for Event-Driven Microservices: PubSub+</title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Wed, 06 Nov 2019 22:27:35 +0000</pubDate>
      <link>https://dev.to/solacedevs/spring-initializr-meet-your-perfect-match-for-event-driven-microservices-pubsub-3kic</link>
      <guid>https://dev.to/solacedevs/spring-initializr-meet-your-perfect-match-for-event-driven-microservices-pubsub-3kic</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bMt7Z8K1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/solace-default-blog-thumbnail-600x285.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bMt7Z8K1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/solace-default-blog-thumbnail-600x285.jpg" alt="Further thoughts on FPGA co-processing and performance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re not familiar with start.spring.io, it hosts the Spring Engineering team’s opinionated version of Spring Initializr, which allows developers to generate Spring Boot projects pre-populated with the dependencies they need to get started quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spring Developer Advocate Josh Long calls start.spring.io the “second-best place on the internet,”&lt;/strong&gt; and it just got better! Why do I say that? Because Solace PubSub+ is now available on start.spring.io, enabling developers to create event-driven microservices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4KtG2fxs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/11/didyouknow-springone.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4KtG2fxs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/11/didyouknow-springone.png" alt="Did you know that devs use Start.Spring to generate 15mil projects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a developer who has been creating event-driven applications with a combination of the Spring Framework and Solace PubSub+ for about eight years, I love how the developer experience keeps improving. This is the next step.&lt;/p&gt;

&lt;p&gt;When selected as a dependency on Initializr at start.spring.io, the `Solace PubSub+’ option informs Initializr to add the Solace JMS Spring Boot Starter to the maven pom or build.gradle file as a dependency. This enables autoconfiguration of a &lt;em&gt;ConnectionFactory&lt;/em&gt; or &lt;em&gt;JndiTemplate,&lt;/em&gt; allowing developers to use Spring Boot to easily create event-driven microservices with PubSub+ and the JMS API. Using PubSub+ to create event-driven microservices empowers developers to use the best message exchange patterns for their use case, such as publish/subscribe, queuing, request/reply and it even provides the ability to &lt;a href="https://docs.solace.com/Configuring-and-Managing/Msg-Replay-Video.htm#Video:"&gt;store &amp;amp; replay&lt;/a&gt;. The use of PubSub+ also allows developers to take advantage of all the benefits of having events flow over the Event Mesh, such as being able to communicate with applications using other APIs and protocols and built-in high availability and disaster recovery.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
&amp;lt;dependency&amp;gt;&lt;br&gt;
 &amp;lt;groupId&amp;gt;com.solace.spring.boot&amp;lt;/groupId&amp;gt;&lt;br&gt;
 &amp;lt;artifactId&amp;gt;solace-jms-spring-boot-starter&amp;lt;/artifactId&amp;gt;&lt;br&gt;
 &amp;lt;version&amp;gt;3.2.0&amp;lt;/version&amp;gt;&lt;br&gt;
&amp;lt;/dependency&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Want to give it a shot? Spring Initializr offers several ways to generate your Spring Boot project. You can do it using the Web UI, from your favorite IDE or even from the command-line.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web:&lt;/strong&gt; Use this link to &lt;a href="https://start.spring.io/#!dependencies=solace"&gt;spring.io&lt;/a&gt; to use the Initializr Web UI, and yes it even offers a dark mode! You can choose your project type (Maven or Gradle), programming language, project dependencies and more. You’ll find the Solace PubSub+ dependency by looking under the “Messaging” section, searching for “solace” or if you use the link above, we’ve pre-populated the Solace PubSub+ dependency for you ;). Once you’ve made your choices, click the &lt;em&gt;Generate&lt;/em&gt; button to download a zip file of your Spring Boot project.
&lt;a href="https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-1.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vYz4xKch--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-1.png" alt=""&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IDE:&lt;/strong&gt; You can also create Spring Boot projects from your favorite IDE. These IDEs currently support Initializr: Spring Tool Suite, IntelliJ IDEA Ultimate, NetBeans (with &lt;a href="https://github.com/AlexFalappa/nb-springboot"&gt;this plugin&lt;/a&gt;) or VSCode (with &lt;a href="https://github.com/microsoft/vscode-spring-initializr"&gt;the vscode-spring-initializr plugin&lt;/a&gt;). Which Initializr do you think they use by default? If you guessed the one at start.spring.io, you’re correct.
For example, when using the Spring Tool Suite IDE for development, you can create a new &lt;em&gt;Spring Starter Project&lt;/em&gt; and under the covers Initializr will generate your project. Check out the options available in the image below.
&lt;a href="https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-2.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kBdTVt4M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-2.png" alt=""&gt;&lt;/a&gt;
After choosing those initial options and selecting &lt;em&gt;Next,&lt;/em&gt; you will be asked to choose dependencies. You’ll find Solace PubSub+ under the &lt;em&gt;Messaging&lt;/em&gt; dropdown. Choose it, click &lt;em&gt;Finish,&lt;/em&gt; and a Spring Boot project is generated right in your IDE.
&lt;a href="https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-3.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Lwhuwii--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-3.png" alt=""&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI:&lt;/strong&gt; Not a fan of a GUI? No worries, you can generate Spring Boot projects from the command line as well. For example, if you want to generate a zip file containing a project with Java 11 and Solace PubSub+ as a dependency, you could execute:
&lt;code&gt;curl https://start.spring.io/starter.zip -d dependencies=solace -d javaVersion=11 -o demo.zip&lt;/code&gt;
Or to see all available options, execute &lt;code&gt;curl -XGET https://start.spring.io&lt;/code&gt; as seen in the image below.
&lt;a href="https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-4.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bDZYueqq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/11/spring-initialzr-blog-post_image-4.png" alt=""&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you’ve used Spring Initializr to generate your Spring Boot project with Solace’s Spring Boot JMS Starter as a dependency, it’s time to code your event-driven microservice. You can learn more about using our Spring Boot JMS Starter using the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog: &lt;a href="https://solace.com/blog/solace-jms-meet-spring-boot-starters/"&gt;https://solace.com/blog/solace-jms-meet-spring-boot-starters/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tutorial: &lt;a href="https://solace.com/samples/solace-samples-spring/spring-boot-autoconfigure/"&gt;https://solace.com/samples/solace-samples-spring/spring-boot-autoconfigure/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any questions, feel free to ask them in the &lt;a href="https://solace.dev/"&gt;Solace Developer Community&lt;/a&gt; with the &lt;code&gt;Spring&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;And if you love start.spring.io so much that you want to learn more about how it works, watch &lt;a href="https://twitter.com/snicoll"&gt;Stéphane Nicoll&lt;/a&gt;’s talk from SpringOne Platform 2019: &lt;a href="https://www.youtube.com/watch?v=YVF08E7Xd_Y&amp;amp;list=PLAdzTan_eSPRlQ8t4TU5c-AB4SHV939M6&amp;amp;index=134"&gt;Creating “The Second Best Place on the Internet” with Spring Initializr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Spring + Solace developer experience has come a long way in the last eight years and I’m excited to see it continuously improve. Check out &lt;a href="https://www.solace.com/spring"&gt;solace.com/spring&lt;/a&gt; to see all the ways you can use Spring with Solace and stay tuned for more upcoming Spring + Solace news.&lt;br&gt;&lt;br&gt;
Hint: SolaceYSpring &amp;amp; SolaceY&lt;a href="https://asyncapi.com/"&gt;AsyncAPI&lt;/a&gt;. Until next time, Happy Eventing!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/solace-pubsub-spring-initializr/"&gt;Spring Initializr, Meet Your Perfect Match for Event-Driven Microservices: PubSub+&lt;/a&gt; appeared first on &lt;a href="https://solace.com"&gt;Solace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>solace</category>
      <category>spring</category>
      <category>microservices</category>
      <category>java</category>
    </item>
    <item>
      <title>Considerations for Developers Building Event-Driven Microservices </title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Mon, 19 Aug 2019 12:00:31 +0000</pubDate>
      <link>https://dev.to/solacedevs/considerations-for-developers-building-event-driven-microservices-47d8</link>
      <guid>https://dev.to/solacedevs/considerations-for-developers-building-event-driven-microservices-47d8</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o43JgGuW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2018/12/advanced-event-broker.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o43JgGuW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2018/12/advanced-event-broker.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;A while back my colleague Jonathan Schabowsky recently wrote a paper called &lt;em&gt;&lt;a href="https://solace.com/blog/event-driven-microservices/"&gt;The Architect’s Guide to Event-Driven Microservices&lt;/a&gt;&lt;/em&gt; that’s turned out to be very popular, and for good reason. In it he explains the benefits of combining event-driven architecture and microservices, and candidly describes how decomposing applications admittedly makes life a little more…as he put it…”interesting.” With this post I’ll summarize the elements of the architectural view that are most important for developers to know as they build event-driven application and microservices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are You Ready to Develop for EDA?
&lt;/h2&gt;

&lt;p&gt;Many organizations migrate to microservices for one reason: Agility. The ability to very quickly create and modify components in a way that offers bottom line business value is mission critical in a world where your competitors are a click away and time to market is everything. So, you’re a developer and you have been tasked with delivering on this migration…what do you need to know to be successful?&lt;/p&gt;

&lt;p&gt;The first thing to understand is &lt;a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing"&gt;the fallacies of distributed computing&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The network is reliable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Latency is zero&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Bandwidth is infinite&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The network is secure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Topology doesn’t change&lt;/li&gt;
&lt;li&gt;There is one administrator&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transport cost is zero&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The network is homogeneous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They’re all relevant, but I’ve bolded the ones that are especially important in the world of microservices, because the smaller you make each microservice, the larger your service count, the more the fallacies of distributed computing impact stability and user experience/system performance.&lt;/p&gt;

&lt;p&gt;The challenge is that microservices require connectivity/data in order to perform their roles and provide business value, and data acquisition/communication has been largely ignored, so much so that the tooling has severely lagged behind. For example, API management/gateway products only support synchronous, request/reply exchange patterns, which when coupled with the fallacies noted above exacerbates the challenges of distributed computing. Many of these challenges can be minimized by properly implementing an Event-Driven Architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Think Event-Driven
&lt;/h2&gt;

&lt;p&gt;Unlike service-oriented design, which are synchronous and blocking, event-driven design is non-blocking and uses lots of &lt;a href="https://en.wikipedia.org/wiki/Callback_(computer_programming)"&gt;callbacks&lt;/a&gt;. Event-driven design is not a new concept, and you may even be familiar with it from using programming patterns such as the “&lt;a href="https://en.wikipedia.org/wiki/Reactor_pattern"&gt;Reactor Pattern&lt;/a&gt;” or the “&lt;a href="https://en.wikipedia.org/wiki/Observer_pattern"&gt;Observer Pattern&lt;/a&gt;” which is one of the “Gang of Four” design patterns. The concepts used by these programming patterns can be applied to event-driven microservice architectures using architectural patterns, such as Publish-Subscribe, to achieve service decoupling, independent scalability, and one-to-many bi-directional communications.&lt;/p&gt;

&lt;p&gt;The first step towards adopting the event-driven mindset is to change the way you think about designing and architecting solutions. Initially the tendency is to think about all interactions between services as a series in a sequence of request/ reply service calls. In fact, if you or your team uses the terminology of “invoking,” “requesting,” or “calling” then it is a sure sign you are still thinking in the request/reply paradigm.&lt;/p&gt;

&lt;p&gt;Instead, try these: “What events should my service process?” and “What events will my service emit?”&lt;/p&gt;

&lt;h3&gt;
  
  
  Stop Orchestrating, Start Choreographing
&lt;/h3&gt;

&lt;p&gt;Once you adopt event-driven thinking, you need to make the shift from orchestration to choreography.  It is common for developers to think in terms of “service A will call service B which will call service C” and then implement that model through a chain of invocations (a-&amp;gt;b&amp;gt; c) or by creating an orchestrator service such that x-&amp;gt;a, then x-&amp;gt;b, then x-&amp;gt;c.  Both approaches will cause chaos when the realities of distributed computing kick in, especially when you start to scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2019/08/dev-considerations-eda_image-1.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4lmf4ljA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/dev-considerations-eda_image-1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thoughtworks.com/insights/blog/scaling-microservices-event-stream"&gt;Orchestration vs. Choreography, Source: Thoughtworks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The alternative is to follow the philosophy of choreography. Services should react to changes in their environment and the benefits are immense:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better agility: Agile development teams are more independent and are significantly less impacted by changes to other services.&lt;/li&gt;
&lt;li&gt;Services are smaller/simpler: Each service is not required to have complex error handling for downstream service or network failures. Who likes writing error handling??? Not me!&lt;/li&gt;
&lt;li&gt;Less service coupling: Services have no knowledge about the existence of other services.&lt;/li&gt;
&lt;li&gt;Enables fine-grained scaling: Each service can be independently scaled up or down based on demand. This ensures a good user experience and is less wasteful of compute resources.&lt;/li&gt;
&lt;li&gt;Easy to add new services: Due to less coupling, a new service can come online, consume events and implement new functionality without changes to any other service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This list of benefits doesn’t come for free; there is no silver bullet…&lt;/p&gt;

&lt;p&gt;Consistency of state then becomes an area of focus, because a service, being temporarily down, means that the event state changes may not be processed immediately. Fundamentally, how do we deal with this negative side effect?&lt;/p&gt;

&lt;h3&gt;
  
  
  Embrace Eventual Consistency
&lt;/h3&gt;

&lt;p&gt;Eventual consistency is the idea that consistency will occur in the future, and it means accepting that things may be out of sync for some time. It’s a pattern and concept that lets developers avoid using nasty XA transactions. It’s the job of the eventing/messaging platform to ensure that these domain change events are never lost before being appropriately handled by a service and acknowledged.&lt;/p&gt;

&lt;p&gt;Some think the only benefit of eventual consistency is performance, but the real advantage is the decoupling of the microservices since individual services are merely acting upon events that they are interested in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pick an Event-Driven Microservices Development Framework
&lt;/h3&gt;

&lt;p&gt;As developers, we want the ability to easily write clean code which enables us to deliver functionality quickly. Thus, the development language and associated tooling becomes important. While event-driven architectures allow us to decouple our microservices and choose different technologies to implement each one it is recommended to choose a standard language/framework that best fits your team’s skill sets and deviate only when necessary.&lt;/p&gt;

&lt;p&gt;For many organizations this skill set includes experience using the Spring Framework with Java (and other Spring supported, JVM-based languages). This experience has led to Spring Boot becoming the most popular framework for building microservices. Its adoption continues to grow and best of all, it has built in support for event-driven microservices through &lt;a href="https://spring.io/projects/spring-cloud-stream"&gt;Spring Cloud Streams&lt;/a&gt;. Spring Cloud Streams is a framework for building highly scalable, event-driven microservices connected using shared event brokers. On top of providing an implementation framework, Spring Cloud Streams also defines vendor agnostic terminology for the event-driven community, including defining &lt;em&gt;source _and _sink _applications that send or receive events over _channels&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2019/08/spring-cloud-streams-architecture.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--267dwCht--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/spring-cloud-streams-architecture-1024x481.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;While event-driven microservices may seem difficult initially, they are the future of most microservices and IT strategies. Become a ninja at their development by following these steps and make your life easier and simpler!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/considerations-developers-building-event-driven-microservices/"&gt;Considerations for Developers Building Event-Driven Microservices &lt;/a&gt; appeared first on &lt;a href="https://solace.com"&gt;Solace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>eventdriven</category>
      <category>microservices</category>
    </item>
    <item>
      <title>How to Develop Microservices: 7 Event-Driven Considerations</title>
      <dc:creator>Marc DiPasquale</dc:creator>
      <pubDate>Mon, 19 Aug 2019 12:00:31 +0000</pubDate>
      <link>https://dev.to/solacedevs/how-to-develop-microservices-7-event-driven-considerations-3gkp</link>
      <guid>https://dev.to/solacedevs/how-to-develop-microservices-7-event-driven-considerations-3gkp</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o43JgGuW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2018/12/advanced-event-broker.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o43JgGuW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2018/12/advanced-event-broker.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;What are the are most important things for developers to know when it comes to microservices application development? Many organizations migrate to microservices for one reason: Agility. The ability to quickly create and modify components in a way that offers bottom-line business value is mission critical in a world where your competitors are a click away and time to market is everything. However, you, a developer in your organization, also know that performance of your operational systems matters and no matter how agile microservices allow your team to be you are tasked with both delivering quickly AND ensuring the operational system can perform under peak load. To achieve both agility and performance many development teams are embracing the use of event-driven microservices. So, what do you need to know to be successful?&lt;/p&gt;

&lt;p&gt;In a nutshell, you need to know:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The basics of messaging – its benefits and the various communication patterns&lt;/li&gt;
&lt;li&gt;The common false assumptions of distributed computing that developers make&lt;/li&gt;
&lt;li&gt;How event-driven architecture can help you&lt;/li&gt;
&lt;li&gt;Why to choose choreography over orchestration for your microservices&lt;/li&gt;
&lt;li&gt;Why you should embrace eventual consistency&lt;/li&gt;
&lt;li&gt;Frameworks that support event-driven microservices development&lt;/li&gt;
&lt;li&gt;Tools to visualize and choreograph your microservices&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Note: This blog post was recently updated on July 7, 2020&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Basics of Messaging
&lt;/h2&gt;

&lt;p&gt;Capitalizing on the benefits of microservices application development within your enterprise requires a broader understanding of &lt;a href="https://solace.com/blog/messaging-patterns-for-event-driven-microservices/"&gt;messaging patterns for event-driven microservices&lt;/a&gt; and when to use them.&lt;/p&gt;

&lt;p&gt;Using messaging to communicate between microservices allows you to realize these benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple, scalable connectivity&lt;/li&gt;
&lt;li&gt;Simple, high availability&lt;/li&gt;
&lt;li&gt;Simple producer/consumer scalability&lt;/li&gt;
&lt;li&gt;The enablement of publish/subscribe, message filtering, routing and fanout&lt;/li&gt;
&lt;li&gt;Decoupling of your producers and consumers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more details about these benefits, I suggest you read &lt;a href="https://solace.com/blog/messaging-between-microservices/"&gt;this blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The False Assumptions of Distributed Computing
&lt;/h2&gt;

&lt;p&gt;It has been more than 20 years since Peter Deutsch and James Gosling developed the &lt;a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing"&gt;8 fallacies of distributed computing&lt;/a&gt;, but these eight false assumptions are still made today by developers new to distributed applications.&lt;/p&gt;

&lt;p&gt;All eight fallacies are relevant, but I’ve bolded the ones that are especially important in the world of microservices application development, because the smaller you make each microservice, the larger your service count, and the larger the service count, the more these fallacies will impact your stability and user experience/system performance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The network is reliable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Latency is zero&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Bandwidth is infinite&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The network is secure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Topology doesn’t change&lt;/li&gt;
&lt;li&gt;There is one administrator&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transport cost is zero&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The network is homogeneous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The challenge is that microservices require connectivity/data in order to perform their roles and provide business value, and data acquisition/communication has been largely ignored, so much so that the tooling has severely lagged behind. For example, API management/gateway products only support synchronous, request/reply exchange patterns, which when coupled with the fallacies noted above, exacerbates the challenges of distributed computing. Many of these challenges can be minimized by properly implementing event-driven architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Advantage of Event-Driven Application Architecture
&lt;/h2&gt;

&lt;p&gt;Unlike service-oriented design, which are synchronous and blocking, event-driven design is non-blocking and uses lots of &lt;a href="https://en.wikipedia.org/wiki/Callback_(computer_programming)"&gt;callbacks&lt;/a&gt;. Event-driven design is not a new concept, and you may even be familiar with it from using programming patterns such as the &lt;a href="https://en.wikipedia.org/wiki/Reactor_pattern"&gt;reactor pattern&lt;/a&gt; or the &lt;a href="https://en.wikipedia.org/wiki/Observer_pattern"&gt;observer pattern&lt;/a&gt;. The concepts used by these programming patterns can be applied to event-driven microservice architectures using architectural patterns, such as &lt;a href="https://solace.com/blog/publish-subscribe-messaging-pattern/"&gt;publish-subscribe&lt;/a&gt;, to achieve service decoupling, independent scalability, and one-to-many bi-directional communications.&lt;/p&gt;

&lt;p&gt;The first step towards adopting the event-driven mindset is to change the way you think about designing and architecting solutions. Initially the tendency is to think about all interactions between services as a series in a sequence of request/reply service calls. In fact, if you or your team uses the terminology of “invoking,” “requesting,” or “calling” then it is a sure sign you are still thinking in the request/reply paradigm.&lt;/p&gt;

&lt;p&gt;Instead, try these: “What events should my service process?” and “What events will my service emit?”&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Benefits of Choreography in Microservices
&lt;/h2&gt;

&lt;p&gt;Once you adopt event-driven thinking, you need to make the shift from &lt;a href="https://solace.com/blog/microservices-choreography-vs-orchestration/"&gt;orchestration to choreography&lt;/a&gt;. It is common for developers to think in terms of “service A will call service B which will call service C” and then implement that model through a chain of invocations (a-&amp;gt;b&amp;gt; c) or by creating an orchestrator service such that x-&amp;gt;a, then x-&amp;gt;b, then x-&amp;gt;c.  Both approaches will cause chaos when the realities of distributed computing kick in, especially when you start to scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2019/08/dev-considerations-eda_image-1.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4lmf4ljA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/dev-considerations-eda_image-1.png" alt="orchestration vs choreography in microservices application development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thoughtworks.com/insights/blog/scaling-microservices-event-stream"&gt;Orchestration vs. Choreography, Source: Thoughtworks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The alternative is to follow the philosophy of choreography. Services should react to changes in their environment and the benefits are immense:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Better agility&lt;/strong&gt; : Agile development teams are more independent and are significantly less impacted by changes to other services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Services are smaller/simpler&lt;/strong&gt; : Each service is not required to have complex error handling for downstream service or network failures. Who likes writing error handling??? Not me!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less service coupling&lt;/strong&gt; : Services have no knowledge about the existence of other services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enables fine-grained scaling&lt;/strong&gt; : Each service can be independently scaled up or down based on demand. This ensures a good user experience and is less wasteful of compute resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to add new services&lt;/strong&gt; : Due to less coupling, a new service can come online, consume events and implement new functionality without changes to any other service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This list of benefits doesn’t come for free; there is no silver bullet…&lt;/p&gt;

&lt;p&gt;Consistency of state then becomes an area of focus, because a service, being temporarily down, means that the event state changes may not be processed immediately. Fundamentally, how do we deal with this negative side effect?&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Eventual Consistency in Microservices
&lt;/h2&gt;

&lt;p&gt;Eventual consistency is the idea that consistency will occur in the future, and it means accepting that things may be out of sync for some time. It’s a pattern and concept that lets developers avoid using nasty XA transactions. It’s the job of the eventing/messaging platform to ensure that these domain change events are never lost before being appropriately handled by a service and acknowledged.&lt;/p&gt;

&lt;p&gt;Some think the only benefit of eventual consistency is performance, but the real advantage is the decoupling of the microservices since individual services are merely acting upon events that they are interested in.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Event-Driven Microservices Development Frameworks
&lt;/h2&gt;

&lt;p&gt;As a developer, you want the ability to easily write clean code which enables you to deliver functionality quicker. Thus, the development language and associated tooling becomes important. While event-driven architectures allow us to decouple our microservices and choose different technologies to implement each one it is recommended to choose a standard language/framework that best fits your team’s skill sets and deviate only when necessary.&lt;/p&gt;

&lt;p&gt;For many development team, their skill set usually includes experience using the Spring framework with Java (and other Spring-supported, JVM-based languages). This experience has led to Spring Boot becoming the most popular framework for microservices application development in organizations. Its adoption continues to grow and best of all, it has built in support for event-driven microservices through  &lt;a href="https://spring.io/projects/spring-cloud-stream"&gt;Spring Cloud Stream.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spring Cloud Stream is a framework for building highly scalable, event-driven microservices connected using shared event brokers (a Solace binder is available &lt;a href="https://github.com/SolaceProducts/solace-spring-cloud/tree/master/solace-spring-cloud-starters/solace-spring-cloud-stream-starter"&gt;here&lt;/a&gt;. On top of providing an implementation framework, Spring Cloud Stream also defines vendor agnostic terminology for the event-driven community, including defining &lt;em&gt;source&lt;/em&gt; and &lt;em&gt;sink&lt;/em&gt; applications that send or receive events over &lt;em&gt;channels&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2019/08/spring-cloud-streams-architecture.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--267dwCht--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2019/08/spring-cloud-streams-architecture-1024x481.png" alt="microservices application development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re interested, I dive deeper into creating microservices using Spring Cloud Stream and AsyncAPI Code Generator in &lt;a href="https://solace.com/blog/asyncapi-codegen-microservices-using-spring-cloud-stream/"&gt;this post&lt;/a&gt; and &lt;a href="https://solace.com/resources/pubsub-event-portal/asyncapi-code-generation-with-spring-cloud-stream"&gt;this video&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Model and Visualize Microservices in Your Event-Driven Process
&lt;/h2&gt;

&lt;p&gt;As discussed earlier, one of the benefits of choreographing your microservices using an event-driven architecture is to achieve less service coupling. But this benefit introduces some challenges of its own. Specifically, when your producers and consumers don’t care about the existence of each other it can make it challenging to model your architecture at design time and even harder to understand what events are flowing where at run-time.&lt;/p&gt;

&lt;p&gt;Attempts to solve this challenge have been made in many different ways by many different organizations, but until recently there hasn’t been an all-encompassing solution available to the masses. The introduction of the Solace PubSub+ Event Portal solves these challenges by allowing you to visualize, manage, &lt;em&gt;and&lt;/em&gt; choreograph your microservices at design time and providing features that allow you to discover, audit and secure your run-time environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2020/03/site-software2-event-portal-datasheet-1.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YdkN78JJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2020/03/site-software2-event-portal-datasheet-1-1024x422.png" alt="microservices application development event portal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more about &lt;a href="https://solace.com/blog/why-developers-need-event-portal/"&gt;Why Developers Need an Event Portal&lt;/a&gt;, where I walk through the steps I took to create consistent and scalable microservices within minutes.&lt;/p&gt;

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

&lt;p&gt;While event-driven microservices may seem difficult initially, they are the future of most microservices and IT strategies. Become a ninja at their development by following these steps and make your life easier and simpler!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/microservices-application-development-considerations/"&gt;How to Develop Microservices: 7 Event-Driven Considerations&lt;/a&gt; appeared first on &lt;a href="https://solace.com"&gt;Solace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>spring</category>
      <category>java</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
