How to Get Webhooks Into Your System Using Solace PubSub+ Cloud

How to Get Webhooks Into Your System Using Solace PubSub+ Cloud

Webhooks will securely get data beyond your firewall (Photo by Image by Peter H from Pixabay)

In some cases you might want to get some data from cloud based systems to an environment that doesn’t expose APIs or ports to the outside world. Using webhooks makes that a little easier, but you still need a system that accepts webhooks and is able to get them across your firewall. That is exactly where Solace PubSub+ Cloud comes in! I’ve built a small webhook forwarder app, that gets data from Solace and sends it onwards without having any of my systems exposed to the Internet.

My initial quest to get this working started with looking at PubNub to get this done, and while relatively successful there was one major feature I was missing. In some of my use cases, I needed to get the HTTP header information (like the X-GitHub-Delivery or X-Hub-Signature when using GitHub webhooks) which wasn’t possible with PubNub.

Luckily, one of my friends, Jeremy Meiss, pointed me to Solace and said that would be the answer to all my messaging needs. So, I decided to look into it and after a bit of head-scratching and reading docs, I managed to get it all working very nicely. To be fair, one of their best features is probably that it’s free 😇!

By default the Solace PubSub+ Cloud instance you get is set to “messaging” mode, which means that all non-standard HTTP headers are removed from the message when it is sent onwards. To fix that, you can set the instance to “microgateway” mode, which will add any received HTTP header fields not specifically mentioned to the Solace message as metadata. As you go into the web-console of your Solace instance, you can change the mode in Message VPN -> Connectivity. The mode should be set to “Gateway

gateway

As you set it to gateway, the Solace microgateway will add all non-standard headers to your message as JMS_Solace_HTTP_field_<header>.

The other thing I discovered, is that in most REST based requests, you’ll not be adding a correlation ID. The Microgateway however, uses that field to correlate the request ith the response. If that field is absent, the gateway will generate a field called appMessageID and use that for correlation between request and reply.

The problem is that the default session.sendReply() method takes the correlationID of the original message if you provide a message to reply to (which I found out after reading the API docs for the session object). When I manually construct the reply, and set the appropriate destination and correlation ID headers, it works perfectly. So in my case, the response should have been constructed as:

var reply = solace.SolclientFactory.createMessage();
reply.setAsReplyMessage(true);
reply.setDestination(message.getReplyTo());
reply.setCorrelationId(message.getApplicationMessageId());
subscriber.session.sendReply(null,reply)

While this sends back an empty message, the gateway will respond with an HTTP/200 status message. In my case this means that I can have GitHub send webhooks to the Intel NUC on my desk without the IT team opening firewall ports (I’m sure they’re very happy with that 😅). I think Solace made the IT and security team very happy (and they likely made a lot more companies very happy with their cool products 😎)

If you want to see my code, check out my GitHub repository and let me know your thoughts either on Twitter or here.

Let's connect

If you have any questions or comments, feel free to drop me a note on Twitter!