MQTT IRC Bot/Bridge

It has been a long time since my last blog post. I was incredibly busy with HiveMQ and my focus pivoted to M2M in general and MQTT, an awesome, ultra-low footprint protocol for the Internet of Things, specifically. In the future this blog will also cover these things.

I had some spare time this weekend and decided to do some fun programming. The result was a MQTT-to-IRC or IRC-to-MQTT bridge bot. Although it is a fun project, it turns out that there are real useful use cases for that and because of that I decided to share it :)

How to use

The first step is to download or clone my Github Repository. Then, on the command line, simply run:

mvn clean package

Copy the jar file to a directory of choice and create a config.properties file with the properties according to the documentation. An example config:

broker.host=localhost
broker.port=1883
mqtt.clientId=mqttbot

irc.hostname=irc.freenode.net
irc.port=6667
irc.nickName=mqtt_bot_
irc.channels=#myircchannel1,#thesecondchannel

The next step is to install a MQTT broker locally. To do this, go to http://www.hivemq.com and download the latest version. HiveMQ is an advanced enterprise MQTT broker which is made for use cases where scalability, extensibility and reliability is key. It is also perfect for private MQTT projects. Please follow the quick start at here to install HiveMQ.

After installing the HiveMQ MQTT broker locally, start the bot and try publish a MQTT message with a tool of choice on the topic „irc/#%yircchannel1“. Now your message should appear in the corresponding IRC chat.

Of course it is also possible to get all messages via MQTT. Just subscribe to the topic „irc/%myircchannel1/messages“ and you should receive all messages of the IRC chat.

Huh? Why should I do that?

At first sight this does not make any sense why one would do that. When taking a second look, you will realize that you could connect any things to a chat with humans. You could send an IRC message when someone enters a door, when your Jenkins has build results, when a Github Commit occurs, and so on.

Also, you may probably want to get a Andorid Push Notification when someone writes your name in an IRC chat. And if you think this does not make any sense, at least it was fun hacking on :-)

Large File Downloads with JBoss Seam 2 and Servlets

Today I worked an an issue which presented users of our application a 403 error page when downloading large files which were generated on the fly. The files were delivered by a servlet and the files were directly copied to the ServletOutputStream, so the files were streamed instead of holding them in memory.

After some debugging it turned out, that the files were not streamed since the Seam Ajax4JSF Filter doesn’t allow to stream files and this resulted in OutOfMemoryExceptions. There are a few ways how to disable or extend the Ajax4JSF Filter (see this Seam Forum Thread).

Since all our download resources are mapped to servlets which resides in the „/media/*“ path, it was pretty easy to just enable the Ajax4JSF Filter for all paths except the „/media/*“ paths. To achieve this, just add to your components.xml:

<web:ajax4jsf-filter regex-url-pattern="^(?:[^/]|/(?!media/))*$"/>

Set Context Root for a JavaEE 6 Application with JBoss 7.1

Per default, a Web Application which is packaged as a WAR file is mapped to „http://jbossurl:port/war_file_name“ when deployed to JBoss AS 7.1. We wanted the application to be mapped to the root context instead of the file name. It turns out, that this is pretty easy to achieve:

  1. Edit standalone.xml in the JBoss configuration directory. Edit the relevant part of the file like this:
    <subsystem xmlns="urn:jboss:domain:web:1.0" default-virtual-server="default-host">
        <connector name="http" protocol="HTTP/1.1" socket-binding="http" scheme="http"/>
        <virtual-server name="default-host" enable-welcome-root="false">

    The important part is the enable-welcome-root=“false“.

  2. Create a file „jboss-web.xml“ in the WEB-INF folder of your application.
  3. Add the following to the file:

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-web>
        <context-root>/</context-root>
    </jboss-web>

Now your Application will be mapped to the context-root of the Application Server and should be accessible with „http://jbossurl:port“.

Programatically Login User with Seam 2 Security Framework

This is a quick one:

When you want to login a user programmatically without checking if the credentials are right or the user is in the IdentityStore with Seam 2, that is pretty easy.

 
final Principal principal = new SimplePrincipal("username");
identity.acceptExternallyAuthenticatedPrincipal(principal);
identity.authenticate();

This will override the Seam 2 Security Framework authentication mechanism and a user with the given username will be logged in, even if the user is not in the IdentityStore of the Application.

I use this regularly when I have some sort of administration interface where I cannot use the default IdentityStore of the application. In this case I provide an own implementation of the required authentication mechanism and just log in the the user with the approach described above. When doing this I add a role to the logged in user (via identity.addRole("myRole")), so I can use all the Seam goodies like the Authorization Annotations (@Restrict) or checks like Identity.loggedIn.

Autostart resque for Gitlab on CentOS 6.2 with RVM installed

In my previous blog post I described how to install Gitlab on a CentOS 6.2 machine. The Resque demon did not start automatically, so I thought I’ll create a little startup script for the resque.sh in the /var/www/gitlabhq directory, so it would autostart. As it turned out, it was harder than expected, because I use RVM. I assume, that you use the installation script I linked in my last blog post to install gitlab, otherwise the following steps could be different for you…. Here are the necessary steps to get it working:

Weiterlesen

Installing Gitlab on CentOS 6.2

I had a hard time installing Gitlab on a CentOS 6.2 machine and I tried several tutorials. I was lucky and I found an awesome installation script by Mattias Ohlsson which installs Ruby, Gitlab, Gitoline and Apache with the Passenger Module. On my machine I was not able to create new repositories with Gitlab.

The solution for the problem was, that the ‚git‘ user had to be added to the AllowedUsers in /etc/ssh/sshd_config .

SLF4J Logger Injection with Guice

I experimented with Google Guice Custom Injections because I wanted to inject a Logger to my guicified application. There is a great part in the Guice documentation about Custom Logger Injection, but in my case I wanted a SLF4J Logger with Logback as implementation. The example in the Guice Wiki is with Log4j Injection.

Here is how I wanted to inject loggers:

1
2
3
4
5
6
@Log
Logger log;
 
public void doSomething{
  log.info("Logmessage");
}

Weiterlesen

Different ways to redirect with JSF and Seam

This is just a quick reminder for myself how to implement programmatic redirects with JBoss Seam and JSF.

I will describe three different techniques:

  • Redirecting to a 404 Error Page from a JSF Backing Bean
  • Redirecting to an external Website
  • Redirecting to a JSF view in a Seam Application

Weiterlesen

Allowed Characters for Javascript Variables

I am playing with the JDK Javascript API (JSR 223) and I wanted to check out the replacement of variables in a String. Then I suddenly got this error:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: missing ; before statement (<Unknown source>#1) in <Unknown source> at line number 1

After some reseach I found out, that my variables did contain invalid characters in my case the variable contained a .

So the Regular Expression for valid Javascript variable names is:

[a-zA-Z_$][0-9a-zA-Z_$]*

It is also possible to use any unicode characters for variables, but of course this is not recommended.