de.dobermai.mqttbot.BotController.java Source code

Java tutorial

Introduction

Here is the source code for de.dobermai.mqttbot.BotController.java

Source

/*
 * Copyright 2013 Dominik Obermaier <dominik.obermaier@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.dobermai.mqttbot;

import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.AbstractIdleService;
import com.netflix.governator.lifecycle.LifecycleManager;
import de.dobermai.mqttbot.config.IRCProperties;
import de.dobermai.mqttbot.config.MQTTProperties;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.UTF8Buffer;
import org.fusesource.mqtt.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.text.MessageFormat;

/**
 * @author Dominik Obermaier
 */
public class BotController extends AbstractIdleService {

    private static final Logger log = LoggerFactory.getLogger(BotController.class);

    private final CallbackConnection mqttConnection;
    private final MqttBot bot;
    private final IRCProperties ircProperties;
    private final MQTTProperties mqttProperties;
    private final LifecycleManager lifecycleManager;

    @Inject
    public BotController(final CallbackConnection mqttConnection, final MqttBot bot,
            final IRCProperties ircProperties, final MQTTProperties mqttProperties,
            final LifecycleManager lifecycleManager) {
        this.mqttConnection = mqttConnection;
        this.bot = bot;
        this.ircProperties = ircProperties;
        this.mqttProperties = mqttProperties;
        this.lifecycleManager = lifecycleManager;
    }

    @Override
    protected void startUp() throws Exception {
        addShutdownHooks();

        mqttConnection.listener(new Listener() {
            @Override
            public void onConnected() {
                log.info("Connected to MQTT broker successfully");
            }

            @Override
            public void onDisconnected() {
                log.info("Disconnected from MQTT broker");
            }

            @Override
            public void onPublish(UTF8Buffer topic, Buffer body, Runnable ack) {

                final String channel = Iterables.getLast(Splitter.on("/").trimResults().split(topic.toString()))
                        .replace(mqttProperties.getMqttIrcChannelPrefix(), "#");

                ack.run();
                log.debug("Received message on topic {} with payload {}. Writing to IRC channel {}",
                        topic.toString(), body.utf8().toString(), channel);
                bot.sendMessage(channel, body.utf8().toString());
            }

            @Override
            public void onFailure(Throwable value) {
                log.error("An error occured", value);
            }
        });

        log.info("Connecting to MQTT Broker");
        mqttConnection.connect(new Callback<Void>() {
            @Override
            public void onSuccess(Void value) {
                log.debug("Connected to MQTT broker successfully");
            }

            @Override
            public void onFailure(Throwable value) {
                log.error("Could not connect to MQTT broker.", value);
            }
        });

        log.info("Connecting to IRC {} on port {}", ircProperties.getIrcHostName(), ircProperties.getPort());
        bot.connect(ircProperties.getIrcHostName(), ircProperties.getPort());

        for (String channel : ircProperties.getIrcChannels()) {
            bot.joinChannel(channel);
            log.info("Joined channel {}", channel);

            final String topic = replaceChannelPrefixes(
                    MessageFormat.format("{0}/{1}", mqttProperties.getMqttTopicPrefix(), channel));
            log.info("Subscribing to MQTT topic {}", topic);
            mqttConnection.subscribe(new Topic[] { new Topic(topic, QoS.EXACTLY_ONCE) }, new Callback<byte[]>() {
                @Override
                public void onSuccess(byte[] value) {
                    log.debug("Successfully subscribed to {}", topic);
                }

                @Override
                public void onFailure(Throwable value) {
                    log.error("There was an error connecting to topic {}", topic, value);
                }
            });
        }
        log.info("Connected to IRC {} successfully", ircProperties.getIrcHostName());

    }

    @Override
    protected void shutDown() throws Exception {

        log.info("Disconnecting from MQTT broker");
        mqttConnection.disconnect(new Callback<Void>() {
            @Override
            public void onSuccess(Void value) {
                log.info("Disconnected from MQTT broker successfully");
            }

            @Override
            public void onFailure(Throwable value) {
                log.warn("There was an error while disconnecting from the MQTT broker", value);
            }
        });

        log.info("Disconnecting from IRC");
        if (bot.isConnected()) {
            bot.disconnect();
        }
    }

    private void addShutdownHooks() {

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    shutDown();
                    log.debug("Shutting down LifecycleManager");
                    lifecycleManager.close();

                } catch (Exception e) {
                    //log.error("Error while shutting down:", e);
                    e.printStackTrace();
                }
            }
        }));
    }

    private String replaceChannelPrefixes(final String channel) {
        return channel.replace("#", mqttProperties.getMqttIrcChannelPrefix());
    }

}