marcd.devmarcd.dev
https://marcd.dev/
2021-03-19Fri, 19 Mar 2021 14:44:41 -0400Jekyll v3.9.0Publishing Github Java Packages to Maven Central for a New Domain<h2 id="overview">Overview</h2>
<p>🎉 The <a href="solace.com">Solace</a> Developer Relations team recently launched our <a href="github.com/SolaceCommunity">SolaceCommunity github organization</a> as a home for open source projects that are authored, maintained and supported by the amazing <a href="solace.community">Solace Community</a>. If you’re interested in joining our community you can read more about it <a href="https://solace.com/blog/announcing-new-solacecommunity-github-organization/">here</a>, but that won’t be the focus of the rest of this blog. <strong>The focus of this blog is how I enabled publishing of Java packges to Maven Central</strong> for this new github community and how you can do so for your own domain. 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. Over the past few weeks I went through the steps necessary to setup publishing of Java packages to Maven Central for the https://solace.community domain. This was trickier than I thought so I figured I’d share what I did to hopefully help others :)</p>
<p>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.
I used the following resources when figuring out these steps so props to their creators!</p>
<ul>
<li><a href="https://central.sonatype.org/pages/ossrh-guide.html">OSSRH Guide</a></li>
<li><a href="https://docs.github.com/en/actions/guides/publishing-java-packages-with-maven">Publishing Java packages with Maven</a></li>
<li><a href="https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c">How to Sign and Release to The Central Repository with GitHub Actions</a></li>
</ul>
<h2 id="setting-up-ossrh-the-repository">Setting up OSSRH (The Repository)</h2>
<p>There are a handful of approved repository hosting options specified by Maven Central. You can find the entire list <a href="https://maven.apache.org/repository/guide-central-repository-upload.html#approved-repository-hosting">here</a>, but the easiest approach seems to leverage <a href="http://central.sonatype.org/pages/ossrh-guide.html">Open Source Software Repository Hosting (OSSRH)</a> so that’s the approach I decided to take.</p>
<p><em>Note that if you’re just trying to publish a few personal projects on github and are fine publishing under <code class="language-plaintext highlighter-rouge">io.github</code> 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 :)</em></p>
<h3 id="get-an-account">Get An Account</h3>
<p>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. <a href="https://issues.sonatype.org/secure/Signup!default.jspa">Sign up for an account here</a></p>
<p>âś… Account Created</p>
<h3 id="prove-domain-ownership">Prove Domain Ownership</h3>
<p>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 <code class="language-plaintext highlighter-rouge">com.company</code> if your domain is <code class="language-plaintext highlighter-rouge">company.com</code>. Since our developer community is at <code class="language-plaintext highlighter-rouge">solace.community</code> this meant we would publish to the <code class="language-plaintext highlighter-rouge">community.solace</code> group.</p>
<p>To prove that we own this domain I had to execute a few simple steps:</p>
<ol>
<li>Open a <a href="https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134">New Project Ticket</a> with OSSRH.</li>
<li>Follow the instructions request in the ticket to addd a DNS TXT record to our domain.</li>
<li>Wait a few hours (it says it could take up to 2 business days) for the DNS TXT record to be verified.</li>
<li>Check the ticket for confirmation that domain ownership has been confirmed.</li>
<li>Make a note to comment on this ticket after your first release to enable syncing to maven central!</li>
</ol>
<p>âś… Domain ownership proven</p>
<h3 id="create-your-user-token">Create Your User Token</h3>
<p>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.</p>
<p>To get this token do the following:</p>
<ol>
<li>Login to the <a href="https://s01.oss.sonatype.org/#welcome">OSSRH Nexus Repository Manager</a> w/ your OSSRH account</li>
<li>Go to your profile using the menu under your username at the top right.</li>
<li>You should see a list menu that is on the <code class="language-plaintext highlighter-rouge">Summary</code> page; change it to <code class="language-plaintext highlighter-rouge">User Token</code>. You can create your token on this page.</li>
<li>Copy & Paste this token info so you can use it later! <strong>(Keep it private!)</strong></li>
</ol>
<p>âś… OSSRH is now ready to go and we have the info we need</p>
<h2 id="configuring-the-maven-pom">Configuring the Maven pom</h2>
<p>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 :)
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.</p>
<p>An entire example pom can be found <a href="https://github.com/solacecommunity/spring-solace-leader-election/blob/master/pom.xml">here</a></p>
<p>Here is what I did:</p>
<ol>
<li>Ensured that my <code class="language-plaintext highlighter-rouge">groupId</code> starts with the reverse domain that we have approval to publish to! For example this is what we used, note that the <code class="language-plaintext highlighter-rouge">groupId</code> starts with <code class="language-plaintext highlighter-rouge">community.solace</code>.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <groupId>community.solace.spring.integration</groupId>
<artifactId>solace-spring-integration-leader</artifactId>
<version>1.1.0-SNAPSHOT</version>
</code></pre></div> </div>
</li>
<li>
<p>What to know about the version! Okay <strong>this is important</strong>. 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 :) <br />
Once you know the difference you’re ready to set your version. Use a version ending in a number, e.g: <code class="language-plaintext highlighter-rouge">1.1.0</code>, for a “release” and end it in <code class="language-plaintext highlighter-rouge">-SNAPSHOT</code>, e.g: <code class="language-plaintext highlighter-rouge">1.1.0-SNAPSHOT</code> for a snapshot.</p>
</li>
<li>Include a description name, description and url pointing to your repository. For example,
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <name>Solace Spring Integration Leader</name>
<description>This project allows for Spring Integration Leader Election using Solace Exclusive Queues</description>
<url>https://github.com/solacecommunity/spring-solace-leader-election</url>
</code></pre></div> </div>
</li>
<li>Include a license, source control info <code class="language-plaintext highlighter-rouge">scm</code>, developers and organization(I believe this is optional) information.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <licenses>
<license>
<name>MIT License</name>
<url>https://github.com/solacecommunity/spring-solace-leader-election/blob/master/LICENSE</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>Solace Community</name>
<email>[email protected]</email>
<organization>Solace Community</organization>
<organizationUrl>https://solace.community</organizationUrl>
</developer>
</developers>
<organization>
<name>Solace Community</name>
<url>https://solace.community</url>
</organization>
<scm>
<url>https://github.com/solacecommunity/solace-spring-integration-leader.git</url>
<connection>scm:git:git://github.com/solacecommunity/solace-spring-integration-leader.git</connection>
<developerConnection>scm:git:[email protected]:solacecommunity/solace-spring-integration-leader.git</developerConnection>
<tag>HEAD</tag>
</scm>
</code></pre></div> </div>
</li>
<li>Add a profile for OSSRH which includes the <code class="language-plaintext highlighter-rouge">snapshotRepository</code> info, the <code class="language-plaintext highlighter-rouge">nexus-staging-maven-plugin</code>, and the <code class="language-plaintext highlighter-rouge">maven-gpg-plugin</code>. Note in the example below I have this profile <code class="language-plaintext highlighter-rouge">activeByDefault</code> 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 :)
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <profile>
<id>ossrh</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<gpg.executable>gpg</gpg.executable>
</properties>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<name>Central Repository OSSRH</name>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<!-- Change to true once we're good! -->
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</code></pre></div> </div>
</li>
<li>Include the <code class="language-plaintext highlighter-rouge">maven-release-plugin</code>, the <code class="language-plaintext highlighter-rouge">maven-javadoc-plugin</code>, the <code class="language-plaintext highlighter-rouge">maven-source-plugin</code> and the <code class="language-plaintext highlighter-rouge">flatten-maven-plugin</code> plugin.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<tagNameFormat>@{project.version}</tagNameFormat>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-invoker</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<source>8</source>
<detectJavaApiLink>false</detectJavaApiLink>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>oss</flattenMode>
<pomElements>
<distributionManagement>remove</distributionManagement>
<repositories>remove</repositories>
</pomElements>
</configuration>
<executions>
<!-- enable flattening -->
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<!-- ensure proper cleanup -->
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</code></pre></div> </div>
</li>
</ol>
<p>âś… The maven pom is now ready to go!</p>
<h2 id="create-gpg-keys">Create GPG Keys</h2>
<p>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.</p>
<h2 id="create-your-key">Create Your Key</h2>
<p>The first step is to <strong>Create Your Key</strong>. You can do this locally using a tool such as gpg. Be sure to keep your <strong>private</strong> key private. If others get ahold of this they can become a trusted publisher of your packages.</p>
<ol>
<li>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 <a href="">here</a>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> brew install gpg
</code></pre></div> </div>
</li>
<li>Generate your key pair. You will be prompted for a “Real Name” and “Eamil Address” that you want to use with the key
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> gpg --gen-key
</code></pre></div> </div>
</li>
</ol>
<p>âś… GPG key created!</p>
<h2 id="share-your-public-key">Share Your Public Key</h2>
<p>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 <code class="language-plaintext highlighter-rouge">gpg</code> 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.</p>
<ol>
<li>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 <em>C48B6G0D63B854H7943892DF0C753FEC18D3F855</em>. In the command below I’ve replaced it with <code class="language-plaintext highlighter-rouge">MYIDENTIFIER</code> to show it’s location.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MJD-MacBook-Pro.local:~$ gpg --list-keys
/path/to/keyring/pubring.kbx
----------------------------------------
pub rsa3072 2021-03-11 [SC] [expires: 2023-03-11]
MYIDENTIFIER
uid [ultimate] solacecommunity <[email protected]>
sub rsa3072 2021-03-11 [E] [expires: 2023-03-11]
</code></pre></div> </div>
</li>
<li>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 <code class="language-plaintext highlighter-rouge">hkp://keyserver.ubuntu.com:11371</code>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gpg --keyserver hkp://pool.sks-keyservers.net --send-keys MYIDENTIFIER
</code></pre></div> </div>
</li>
</ol>
<p>✅ We’ve now shared our public key!</p>
<h2 id="configure-the-github-secrets">Configure the Github Secrets</h2>
<p>Okay at this point our project is looking pretty good and we could run a deployment locally using the <code class="language-plaintext highlighter-rouge">mvn --batch-mode clean deploy</code> command, however we actually want to perform our releases via a Github action. Shoutout to <a href="https://gist.github.com/sualeh">sualeh</a> for creating <a href="https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c">this gist</a> 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 <a href="https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets">Github Action Secrets</a>.</p>
<p>I created secrets at the Github Organization level so I followed the steps below to keep my <code class="language-plaintext highlighter-rouge">OSSRH_GPG_SECRET_KEY</code>,<code class="language-plaintext highlighter-rouge">OSSRH_GPG_SECRET_KEY_PASSWORD</code>,<code class="language-plaintext highlighter-rouge">OSSRH_USERNAME</code> and <code class="language-plaintext highlighter-rouge">OSSRH_PASSWORD</code> 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 <a href="https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-an-organization">docs here</a>
<img src="https://marcd.dev/img/createOrgSecrets.png" alt="Creating encrypted secrets for an organization" /></p>
<p>âś… Secrets configured!</p>
<h2 id="setting-up-the-github-action">Setting up the Github Action</h2>
<p>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 <a href="https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c">gist</a> as a starting point. You can find the Github Action <a href="https://github.com/solacecommunity/spring-solace-leader-election/actions/runs/645154320/workflow">workflow file here</a>.</p>
<p>You’ll see below that this Github Action will run on the latest ubuntu and execute the <code class="language-plaintext highlighter-rouge">publish</code> 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.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Publish package to the Maven Central Repository</span>
<span class="na">on</span><span class="pi">:</span>
<span class="na">release</span><span class="pi">:</span>
<span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">created</span><span class="pi">]</span>
<span class="na">jobs</span><span class="pi">:</span>
<span class="na">publish</span><span class="pi">:</span>
<span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
<span class="na">steps</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Set up Maven Central Repository</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-java@v1</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">java-version</span><span class="pi">:</span> <span class="m">11</span>
<span class="na">server-id</span><span class="pi">:</span> <span class="s">ossrh</span>
<span class="na">server-username</span><span class="pi">:</span> <span class="s">MAVEN_USERNAME</span>
<span class="na">server-password</span><span class="pi">:</span> <span class="s">MAVEN_PASSWORD</span>
<span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">install-secret-key</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Install gpg secret key</span>
<span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
<span class="s">cat <(echo -e "$") | gpg --batch --import</span>
<span class="s">gpg --list-secret-keys --keyid-format LONG</span>
<span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">publish-to-central</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Publish to Central Repository</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">MAVEN_USERNAME</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">MAVEN_PASSWORD</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
<span class="s">mvn \</span>
<span class="s">--no-transfer-progress \</span>
<span class="s">--batch-mode \</span>
<span class="s">-Dgpg.passphrase=$ \</span>
<span class="s">clean deploy</span>
</code></pre></div></div>
<p>âś… Github Action ready to go</p>
<h2 id="running-the-github-action---lets-test-it-with-a-snapshot-release">Running the Github Action - let’s test it with a Snapshot release</h2>
<p>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 <code class="language-plaintext highlighter-rouge">version</code> in the pom ends in <code class="language-plaintext highlighter-rouge">-SNAPSHOT</code> as discused earlier.</p>
<ol>
<li>
<p>Once the version on your <code class="language-plaintext highlighter-rouge">main</code> branch includes <code class="language-plaintext highlighter-rouge">-SNAPSHOT</code> go ahead and run the github action workflow. You should see the <code class="language-plaintext highlighter-rouge">publish</code> job successed in a few minutes depending on how long your build takes. Ours took 1m 20s the first time.</p>
</li>
<li>
<p>After the deploy job successfully runs you can head over to https://s01.oss.sonatype.org/content/repositories/snapshots/ and navigate to your project to verify that the snapshot has successfully deployed. It should look something like this:</p>
</li>
</ol>
<p><img src="https://marcd.dev/img/snapshot.png" alt="snapshot" /></p>
<p>âś… Snapshot published!</p>
<h2 id="running-the-github-action---now-lets-make-an-actual-release">Running the Github Action - now let’s make an actual release</h2>
<p>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 :)</p>
<ol>
<li>Change your version in the pom to remove the <code class="language-plaintext highlighter-rouge">-SNAPSHOT</code>, so it should end in a number. Something like <code class="language-plaintext highlighter-rouge">1.1.0</code>.</li>
<li>Re-Run the Github Action workflow. Wait for the publish job to succeed :)</li>
</ol>
<p>âś… At this point our project will be staged for release. There is just one more step!</p>
<h3 id="approve-the-deployment-in-nexus">Approve the Deployment in Nexus</h3>
<p>Now that our project is staged for release we need to login to the OSSRH Nexus Repository Manager to promote the release.</p>
<ol>
<li>Login to the <a href="https://s01.oss.sonatype.org/#welcome">OSSRH Sonatype Nexus Repository Manager</a></li>
<li>Navigate to the <code class="language-plaintext highlighter-rouge">Staging Repositories</code> in the menu on the left hand side.</li>
<li>Examine the contents of the release and if everything looks good <code class="language-plaintext highlighter-rouge">close</code> the release. More information is available <a href="https://central.sonatype.org/pages/releasing-the-deployment.html">here</a></li>
<li>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.</li>
</ol>
<p>âś… Deployment Complete!</p>
<h3 id="check-out-the-deployed-project">Check out the deployed project!</h3>
<p>After ~24 hours head over to <a href="https://search.maven.org/search">Maven Central’s search</a> and you should be able to find our project by typing in your groupId or artifactId.
<img src="https://marcd.dev/img/mavenCentralSearch.png" alt="mavenCentralSearch" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>Hope this was useful! Feel free to leave a comment if you have any questions :)</p>
2021-03-19
https://marcd.dev/articles/2021-03/mvncentral-publish-github
https://marcd.dev/articles/2021-03/mvncentral-publish-githubjavagithubmavenpostReflecting on my First Hackathon<h2 id="the-hackathon-makeuoft">The Hackathon: MakeUofT</h2>
<p>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 <em>maybe</em> partially working, if at all.</p>
<p><img src="https://marcd.dev/img/makeathon.png" alt="Makeathon" /></p>
<p>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.</p>
<p><img src="https://marcd.dev/img/rasppi.jpg" alt="Raspberry PI" /></p>
<h3 id="my-reflection">My Reflection</h3>
<p>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 & 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.</p>
<p>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 <em>baseline</em> 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 & 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!</p>
<p>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 <a href="https://makeuoft-2020.devpost.com/submissions/search?utf8=%E2%9C%93&prize_filter%5Bprizes%5D%5B%5D=35080">here</a> which I’ve also shown an image of below.</p>
<p><img src="https://marcd.dev/img/makeuoft-projects.png" alt="MakeUofT Projects" /></p>
<h3 id="the-business-value-of-a-hackathon">The Business Value of a Hackathon</h3>
<p>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?</p>
<p>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.</p>
<p>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.</p>
<p><img src="https://marcd.dev/img/makeuoft-booth.jpg" alt="MakeUofT Booth" /></p>
<p>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!</p>
<p>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!</p>
<p>After such a great weekend I’m definitely looking forward to the next time I’ll get to participate in a hackathon! <strong>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: Solace, 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.</strong></p>
2021-03-19
https://marcd.dev/articles/2020-02/hackathon-reflections
https://marcd.dev/articles/2020-02/hackathon-reflectionspostMakeUofT Developer Workshop & Hackathon<h2 id="my-first-hackathon">My First Hackathon</h2>
<ul>
<li>Hackathon - <a href="https://ieee.utoronto.ca/makeuoft/">MakeUofT 2020</a></li>
<li>Co-Speaker - Vats Vanamamalai - Solutions Architect @ Solace</li>
<li>Location - University of Toronto</li>
<li>Audience Size - ~15 at the workshop; ~300 at the event w/ 12 teams of 4 students submitting for the Solace prize!</li>
<li>What happened!? - Vats and I put on a developer workshop where we showed attendees how they can use Solace to stream sensor data from both physical and virtual sensors on a Raspberry PI into Solace Cloud. Once in Solace Cloud we used NodeRed to subscribe to the event streams and visualize the sensor data. This demo was also used throughout the hackathon to explain how PubSub+ can be used to stream event data. Want to check out the demo? See the github url below.</li>
<li>Github repo - https://github.com/SolaceLabs/makeuoft-hackathon</li>
</ul>
<p><img src="https://marcd.dev/img/makeuoft-flier.png" alt="MakeUofT-OnePager" /></p>
2021-03-19
https://marcd.dev/articles/2020-02/makeuoft
https://marcd.dev/articles/2020-02/makeuofttalkworkshopworkshopTalk at AWS Re-Invent 2019<h2 id="aws-re-invent-2019">AWS Re-Invent 2019</h2>
<ul>
<li>Talk Title - “Go Event-Driven with Event Mesh & AWS Lambda”</li>
<li>Conference - <a href="https://reinvent.awsevents.com">AWS Re-Invent 2019</a></li>
<li>Location - Aria, Las Vegas, NV</li>
<li>Audience Size - 60</li>
<li>Talk Recording - <a href="https://www.youtube.com/watch?v=9iCJFf2th5Q">Available on Youtube</a></li>
<li>Abstract - We live in an event-driven world. Events are becoming a core component of new business architectures, and they allow organizations to react in real time to an ever-changing environment. But shifting to an event-driven architecture is daunting—how do you move events from on-premises data centers to the cloud? How do you transmit events across AWS Regions? How do you enable legacy applications to communicate with modern, cloud-native applications built on services such as AWS Lambda and Amazon Kinesis? In this talk, we discuss how an Event Mesh enables organizations to meet these challenges. This presentation is brought to you by Solace Corporation, an APN Partner.</li>
</ul>
<p><img src="https://marcd.dev/img/awsreinvent-2019.jpg" alt="AWSReinvent2019" /></p>
2021-03-19
https://marcd.dev/articles/2019-12/aws-reinvent
https://marcd.dev/articles/2019-12/aws-reinventtalktalkSolace NY User Group 2019<h2 id="springone-platform-2019">SpringOne Platform 2019</h2>
<ul>
<li>Talk Title - “Solace Event Portal Demo”</li>
<li>Conference - Solace NY User Group 2019</li>
<li>Location - Millenium Partners, New York, NY</li>
<li>Audience Size - ~80</li>
<li>Abstract - I had the pleasure of demonstrating the brand new Solace Event Portal to an audience of current and prospective customers. The demo included showing current functionality as well as showing some of what will be coming in the future :)</li>
</ul>
2021-03-19
https://marcd.dev/articles/2019-11/solace-nyug
https://marcd.dev/articles/2019-11/solace-nyugtalktalkDeveloper Workshop at SpringOne Platform 2019<h2 id="springone-platform-2019">SpringOne Platform 2019</h2>
<ul>
<li>Talk Title - “Be Event-Driven with AsyncAPI & Spring Cloud Streams”</li>
<li>Conference - <a href="https://springoneplatform.io/2019">SpringOne Platform 2019</a></li>
<li>Co-Speaker - <a href="https://twitter.com/jschabowsky">Jonathan Schabowsky</a> - Senior Architect, Office of the CTO @ Solace</li>
<li>Location - Austin Convention Center</li>
<li>Audience Size - 60</li>
<li>Codelab - <a href="https://www.marcd.dev/s1p-codelab-2019/#0">https://www.marcd.dev/s1p-codelab-2019</a></li>
<li>Code Repository - <a href="https://github.com/Mrc0113/workshop-scs-s1p">https://github.com/Mrc0113/workshop-scs-s1p</a></li>
</ul>
<h4 id="workshop-description">Workshop Description:</h4>
<p>Are you passionate about building modern, distributed, real-time applications? Is your organization adopting an Event Driven Architecture to compete in our event-driven world? AsyncAPI is the industry standard for defining asynchronous APIs. Build and expand your developer toolbox by learning how to create event-driven microservices using Spring Cloud Streams, AsyncAPI and Solace PubSub+. And deploy those microservices using Pivotal’s Cloud Platform to allow for continuous delivery and agility in hybrid and multi-cloud environments.</p>
<p>Solace PubSub+ is an advanced event broker used by some of the largest enterprises in the world to process many billions of messages with low latency and high performance every day. It is available as a run-anywhere software, purpose-built hardware, and a managed service. Connect your Brokers to form your Event Mesh and dynamically route events across hybrid and multi-cloud environments using open standards such as MQTT, AMQP, JMS, REST, and of course our Spring Cloud Streams Binder!</p>
<p>In this hands-on workshop, attendees will be guided through a CodeLab where they will:
Discover how Spring Cloud Streams (SCS) enables developers to create highly scalable, event-driven applications.
Combine Spring Cloud Streams & AsyncAPI Code Generation to see how easy event-driven development is becoming.
Effortlessly deploy those microservices using a PubSub+ Event Mesh and Pivotal’s Cloud Platform to achieve event-driven, multi-cloud nirvana.</p>
<p><img src="https://marcd.dev/img/s1p-ws-2019.jpg" alt="S1PWorkshop" /></p>
2021-03-19
https://marcd.dev/articles/2019-10/s1p-ws
https://marcd.dev/articles/2019-10/s1p-wstalkworkshopworkshopTalk at API Days SF 2019<h2 id="api-days-sf-2019">API Days SF 2019</h2>
<ul>
<li>Talk Title - “API Management, Meet Event Management”</li>
<li>Conference - <a href="https://www.apidays.co/sanfrancisco">API Days SF 2019</a></li>
<li>Co-Speaker - <a href="https://twitter.com/jschabowsky">Jonathan Schabowsky</a> - Senior Architect, Office of the CTO @ Solace</li>
<li>Location - Yerba Buena Center for the Arts, SF</li>
<li>Audience Size - 125</li>
<li>Abstract - Event-driven apps and architectures will be transformational to businesses when we have the tools to manage events the way we manage APIs. Documenting, discovering, registering, and co-creating events and applications is key, but it’s not possible today. In this talk we’ll introduce the concept of an “Event Management Platform” that will perform similar functions to an API Management Platform, but for the event-driven world. We’ll also demo code creation for event-driven microservices using AsyncAPI.</li>
</ul>
<h3 id="check-out-the-talk-on-youtube">Check out the talk on Youtube!</h3>
<p align="center"><iframe width="560" height="315" src="https://www.youtube.com/embed/4d93vyRu-8Q" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></p>
<p><img src="https://marcd.dev/img/apidays-sf-2019.jpg" alt="APIDays" /></p>
2021-03-19
https://marcd.dev/articles/2019-07/apidays-sf
https://marcd.dev/articles/2019-07/apidays-sftalktalkTalk at OrlandoDevs Meetup<h2 id="odevs-july-meetup---modern-app-architectures">ODevs July Meetup - “Modern App Architectures”</h2>
<ul>
<li>Talk Title - “Building Event-Driven Apps for a Real-Time World”</li>
<li>Conference - <a href="https://orlandodevs.com">Orlando Developers Meetup</a> - July 2019 - “Modern App Architectures”</li>
<li>Meetup Link - https://www.meetup.com/OrlandoDevs/events/262394428/</li>
<li>Location - Tree House @ Full Sail, Orlando, FL</li>
<li>Audience Size - ~90 (We filled up the room!)</li>
<li>Abstract - We live in an event-driven world. Events are a core component of all new business architectures and allow organizations to react in real time to an ever-changing environment. As software architectures shift to more event-driven designs, the usage of traditional REST-over-HTTP for communication can limit the flexibility and performance of distributed applications and microservices. This talk will discuss why this is the case and introduce developers to event-driven design.</li>
</ul>
<p><img src="https://marcd.dev/img/odevs-stage.png" alt="ODevs-stage" />
<img src="https://marcd.dev/img/odevs-room.png" alt="ODevs-room" />
<img src="https://marcd.dev/img/odevs-sign.png" alt="ODevs-sign" /></p>
2021-03-19
https://marcd.dev/articles/2019-07/orlando-devs
https://marcd.dev/articles/2019-07/orlando-devstalktalkMy DevRel Journey Begins<h2 id="a-public-speaking-success">A Public Speaking Success</h2>
<p>This was a really exciting (and nerve-racking) week for me. Upon taking my new position at Solace as a Developer Advocate earlier this year I officially joined the Developer Relations community. I knew that this meant I would eventually have to face my fear of public speaking and overcome it. I am proud to say that this week I made a large step towards doing just that. I figured I’d write a quick post on about my week and touch on a few tips that helped me when speaking this week!</p>
<p>The first half of this week was quite hectic for me. I flew to Chicago on Sunday evening for a Developer Workshop with one of our customers on Monday. Then caught a flight Monday evening to San Francisco for MuleSoft Connect on Tuesday & Wednesday. At MuleSoft Connect I did the <a href="https://www.marcd.dev/articles/2019-06/mulesoft-connect">first conference talk of my career</a> before catching a redeye flight home to Orlando after the conference.</p>
<p>A huge thanks to my friend and colleague, Jonathan Schabowsky <a href="https://twitter.com/jschabowsky">@jschabowsky</a>, as this week would have been much more challenging without your help! Jonathan kicked off the all day workshop with a presentation before handing it off to me for the hands on portion. The hands on portion of the workshop was a Google CodeLab that teaches the fundamentals of Spring Cloud Streams (you’ll probably see more on this in a future blog). I was a bit nervous going into the workshop knowing that I would literally be in front of the attendees for 3-5 hours, but I found comfort in the fact that I created the CodeLab materials and was more familiar with them than anyone else. Three key tips here!</p>
<ul>
<li>Tip #1 - If possible, co-speaking with someone you trust for your first talk or two really takes the pressure off. For me speaking with Jonathan really allowed me to relax as I knew if I were to slip up or forget something that he would chime in to provide clarification.
<img src="https://marcd.dev/img/cospeakers.jpg" alt="CoSpeaking" /></li>
<li>Tip #2 - Create your own materials! I’ve been in countless meetings where I’ve had to present powerpoint slides that were created by someone else and I always have those few moments where I change the slide, there are no notes available, and it isn’t clear to me what point the creator was trying to make with the slide. If you’re going to be talking in front of a live audience I HIGHLY RECOMMEND creating your own presentation material.</li>
<li>Tip #3 - It’s okay to pause and think. Most people, including myself, get the urge to speak faster when presenting to a group of people and feel like we have to continually talk. However, this is not the case! It’s okay for there to be short silences between sentences or slides while you think about what you’re going to say next. It also gives the audience an opportunity to take in any diagrams or graphics being displayed.</li>
</ul>
<p>After arriving in San Francisco after the Developer Workshop my mind had shifted to MuleSoft Connect. It was a two day conference with my speaking slot being on the second day. During the first day I was able to watch a few of the other speakers do their presentations and get a feel for the conference and it’s attendees while talking to folks that came by our booth (Solace was a sponsor). The next morning I met with my co-speaker, Jonathan, to practice and remove some content from our talk. We originally thought we had a 30 minute slot but found out we were only allotted 15 minutes after arriving at the conference. Because of the time adjustment we did a few dry runs at a nearby cafe and timed ourselves to make sure we didn’t have too much content. A few hours later was show time! We were quite surprised when the chairs in the room were already filled up ~5-10 minutes before the talk. We even ran out of standing room by the time the talk started and we were told afterwards that 40-50 people had to be turned away due to the room’s capacity! Once again Jonathan kicked off the talk for the first ~5 minutes and did an introduction before handing it off to me for the last ~10 minutes where I got to show off a preview of our new product that is debuting in the fall. The talk flew bye and we were lucky enough to get a lot of positive feedback throughout the rest of the day after the talk.
<img src="https://marcd.dev/img/mulesoftmocha.jpg" alt="MuleSoftMocha" />
Here are a few more tips from my experience at MuleSoft Connect:</p>
<ul>
<li>Tip #4 - Practice your talk! Go through your slides or presentation materials several times prior to the actual talk. If using something like powerpoint, use presentation view if possible and add keypoints that you want to make on each slide. And don’t forget to time yourself! You have an allotted time and don’t want someone forcing you to end early.</li>
<li>Tip #5 - Accept that you don’t have to know everything. You also don’t have to be the smartest person in the room to present. I’m definitely not. One of my worries before doing public speaking engagements was that people in the audience would know more than me about my subject or try to stump me in the Q&A session by asking a super detailed question. But that isn’t the case. Most audience members will respect you just for going on stage and speaking. They know it’s not easy and aren’t there to badger you or cause issues. As said by Heraclitus - “The Only Thing That Is Constant Is Change.” This is especially true in the tech field where things are changing every day. You could learn something in detail 365 days a year and still not know nearly everything there is to know in the tech field. You definitely know things that many of your audience members don’t and vice versa.</li>
<li>Tip #6 - Skip the Q&A session. If you’re not comfortable taking questions on the stage just use all the time during your talk and end with something like “Thank you all for attending - If you have any comments or questions I’d love to hear from you and will hang around after the talk”</li>
<li>Tip #7 - Duration - Start Short. As the room started to fill up and then went to standing room only I definitely started to get more and more nervous. I was able to calm my nerves and take solace in the fact that I only had to speak for 10 out of the 15 minutes and that I had more than enough material to do so (which I knew from tip #4). For your first few talks I would definitely suggest submitting talks for some of the shorter slots.</li>
</ul>
<p>I’m still a long way from considering myself a <del>good</del>calm public speaker, but this week was a huge first step towards eventually being one! I hope the tips I shared above can also be useful to you as well. Definitely let me know your tips in the comments :)</p>
2021-03-19
https://marcd.dev/articles/2019-06/devrel-start
https://marcd.dev/articles/2019-06/devrel-startDevRelpostTalk at MuleSoft Connect 2019<h2 id="my-first-conference-talk-was-a-success">My First Conference Talk was a success!</h2>
<ul>
<li>Talk Title - “API Management, Meet Event Management”</li>
<li>Conference - MuleSoft Connect 2019</li>
<li>Co-Speaker - Jonathan Schabowsky - Senior Architect, Office of the CTO @ Solace</li>
<li>Location - Marriot Marquis, San Francisco, CA</li>
<li>Audience Size - ~100 (with ~40-50 turned away due to room capacity!)</li>
<li>Abstract - Event-driven apps and architectures will be transformational to businesses when we have the tools to manage events the way we manage APIs. Documenting, discovering, registering, and co-creating events and applications is key, but it’s not possible today. In this talk we’ll introduce the concept of an “Event Management Platform” that will perform similar functions to an API Management Platform, but for the event-driven world. We’ll also demo code creation for event-driven microservices using AsyncAPI.</li>
</ul>
<p><img src="https://pbs.twimg.com/media/D-A87QRU0AE5LO9.jpg:small" alt="MuleSoftConnect2019" /></p>
2021-03-19
https://marcd.dev/articles/2019-06/mulesoft-connect
https://marcd.dev/articles/2019-06/mulesoft-connecttalktalk