Suppose you want to work with a Particle (formerly Spark) device using Ruby. Suppose that you don't want to duplicate efforts (read: you're lazy), so naturally, you're using Julien Vanier's excellent ParticleRb gem. Finally, suppose you want to get the information your device is putting out via Spark.publish()
Theeeen you're going to be using webhooks.
Then you need a web server.
Now suppose you just want to test that your Particle-based device is outputting what you expect in a programmatic fashion. In other words, suppose you don't really want to run your full application.
Exactly. That's why we've developed Sorghum.
It's easier than trying to implement an EventMachine Server-Sent Events consumer. It requires minimal development and maintenance. It's light-bodied and gluten-free.
Sorghum is a stupid simple Sinatra app that mainly just provides an end-point to lob webhooks at. All it does is receive POST messages at event end-points Ohmbrewer supplies and dump what it receives into some handy locations.
Currently, Sorghum outputs webhook receiving info via the normal Sinatra logging process which means information about
webhooks being received and so forth will show up in STDERR. If you want to monkey around with actual files, there's some
settings in sorghum/config.ru
that you can uncomment to send that stuff to sorghum/logs/info.log.
Regardless, if you're so inclined, you can parse that log info to determine what time something was received.
Additionally, the last message received for a given event route is returned when you send a GET request to /last/EVENTNAME
.
That's probably where you want to point the validation steps if you're using this as a testing mock.
This last event dealie isn't great for running tests in parallel, but otherwise it provides a pretty decent way of checking for receipt of a single message as long as you account for transmission time. Again, we're going for simplicity, not production-readiness.
Finally, all messages are passed around as JSONs, in case you're interested. Just throwing that out there.
You'll want to make sure you've installed all the gems in the Gemfile, so make sure to run
bundle install
from the sorghum
directory.
Sorghum is Sinatra app built in the "Modular" style. That means you're going to want to run it via Rack. We've provided a config.ru file to make that easier. Regardless, it goes like this:
rackup -o 0.0.0.0 -p 4567 config.ru
If you're using RubyMine, the run configuration will look like this:
Server: default
IP address: 0.0.0.0
Port: 4567
Rack config file: config.ru
In order to communicate with Particle's cloud services, Sorghum will need to be accessible to the Internet at large. If you're running Sorghum on your localhost, the easiest way to do that now is to use NGrok to punch a hole down to it. Check out Brandon West's blog post on the subject for the nitty-gritty. Remember, though, the main difference here is that we aren't using SendGrid, we're using Sorghum.
Of course, you should be able to get around the NGrok requirement by running on some sort of publicly accessible web server (AWS, Heroku, etc.).
In fact, we've got a Procfile and Puma config for exactly that sort of thing... Try deploying it to Heroku - hopefully it (still) works!
If you're not down for NGrok or Heroku, your best bet is to use the rackup command above via Cloud9, but if you want to go this route, the work is left up to the reader 😉
Alternatively, we've got a Dockerfile if you want to build a Docker container and a Docker Compose file to make it even easier. All you have to do is:
docker-compose build
docker-compose up
Booyah! You should have Sorghum running on port 5000. If you don't feel like building it yourself, we've got an image on Docker Hub too, but we can't guarantee it'll be the most up-to-date (yet).
That said, check out the sorghum/test
directory. There's MiniTest tests for what we support so far.
If you add something else, make sure to create a test for it.
Mad props to Julien Vanier for writing the ParticleRb gem and Brandon West for writing just the blog post I was looking for after trying to attack this particular challenge from a few different angles. That post made for a good jumping off point.