io.crate.mqtt.netty.MqttMessageLogger.java Source code

Java tutorial

Introduction

Here is the source code for io.crate.mqtt.netty.MqttMessageLogger.java

Source

/*
 * This file is part of a module with proprietary Enterprise Features.
 *
 * Licensed to Crate.io Inc. ("Crate.io") under one or more contributor
 * license agreements.  See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 *
 * Unauthorized copying of this file, via any medium is strictly prohibited.
 *
 * To use this file, Crate.io must have given you permission to enable and
 * use such Enterprise Features and you must have a valid Enterprise or
 * Subscription Agreement with Crate.io.  If you enable or use the Enterprise
 * Features, you represent and warrant that you have a valid Enterprise or
 * Subscription Agreement with Crate.io.  Your use of the Enterprise Features
 * if governed by the terms and conditions of your Enterprise or Subscription
 * Agreement with Crate.io.
 *
 * This code is derived from https://github.com/andsel/moquette/blob/master/broker/src/main/java/io/moquette/server/netty/metrics/MQTTMessageLogger.java
 */

package io.crate.mqtt.netty;

import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader;
import io.netty.handler.codec.mqtt.MqttMessageType;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import io.netty.handler.codec.mqtt.MqttSubAckMessage;
import io.netty.handler.codec.mqtt.MqttSubscribeMessage;
import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;

import java.util.List;

@ChannelHandler.Sharable
public class MqttMessageLogger extends ChannelDuplexHandler {

    private static final String DIRECTION_READ = "C->B";
    private static final String DIRECTION_WRITE = "C<-B";

    private final Logger logger;

    MqttMessageLogger(Settings settings) {
        logger = Loggers.getLogger(getClass(), settings);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object message) {
        logMQTTMessage(ctx, message, DIRECTION_READ);
        ctx.fireChannelRead(message);
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        logMQTTMessage(ctx, msg, DIRECTION_WRITE);
        ctx.write(msg, promise);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String clientID = NettyUtils.clientID(ctx.channel());
        if (clientID != null && !clientID.isEmpty() && logger.isTraceEnabled()) {
            logger.trace("Channel closed <{}>", clientID);
        }
        ctx.fireChannelInactive();
    }

    private void logMQTTMessage(ChannelHandlerContext ctx, Object message, String direction) {
        if (logger.isTraceEnabled() && message instanceof MqttMessage) {
            MqttMessage msg = (MqttMessage) message;
            String clientID = NettyUtils.clientID(ctx.channel());
            MqttMessageType messageType = msg.fixedHeader().messageType();
            switch (messageType) {
            case CONNECT:
            case CONNACK:
            case PINGREQ:
            case PINGRESP:
            case DISCONNECT:
                logger.trace("{} {} <{}>", direction, messageType, clientID);
                break;
            case SUBSCRIBE:
                MqttSubscribeMessage subscribe = (MqttSubscribeMessage) msg;
                logger.trace("{} SUBSCRIBE <{}> to topics {}", direction, clientID,
                        subscribe.payload().topicSubscriptions());
                break;
            case UNSUBSCRIBE:
                MqttUnsubscribeMessage unsubscribe = (MqttUnsubscribeMessage) msg;
                logger.trace("{} UNSUBSCRIBE <{}> to topics <{}>", direction, clientID,
                        unsubscribe.payload().topics());
                break;
            case PUBLISH:
                MqttPublishMessage publish = (MqttPublishMessage) msg;
                logger.trace("{} PUBLISH <{}> to topics <{}>", direction, clientID,
                        publish.variableHeader().topicName());
                break;
            case PUBREC:
            case PUBCOMP:
            case PUBREL:
            case PUBACK:
            case UNSUBACK:
                logger.trace("{} {} <{}> packetID <{}>", direction, messageType, clientID, messageId(msg));
                break;
            case SUBACK:
                MqttSubAckMessage suback = (MqttSubAckMessage) msg;
                List<Integer> grantedQoSLevels = suback.payload().grantedQoSLevels();
                logger.trace("{} SUBACK <{}> packetID <{}>, grantedQoses {}", direction, clientID, messageId(msg),
                        grantedQoSLevels);
                break;
            default:
                logger.trace("{} {} <{}> Unknown message type received.", direction, messageType, clientID);
            }
        }
    }

    private static int messageId(MqttMessage msg) {
        return ((MqttMessageIdVariableHeader) msg.variableHeader()).messageId();
    }
}