diff --git a/README.adoc b/README.adoc index ae02385..a1a01de 100644 --- a/README.adoc +++ b/README.adoc @@ -73,6 +73,7 @@ An example configuration file is available in `conf/examples/`, which removes th |verbose |Log detailed information about an MQTT event | false |payload |Log the payload of a message | true +|json |Log the MQTT events in JSON format | false |=== Normally, events only log important information. @@ -83,6 +84,8 @@ CAUTION: use `verbose=true` very carefully as it will flood your log immediately Set the `payload` property to `false` if you want to suppress logging payloads (i.e. for publish-received, publish-send, and will messages). +Set the `json` property to `true` if you want to log the MQTT events in a JSON format. + == First Steps Connect with an {hivemq-blog-tools}[MQTT client] of your choice. @@ -108,6 +111,23 @@ User Properties: [Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value [Name: 'name2', Value: 'value2'], Will Delay: '100' }" ---- +=== Verbose CONNECT message with payload in JSON + +[source,bash] +---- +2025-04-22 16:55:37,192 INFO - {"Event": "Received CONNECT", "Client": "clientid", "Protocol version": "V_5", "Clean Start": "true", +"Session Expiry Interval": "0", "Keep Alive": "60", "Maximum Packet Size": "268435460", +"Receive Maximum": "65535", "Topic Alias Maximum": "0", "Request Problem Information": "true", +"Request Response Information": "false", "Username": "username", "Password": "password", +"Auth Method": "null", "Auth Data (Base64)": "null", +"User Properties (2)": [{"Name (0)": "name0", "Value (0)": "value0"}, {"Name (1)": "name1", "Value (1)": "value1"}], +"Will": { "Topic": "willtopic", "Payload (Base64)": "d2lsbGRhdGE=", "QoS": "0", "Retained": "false", "Message Expiry Interval": "1234", +"Duplicate Delivery": "false", "Correlation Data": "ZGF0YQ==", "Response Topic": "responseTopic", +"Content Type": "content-type", "Payload Format Indicator": "UTF_8", "Subscription Identifiers": "[]", +"User Properties (2)": [{"Name (0)": "name0", "Value (0)": "value0"}, +{"Name (1)": "name1", "Value (1)": "value1"}], "Will Delay": "100" }} +---- + === Basic CONNECT message [source,bash] @@ -115,6 +135,13 @@ User Properties: [Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value "17:26:23.602 INFO - Received CONNECT from client 'clientid': Protocol version: 'V_5', Clean Start: 'false', Session Expiry Interval: '10000'" ---- +=== Basic CONNECT message in JSON + +[source,bash] +---- +2025-04-17 15:42:22,616 INFO - {"Event": "Received CONNECT", "Client": "test-client", "Protocol version": "V_5", "Clean Start": "true", "Session Expiry Interval": "0"} +---- + == Need Help? If you encounter any problems, we are happy to help. diff --git a/gradle.properties b/gradle.properties index 2d48fba..2da9394 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.2.1 +version=1.2.2 diff --git a/src/hivemq-extension/conf/examples/config.xml b/src/hivemq-extension/conf/examples/config.xml index 7c73a7e..b8a02ee 100644 --- a/src/hivemq-extension/conf/examples/config.xml +++ b/src/hivemq-extension/conf/examples/config.xml @@ -9,6 +9,7 @@ false true + false false diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigJsonIT.java new file mode 100644 index 0000000..6823421 --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigJsonIT.java @@ -0,0 +1,168 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; + +/** + * @since 1.1.3 + */ +@Testcontainers +public class FullConfigJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigJson.properties"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/mqttMessageLog.properties") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\", \"Keep Alive\": \"60\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"65535\", \"Topic Alias Maximum\": \"0\", \"Request Problem Information\": \"true\", \"Request Response Information\": \"false\", \"Username\": \"null\", \"Password\": \"null\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\", \"Will\": { \"Topic\": \"will\", \"Payload (Base64)\": \"d2lsbFBheWxvYWQ=\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"willResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"willProperty\", \"Value (0)\": \"willValue\"}], \"Will Delay\": \"50000\" }}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\", \"Session Expiry Interval\": \"null\", \"Assigned ClientId\": \"null\", \"Maximum QoS\": \"EXACTLY_ONCE\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"10\", \"Topic Alias Maximum\": \"5\", \"Reason String\": \"null\", \"Response Information\": \"null\", \"Server Keep Alive\": \"null\", \"Server Reference\": \"null\", \"Shared Subscription Available\": \"true\", \"Wildcards Available\": \"true\", \"Retain Available\": \"true\", \"Subscription Identifiers Available\": \"true\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\", \"Retain As Published\": \"false\", \"No Local\": \"false\", \"Retain Handling\": \"SEND\"} ], \"Subscription Identifier\": \"1\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ], \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\", \"Reason String\": \"null\", \"Server Reference\": \"null\", \"Session Expiry\": \"null\", \"User Properties\": \"null\"}")); + } +} diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoPayloadJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoPayloadJsonIT.java new file mode 100644 index 0000000..e3f804c --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoPayloadJsonIT.java @@ -0,0 +1,176 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * @since 1.1.6 + */ +@Testcontainers +public class FullConfigNoPayloadJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigNoPayloadJson.properties"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/mqttMessageLog.properties") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\", \"Keep Alive\": \"60\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"65535\", \"Topic Alias Maximum\": \"0\", \"Request Problem Information\": \"true\", \"Request Response Information\": \"false\", \"Username\": \"null\", \"Password\": \"null\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\", \"Will\": { \"Topic\": \"will\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"willResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"willProperty\", \"Value (0)\": \"willValue\"}], \"Will Delay\": \"50000\" }}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\", \"Session Expiry Interval\": \"null\", \"Assigned ClientId\": \"null\", \"Maximum QoS\": \"EXACTLY_ONCE\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"10\", \"Topic Alias Maximum\": \"5\", \"Reason String\": \"null\", \"Response Information\": \"null\", \"Server Keep Alive\": \"null\", \"Server Reference\": \"null\", \"Shared Subscription Available\": \"true\", \"Wildcards Available\": \"true\", \"Retain Available\": \"true\", \"Subscription Identifiers Available\": \"true\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\", \"Retain As Published\": \"false\", \"No Local\": \"false\", \"Retain Handling\": \"SEND\"} ], \"Subscription Identifier\": \"1\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ], \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\", \"Reason String\": \"null\", \"Server Reference\": \"null\", \"Session Expiry\": \"null\", \"User Properties\": \"null\"}")); + + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDE=\"")); + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDI=\"")); + } +} diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoPayloadNoVerboseJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoPayloadNoVerboseJsonIT.java new file mode 100644 index 0000000..332fd37 --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoPayloadNoVerboseJsonIT.java @@ -0,0 +1,176 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * @since 1.1.6 + */ +@Testcontainers +public class FullConfigNoPayloadNoVerboseJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigNoPayloadNoVerboseJson.properties"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/mqttMessageLog.properties") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ]}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ]}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\"}")); + + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDE=\"")); + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDI=\"")); + } +} diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoVerboseJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoVerboseJsonIT.java new file mode 100644 index 0000000..13a217b --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigNoVerboseJsonIT.java @@ -0,0 +1,176 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @since 1.1.6 + */ +@Testcontainers +public class FullConfigNoVerboseJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigNoVerboseJson.properties"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/mqttMessageLog.properties") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ]}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ]}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\"}")); + + assertTrue(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDE=\"")); + assertTrue(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDI=\"")); + } +} diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlJsonIT.java new file mode 100644 index 0000000..c4c1552 --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlJsonIT.java @@ -0,0 +1,168 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; + +/** + * @since 1.2.0 + */ +@Testcontainers +public class FullConfigXmlJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigJson.xml"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/conf/config.xml") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\", \"Keep Alive\": \"60\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"65535\", \"Topic Alias Maximum\": \"0\", \"Request Problem Information\": \"true\", \"Request Response Information\": \"false\", \"Username\": \"null\", \"Password\": \"null\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\", \"Will\": { \"Topic\": \"will\", \"Payload (Base64)\": \"d2lsbFBheWxvYWQ=\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"willResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"willProperty\", \"Value (0)\": \"willValue\"}], \"Will Delay\": \"50000\" }}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\", \"Session Expiry Interval\": \"null\", \"Assigned ClientId\": \"null\", \"Maximum QoS\": \"EXACTLY_ONCE\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"10\", \"Topic Alias Maximum\": \"5\", \"Reason String\": \"null\", \"Response Information\": \"null\", \"Server Keep Alive\": \"null\", \"Server Reference\": \"null\", \"Shared Subscription Available\": \"true\", \"Wildcards Available\": \"true\", \"Retain Available\": \"true\", \"Subscription Identifiers Available\": \"true\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\", \"Retain As Published\": \"false\", \"No Local\": \"false\", \"Retain Handling\": \"SEND\"} ], \"Subscription Identifier\": \"1\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ], \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\", \"Reason String\": \"null\", \"Server Reference\": \"null\", \"Session Expiry\": \"null\", \"User Properties\": \"null\"}")); + } +} diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoPayloadJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoPayloadJsonIT.java new file mode 100644 index 0000000..c034ad3 --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoPayloadJsonIT.java @@ -0,0 +1,176 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * @since 1.2.0 + */ +@Testcontainers +public class FullConfigXmlNoPayloadJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigNoPayloadJson.xml"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/conf/config.xml") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\", \"Keep Alive\": \"60\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"65535\", \"Topic Alias Maximum\": \"0\", \"Request Problem Information\": \"true\", \"Request Response Information\": \"false\", \"Username\": \"null\", \"Password\": \"null\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\", \"Will\": { \"Topic\": \"will\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"willResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"willProperty\", \"Value (0)\": \"willValue\"}], \"Will Delay\": \"50000\" }}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\", \"Session Expiry Interval\": \"null\", \"Assigned ClientId\": \"null\", \"Maximum QoS\": \"EXACTLY_ONCE\", \"Maximum Packet Size\": \"268435460\", \"Receive Maximum\": \"10\", \"Topic Alias Maximum\": \"5\", \"Reason String\": \"null\", \"Response Information\": \"null\", \"Server Keep Alive\": \"null\", \"Server Reference\": \"null\", \"Shared Subscription Available\": \"true\", \"Wildcards Available\": \"true\", \"Retain Available\": \"true\", \"Subscription Identifiers Available\": \"true\", \"Auth Method\": \"null\", \"Auth Data (Base64)\": \"null\", \"User Properties\": \"null\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\", \"Retain As Published\": \"false\", \"No Local\": \"false\", \"Retain Handling\": \"SEND\"} ], \"Subscription Identifier\": \"1\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\", \"Message Expiry Interval\": \"10000\", \"Duplicate Delivery\": \"false\", \"Correlation Data\": \"d2lsbENvcnJlbGF0aW9uRGF0YQ==\", \"Response Topic\": \"publishResponse\", \"Content Type\": \"text/plain\", \"Payload Format Indicator\": \"UTF_8\", \"Subscription Identifiers\": \"[1]\", \"User Properties (1)\": [{\"Name (0)\": \"publishProperty\", \"Value (0)\": \"publishValue\"}]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ], \"User Properties\": \"null\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ], \"Reason String\": \"null\", \"User Properties\": \"null\"}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\", \"Reason String\": \"null\", \"Server Reference\": \"null\", \"Session Expiry\": \"null\", \"User Properties\": \"null\"}")); + + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDE=\"")); + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDI=\"")); + } +} diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoPayloadNoVerboseJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoPayloadNoVerboseJsonIT.java new file mode 100644 index 0000000..3bc24e1 --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoPayloadNoVerboseJsonIT.java @@ -0,0 +1,176 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * @since 1.2.0 + */ +@Testcontainers +public class FullConfigXmlNoPayloadNoVerboseJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigNoPayloadNoVerboseJson.xml"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/conf/config.xml") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ]}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ]}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\"}")); + + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDE=\"")); + assertFalse(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDI=\"")); + } +} diff --git a/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoVerboseJsonIT.java b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoVerboseJsonIT.java new file mode 100644 index 0000000..c1c7a3a --- /dev/null +++ b/src/integrationTest/java/com/hivemq/extensions/log/FullConfigXmlNoVerboseJsonIT.java @@ -0,0 +1,176 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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 com.hivemq.extensions.log; + +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; +import io.github.sgtsilvio.gradle.oci.junit.jupiter.OciImages; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.testcontainers.hivemq.HiveMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; + +import java.nio.charset.StandardCharsets; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @since 1.2.0 + */ +@Testcontainers +public class FullConfigXmlNoVerboseJsonIT { + + @Container + final @NotNull HiveMQContainer hivemq = + new HiveMQContainer(OciImages.getImageName("hivemq/extensions/hivemq-mqtt-message-log-extension") + .asCompatibleSubstituteFor("hivemq/hivemq4")) // + .withCopyToContainer(MountableFile.forClasspathResource("fullConfigNoVerboseJson.xml"), + "/opt/hivemq/extensions/hivemq-mqtt-message-log-extension/conf/config.xml") + .withLogConsumer(outputFrame -> System.out.print("HiveMQ: " + outputFrame.getUtf8String())); + + @Test + void test() { + final Mqtt5BlockingClient client = Mqtt5Client.builder() + .identifier("test-client") + .serverHost(hivemq.getHost()) + .serverPort(hivemq.getMqttPort()) + .buildBlocking(); + + client.connectWith() + .willPublish() + .topic("will") + .qos(MqttQos.EXACTLY_ONCE) + .payload("willPayload".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("willResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("willProperty", "willValue") + .applyUserProperties() + .delayInterval(50_000) + .applyWillPublish() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received CONNECT\", \"Client\": \"test-client\", \"Protocol version\": \"V_5\", \"Clean Start\": \"true\", \"Session Expiry Interval\": \"0\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent CONNACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\", \"Session Present\": \"false\"}")); + + client.subscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received SUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [{\"Topic\": \"#\", \"QoS\": \"2\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent SUBACK\", \"Client\": \"test-client\", \"Suback Reason Codes (1)\": [{\"Reason Code\": \"GRANTED_QOS_2\"} ]}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.EXACTLY_ONCE) + .payload("payload1".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDE=\", \"QoS\": \"2\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBREC\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBREL\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBCOMP\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.publishWith() + .topic("publish") + .qos(MqttQos.AT_LEAST_ONCE) + .payload("payload2".getBytes(StandardCharsets.UTF_8)) + .contentType("text/plain") + .correlationData("willCorrelationData".getBytes(StandardCharsets.UTF_8)) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .responseTopic("publishResponse") + .retain(false) + .messageExpiryInterval(10_000) + .userProperties() + .add("publishProperty", "publishValue") + .applyUserProperties() + .send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent PUBLISH\", \"Client\": \"test-client\", \"Topic\": \"publish\", \"Payload (Base64)\": \"cGF5bG9hZDI=\", \"QoS\": \"1\", \"Retained\": \"false\"}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received PUBACK\", \"Client\": \"test-client\", \"Reason Code\": \"SUCCESS\"}")); + + client.unsubscribeWith().topicFilter("#").send(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received UNSUBSCRIBE\", \"Client\": \"test-client\", \"Topics\": [ {\"Topic\": \"#\"} ]}")); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Sent UNSUBACK\", \"Client\": \"test-client\", \"Unsuback Reason Codes (1)\": [ {\"Reason Code\": \"SUCCESS\"} ]}")); + + client.disconnect(); + await().until(() -> hivemq.getLogs() + .contains( + "{\"Event\": \"Received DISCONNECT\", \"Client\": \"test-client\", \"Reason Code\": \"NORMAL_DISCONNECTION\"}")); + + assertTrue(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDE=\"")); + assertTrue(hivemq.getLogs() + .contains( + "\"Payload (Base64)\": \"cGF5bG9hZDI=\"")); + } +} diff --git a/src/integrationTest/resources/fullConfig.properties b/src/integrationTest/resources/fullConfig.properties index 4b865b5..b168da0 100644 --- a/src/integrationTest/resources/fullConfig.properties +++ b/src/integrationTest/resources/fullConfig.properties @@ -15,6 +15,7 @@ # verbose=true payload=true +json=false publish-received=true publish-send=true client-connect=true diff --git a/src/integrationTest/resources/fullConfig.xml b/src/integrationTest/resources/fullConfig.xml index 3e6fb45..54d4ffe 100644 --- a/src/integrationTest/resources/fullConfig.xml +++ b/src/integrationTest/resources/fullConfig.xml @@ -20,6 +20,7 @@ xsi:noNamespaceSchemaLocation="../../main/resources/config.xsd"> true true + false true true true diff --git a/src/integrationTest/resources/fullConfigJson.properties b/src/integrationTest/resources/fullConfigJson.properties new file mode 100644 index 0000000..cc64bf0 --- /dev/null +++ b/src/integrationTest/resources/fullConfigJson.properties @@ -0,0 +1,37 @@ +# +# Copyright 2019-present HiveMQ GmbH +# +# 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. +# +verbose=true +payload=true +json=true +publish-received=true +publish-send=true +client-connect=true +connack-send=true +client-disconnect=true +subscribe-received=true +suback-send=true +unsubscribe-received=true +unsuback-send=true +ping-request-received=true +ping-response-send=true +puback-received=true +puback-send=true +pubrec-received=true +pubrec-send=true +pubrel-received=true +pubrel-send=true +pubcomp-received=true +pubcomp-send=true diff --git a/src/integrationTest/resources/fullConfigJson.xml b/src/integrationTest/resources/fullConfigJson.xml new file mode 100644 index 0000000..9cb3cdb --- /dev/null +++ b/src/integrationTest/resources/fullConfigJson.xml @@ -0,0 +1,43 @@ + + + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + diff --git a/src/integrationTest/resources/fullConfigNoPayload.properties b/src/integrationTest/resources/fullConfigNoPayload.properties index 6321166..68a0902 100644 --- a/src/integrationTest/resources/fullConfigNoPayload.properties +++ b/src/integrationTest/resources/fullConfigNoPayload.properties @@ -15,6 +15,7 @@ # verbose=true payload=false +json=false publish-received=true publish-send=true client-connect=true diff --git a/src/integrationTest/resources/fullConfigNoPayload.xml b/src/integrationTest/resources/fullConfigNoPayload.xml index 048efb7..f71d9c6 100644 --- a/src/integrationTest/resources/fullConfigNoPayload.xml +++ b/src/integrationTest/resources/fullConfigNoPayload.xml @@ -20,6 +20,7 @@ xsi:noNamespaceSchemaLocation="../../main/resources/config.xsd"> true false + false true true true diff --git a/src/integrationTest/resources/fullConfigNoPayloadJson.properties b/src/integrationTest/resources/fullConfigNoPayloadJson.properties new file mode 100644 index 0000000..d34bb31 --- /dev/null +++ b/src/integrationTest/resources/fullConfigNoPayloadJson.properties @@ -0,0 +1,37 @@ +# +# Copyright 2019-present HiveMQ GmbH +# +# 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. +# +verbose=true +payload=false +json=true +publish-received=true +publish-send=true +client-connect=true +connack-send=true +client-disconnect=true +subscribe-received=true +suback-send=true +unsubscribe-received=true +unsuback-send=true +ping-request-received=true +ping-response-send=true +puback-received=true +puback-send=true +pubrec-received=true +pubrec-send=true +pubrel-received=true +pubrel-send=true +pubcomp-received=true +pubcomp-send=true diff --git a/src/integrationTest/resources/fullConfigNoPayloadJson.xml b/src/integrationTest/resources/fullConfigNoPayloadJson.xml new file mode 100644 index 0000000..5595bea --- /dev/null +++ b/src/integrationTest/resources/fullConfigNoPayloadJson.xml @@ -0,0 +1,43 @@ + + + + true + false + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + diff --git a/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.properties b/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.properties index 822eb26..32b7e2d 100644 --- a/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.properties +++ b/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.properties @@ -15,6 +15,7 @@ # verbose=false payload=false +json=false publish-received=true publish-send=true client-connect=true diff --git a/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.xml b/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.xml index 557b16e..d602d54 100644 --- a/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.xml +++ b/src/integrationTest/resources/fullConfigNoPayloadNoVerbose.xml @@ -20,6 +20,7 @@ xsi:noNamespaceSchemaLocation="../../main/resources/config.xsd"> false false + false true true true diff --git a/src/integrationTest/resources/fullConfigNoPayloadNoVerboseJson.properties b/src/integrationTest/resources/fullConfigNoPayloadNoVerboseJson.properties new file mode 100644 index 0000000..d8d18e7 --- /dev/null +++ b/src/integrationTest/resources/fullConfigNoPayloadNoVerboseJson.properties @@ -0,0 +1,37 @@ +# +# Copyright 2019-present HiveMQ GmbH +# +# 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. +# +verbose=false +payload=false +json=true +publish-received=true +publish-send=true +client-connect=true +connack-send=true +client-disconnect=true +subscribe-received=true +suback-send=true +unsubscribe-received=true +unsuback-send=true +ping-request-received=true +ping-response-send=true +puback-received=true +puback-send=true +pubrec-received=true +pubrec-send=true +pubrel-received=true +pubrel-send=true +pubcomp-received=true +pubcomp-send=true diff --git a/src/integrationTest/resources/fullConfigNoPayloadNoVerboseJson.xml b/src/integrationTest/resources/fullConfigNoPayloadNoVerboseJson.xml new file mode 100644 index 0000000..366c517 --- /dev/null +++ b/src/integrationTest/resources/fullConfigNoPayloadNoVerboseJson.xml @@ -0,0 +1,43 @@ + + + + false + false + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + diff --git a/src/integrationTest/resources/fullConfigNoVerbose.properties b/src/integrationTest/resources/fullConfigNoVerbose.properties index 6463635..cb0b58a 100644 --- a/src/integrationTest/resources/fullConfigNoVerbose.properties +++ b/src/integrationTest/resources/fullConfigNoVerbose.properties @@ -15,6 +15,7 @@ # verbose=false payload=true +json=false publish-received=true publish-send=true client-connect=true diff --git a/src/integrationTest/resources/fullConfigNoVerbose.xml b/src/integrationTest/resources/fullConfigNoVerbose.xml index 9fe4b7a..a4bf090 100644 --- a/src/integrationTest/resources/fullConfigNoVerbose.xml +++ b/src/integrationTest/resources/fullConfigNoVerbose.xml @@ -20,6 +20,7 @@ xsi:noNamespaceSchemaLocation="../../main/resources/config.xsd"> false true + false true true true diff --git a/src/integrationTest/resources/fullConfigNoVerboseJson.properties b/src/integrationTest/resources/fullConfigNoVerboseJson.properties new file mode 100644 index 0000000..3e35853 --- /dev/null +++ b/src/integrationTest/resources/fullConfigNoVerboseJson.properties @@ -0,0 +1,37 @@ +# +# Copyright 2019-present HiveMQ GmbH +# +# 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. +# +verbose=false +payload=true +json=true +publish-received=true +publish-send=true +client-connect=true +connack-send=true +client-disconnect=true +subscribe-received=true +suback-send=true +unsubscribe-received=true +unsuback-send=true +ping-request-received=true +ping-response-send=true +puback-received=true +puback-send=true +pubrec-received=true +pubrec-send=true +pubrel-received=true +pubrel-send=true +pubcomp-received=true +pubcomp-send=true diff --git a/src/integrationTest/resources/fullConfigNoVerboseJson.xml b/src/integrationTest/resources/fullConfigNoVerboseJson.xml new file mode 100644 index 0000000..b934ff1 --- /dev/null +++ b/src/integrationTest/resources/fullConfigNoVerboseJson.xml @@ -0,0 +1,43 @@ + + + + false + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfig.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfig.java index 1b035c7..af6e5ca 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfig.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfig.java @@ -62,6 +62,8 @@ public interface ExtensionConfig { boolean isPayload(); + boolean isJson(); + default boolean allDisabled() { return !isClientConnect() && !isClientDisconnect() && diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigProperties.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigProperties.java index f33ec56..14da81a 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigProperties.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigProperties.java @@ -26,6 +26,7 @@ public class ExtensionConfigProperties implements ExtensionConfig { static final @NotNull String FALSE = "false"; static final @NotNull String VERBOSE = "verbose"; static final @NotNull String PAYLOAD = "payload"; + static final @NotNull String JSON = "json"; static final @NotNull String CLIENT_CONNECT = "client-connect"; static final @NotNull String CLIENT_DISCONNECT = "client-disconnect"; static final @NotNull String CONNACK_SEND = "connack-send"; @@ -136,6 +137,10 @@ public boolean isPayload() { return getForKey(PAYLOAD); } + public boolean isJson() { + return getForKey(JSON); + } + private boolean getForKey(final @NotNull String key) { return properties.getProperty(key, TRUE).equalsIgnoreCase(TRUE); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReader.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReader.java index 64db534..9d32b9f 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReader.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReader.java @@ -33,6 +33,7 @@ import static com.hivemq.extensions.log.mqtt.message.config.ExtensionConfigProperties.CLIENT_DISCONNECT; import static com.hivemq.extensions.log.mqtt.message.config.ExtensionConfigProperties.CONNACK_SEND; import static com.hivemq.extensions.log.mqtt.message.config.ExtensionConfigProperties.FALSE; +import static com.hivemq.extensions.log.mqtt.message.config.ExtensionConfigProperties.JSON; import static com.hivemq.extensions.log.mqtt.message.config.ExtensionConfigProperties.PAYLOAD; import static com.hivemq.extensions.log.mqtt.message.config.ExtensionConfigProperties.PING_REQUEST_RECEIVED; import static com.hivemq.extensions.log.mqtt.message.config.ExtensionConfigProperties.PING_RESPONSE_SEND; @@ -172,6 +173,8 @@ private static ExtensionConfig readPropertiesFile(final @NotNull File extensionH properties.setProperty(VERBOSE, FALSE); properties.setProperty(PAYLOAD, TRUE); + properties.setProperty(JSON, FALSE); + return properties; } } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigXml.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigXml.java index 986e6ee..5baca4b 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigXml.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigXml.java @@ -38,6 +38,9 @@ public class ExtensionConfigXml implements ExtensionConfig { @XmlElement(name = "payload", defaultValue = "true") private boolean payload = true; + @XmlElement(name = "json", defaultValue = "false") + private boolean json = false; + @XmlElement(name = "publish-received", defaultValue = "true") private boolean publishReceived = true; @@ -103,6 +106,10 @@ public boolean isPayload() { return payload; } + public boolean isJson() { + return json; + } + public boolean isPublishReceived() { return publishReceived; } @@ -186,6 +193,8 @@ public String toString() { verbose + ", payload=" + payload + + ", json=" + + json + ", publishReceived=" + publishReceived + ", publishSend=" + diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl.java index 663352d..d5427b6 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl.java @@ -62,12 +62,13 @@ public ClientInitializerImpl(final @NotNull ExtensionConfig config) { private void init() { if (config.isClientConnect()) { Services.interceptorRegistry().setConnectInboundInterceptorProvider( // - ignored -> new ConnectInboundInterceptorImpl(config.isVerbose(), config.isPayload())); + ignored -> new ConnectInboundInterceptorImpl(config.isVerbose(), config.isPayload(), + config.isJson())); } if (config.isConnackSend()) { Services.interceptorRegistry().setConnackOutboundInterceptorProvider( // - ignored -> new ConnackOutboundInterceptorImpl(config.isVerbose())); + ignored -> new ConnackOutboundInterceptorImpl(config.isVerbose(), config.isJson())); } } @@ -75,66 +76,80 @@ private void init() { public void initialize( final @NotNull InitializerInput initializerInput, final @NotNull ClientContext clientContext) { if (config.isClientDisconnect()) { - clientContext.addDisconnectInboundInterceptor(new DisconnectInboundInterceptorImpl(config.isVerbose())); - clientContext.addDisconnectOutboundInterceptor(new DisconnectOutboundInterceptorImpl(config.isVerbose())); + clientContext.addDisconnectInboundInterceptor(new DisconnectInboundInterceptorImpl(config.isVerbose(), + config.isJson())); + clientContext.addDisconnectOutboundInterceptor(new DisconnectOutboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isSubscribeReceived()) { - clientContext.addSubscribeInboundInterceptor(new SubscribeInboundInterceptorImpl(config.isVerbose())); + clientContext.addSubscribeInboundInterceptor(new SubscribeInboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isSubackSend()) { - clientContext.addSubackOutboundInterceptor(new SubackOutboundInterceptorImpl(config.isVerbose())); + clientContext.addSubackOutboundInterceptor(new SubackOutboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPingRequestReceived()) { - clientContext.addPingReqInboundInterceptor(new PingreqInboundInterceptorImpl()); + clientContext.addPingReqInboundInterceptor(new PingreqInboundInterceptorImpl(config.isJson())); } if (config.isPingResponseSend()) { - clientContext.addPingRespOutboundInterceptor(new PingrespOutboundInterceptorImpl()); + clientContext.addPingRespOutboundInterceptor(new PingrespOutboundInterceptorImpl(config.isJson())); } if (config.isUnsubscribeReceived()) { - clientContext.addUnsubscribeInboundInterceptor(new UnsubscribeInboundInterceptorImpl(config.isVerbose())); + clientContext.addUnsubscribeInboundInterceptor(new UnsubscribeInboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isUnsubackSend()) { - clientContext.addUnsubackOutboundInterceptor(new UnsubackOutboundInterceptorImpl(config.isVerbose())); + clientContext.addUnsubackOutboundInterceptor(new UnsubackOutboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPublishReceived()) { clientContext.addPublishInboundInterceptor(new PublishInboundInterceptorImpl(config.isVerbose(), - config.isPayload())); + config.isPayload(), config.isJson())); } if (config.isPublishSend()) { clientContext.addPublishOutboundInterceptor(new PublishOutboundInterceptorImpl(config.isVerbose(), - config.isPayload())); + config.isPayload(), config.isJson())); } if (config.isPubackReceived()) { - clientContext.addPubackInboundInterceptor(new PubackInboundInterceptorImpl(config.isVerbose())); + clientContext.addPubackInboundInterceptor(new PubackInboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPubackSend()) { - clientContext.addPubackOutboundInterceptor(new PubackOutboundInterceptorImpl(config.isVerbose())); + clientContext.addPubackOutboundInterceptor(new PubackOutboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPubrecReceived()) { - clientContext.addPubrecInboundInterceptor(new PubrecInboundInterceptorImpl(config.isVerbose())); + clientContext.addPubrecInboundInterceptor(new PubrecInboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPubrecSend()) { - clientContext.addPubrecOutboundInterceptor(new PubrecOutboundInterceptorImpl(config.isVerbose())); + clientContext.addPubrecOutboundInterceptor(new PubrecOutboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPubrelReceived()) { - clientContext.addPubrelInboundInterceptor(new PubrelInboundInterceptorImpl(config.isVerbose())); + clientContext.addPubrelInboundInterceptor(new PubrelInboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPubrelSend()) { - clientContext.addPubrelOutboundInterceptor(new PubrelOutboundInterceptorImpl(config.isVerbose())); + clientContext.addPubrelOutboundInterceptor(new PubrelOutboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPubcompReceived()) { - clientContext.addPubcompInboundInterceptor(new PubcompInboundInterceptorImpl(config.isVerbose())); + clientContext.addPubcompInboundInterceptor(new PubcompInboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPubcompSend()) { - clientContext.addPubcompOutboundInterceptor(new PubcompOutboundInterceptorImpl(config.isVerbose())); + clientContext.addPubcompOutboundInterceptor(new PubcompOutboundInterceptorImpl(config.isVerbose(), + config.isJson())); } } } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl4_2.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl4_2.java index e80d798..8c12d27 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl4_2.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/initializer/ClientInitializerImpl4_2.java @@ -47,13 +47,16 @@ public ClientInitializerImpl4_2(final @NotNull ExtensionConfig config) { private void init() { if (config.isClientConnect() && config.isClientDisconnect()) { Services.eventRegistry().setClientLifecycleEventListener( // - input -> new ConnectDisconnectEventListener(true, config.isVerbose(), config.isPayload())); + input -> new ConnectDisconnectEventListener(true, config.isVerbose(), config.isPayload(), + config.isJson())); } else if (config.isClientDisconnect()) { Services.eventRegistry().setClientLifecycleEventListener( // - input -> new ConnectDisconnectEventListener(false, config.isVerbose(), config.isPayload())); + input -> new ConnectDisconnectEventListener(false, config.isVerbose(), config.isPayload(), + config.isJson())); } else if (config.isClientConnect()) { Services.interceptorRegistry().setConnectInboundInterceptorProvider( // - input -> new ConnectInboundInterceptorImpl(config.isVerbose(), config.isPayload())); + input -> new ConnectInboundInterceptorImpl(config.isVerbose(), config.isPayload(), + config.isJson())); } } @@ -61,15 +64,16 @@ private void init() { public void initialize( final @NotNull InitializerInput initializerInput, final @NotNull ClientContext clientContext) { if (config.isSubscribeReceived()) { - clientContext.addSubscribeInboundInterceptor(new SubscribeInboundInterceptorImpl(config.isVerbose())); + clientContext.addSubscribeInboundInterceptor(new SubscribeInboundInterceptorImpl(config.isVerbose(), + config.isJson())); } if (config.isPublishReceived()) { clientContext.addPublishInboundInterceptor(new PublishInboundInterceptorImpl(config.isVerbose(), - config.isPayload())); + config.isPayload(), config.isJson())); } if (config.isPublishSend()) { clientContext.addPublishOutboundInterceptor(new PublishOutboundInterceptorImpl(config.isVerbose(), - config.isPayload())); + config.isPayload(), config.isJson())); } } } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnackOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnackOutboundInterceptorImpl.java index 848d4fd..6d1aaa8 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnackOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnackOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class ConnackOutboundInterceptorImpl implements ConnackOutboundIntercepto private static final @NotNull Logger LOG = LoggerFactory.getLogger(ConnackOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public ConnackOutboundInterceptorImpl(final boolean verbose) { + public ConnackOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -40,7 +42,7 @@ public void onOutboundConnack( final @NotNull ConnackOutboundInput connackOutboundInput, final @NotNull ConnackOutboundOutput connackOutboundOutput) { try { - MessageLogUtil.logConnack(connackOutboundInput, verbose); + MessageLogUtil.logConnack(connackOutboundInput, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound connack logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectDisconnectEventListener.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectDisconnectEventListener.java index b1ea82c..e9c4e04 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectDisconnectEventListener.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectDisconnectEventListener.java @@ -39,11 +39,14 @@ public class ConnectDisconnectEventListener implements ClientLifecycleEventListe private final boolean logConnect; private final boolean verbose; private final boolean payload; + private final boolean json; - public ConnectDisconnectEventListener(final boolean logConnect, final boolean verbose, final boolean payload) { + public ConnectDisconnectEventListener(final boolean logConnect, final boolean verbose, final boolean payload, + final boolean json) { this.logConnect = logConnect; this.verbose = verbose; this.payload = payload; + this.json = json; } @Override @@ -53,7 +56,7 @@ public void onMqttConnectionStart(final @NotNull ConnectionStartInput connection } try { final ConnectPacket connectPacket = connectionStartInput.getConnectPacket(); - MessageLogUtil.logConnect(connectPacket, verbose, payload); + MessageLogUtil.logConnect(connectPacket, verbose, payload, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound connect logging: ", e); } @@ -72,7 +75,7 @@ public void onDisconnect(final @NotNull DisconnectEventInput disconnectEventInpu @Override public void onAuthenticationFailedDisconnect(final @NotNull AuthenticationFailedInput authenticationFailedInput) { MessageLogUtil.logDisconnect(String.format("Sent DISCONNECT to client '%s' because authentication failed.", - authenticationFailedInput.getClientInformation().getClientId()), authenticationFailedInput, verbose); + authenticationFailedInput.getClientInformation().getClientId()), authenticationFailedInput, verbose, json); } @Override @@ -85,7 +88,7 @@ public void onClientInitiatedDisconnect(final @NotNull ClientInitiatedDisconnect MessageLogUtil.logDisconnect(String.format("Received DISCONNECT from client '%s':", clientInitiatedDisconnectInput.getClientInformation().getClientId()), clientInitiatedDisconnectInput, - verbose); + verbose, json); } @Override @@ -93,6 +96,6 @@ public void onServerInitiatedDisconnect(final @NotNull ServerInitiatedDisconnect MessageLogUtil.logDisconnect(String.format("Sent DISCONNECT to client '%s':", serverInitiatedDisconnectInput.getClientInformation().getClientId()), serverInitiatedDisconnectInput, - verbose); + verbose, json); } } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectInboundInterceptorImpl.java index 2d52407..998382f 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/ConnectInboundInterceptorImpl.java @@ -32,10 +32,12 @@ public class ConnectInboundInterceptorImpl implements ConnectInboundInterceptor private static final @NotNull Logger LOG = LoggerFactory.getLogger(ConnectInboundInterceptorImpl.class); private final boolean verbose; private final boolean payload; + private final boolean json; - public ConnectInboundInterceptorImpl(final boolean verbose, final boolean payload) { + public ConnectInboundInterceptorImpl(final boolean verbose, final boolean payload, final boolean json) { this.verbose = verbose; this.payload = payload; + this.json = json; } @Override @@ -44,7 +46,7 @@ public void onConnect( final @NotNull ConnectInboundOutput connectInboundOutput) { try { final ConnectPacket connectPacket = connectInboundInput.getConnectPacket(); - MessageLogUtil.logConnect(connectPacket, verbose, payload); + MessageLogUtil.logConnect(connectPacket, verbose, payload, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound connect logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectInboundInterceptorImpl.java index fedcd55..63d04f2 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectInboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class DisconnectInboundInterceptorImpl implements DisconnectInboundInterc private static final @NotNull Logger LOG = LoggerFactory.getLogger(DisconnectInboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public DisconnectInboundInterceptorImpl(final boolean verbose) { + public DisconnectInboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onInboundDisconnect( final @NotNull DisconnectInboundOutput disconnectInboundOutput) { try { final String clientId = disconnectInboundInput.getClientInformation().getClientId(); - MessageLogUtil.logDisconnect(disconnectInboundInput.getDisconnectPacket(), clientId, true, verbose); + MessageLogUtil.logDisconnect(disconnectInboundInput.getDisconnectPacket(), clientId, true, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound disconnect logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectOutboundInterceptorImpl.java index 62955bc..bf8615b 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/DisconnectOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class DisconnectOutboundInterceptorImpl implements DisconnectOutboundInte private static final @NotNull Logger LOG = LoggerFactory.getLogger(DisconnectOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public DisconnectOutboundInterceptorImpl(final boolean verbose) { + public DisconnectOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onOutboundDisconnect( final @NotNull DisconnectOutboundOutput disconnectOutboundOutput) { try { final String clientId = disconnectOutboundInput.getClientInformation().getClientId(); - MessageLogUtil.logDisconnect(disconnectOutboundInput.getDisconnectPacket(), clientId, false, verbose); + MessageLogUtil.logDisconnect(disconnectOutboundInput.getDisconnectPacket(), clientId, false, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound disconnect logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingreqInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingreqInboundInterceptorImpl.java index 9a4f9e9..2dacc65 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingreqInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingreqInboundInterceptorImpl.java @@ -29,13 +29,18 @@ public class PingreqInboundInterceptorImpl implements PingReqInboundInterceptor { private static final @NotNull Logger LOG = LoggerFactory.getLogger(PingreqInboundInterceptorImpl.class); + private final boolean json; + + public PingreqInboundInterceptorImpl(final boolean json) { + this.json = json; + } @Override public void onInboundPingReq( final @NotNull PingReqInboundInput pingReqInboundInput, final @NotNull PingReqInboundOutput pingReqInboundOutput) { try { - MessageLogUtil.logPingreq(pingReqInboundInput); + MessageLogUtil.logPingreq(pingReqInboundInput, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound ping request logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingrespOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingrespOutboundInterceptorImpl.java index e74d307..f929955 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingrespOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PingrespOutboundInterceptorImpl.java @@ -29,13 +29,18 @@ public class PingrespOutboundInterceptorImpl implements PingRespOutboundInterceptor { private static final @NotNull Logger LOG = LoggerFactory.getLogger(PingrespOutboundInterceptorImpl.class); + private final boolean json; + + public PingrespOutboundInterceptorImpl(final boolean json) { + this.json = json; + } @Override public void onOutboundPingResp( final @NotNull PingRespOutboundInput pingRespOutboundInput, final @NotNull PingRespOutboundOutput pingRespOutboundOutput) { try { - MessageLogUtil.logPingresp(pingRespOutboundInput); + MessageLogUtil.logPingresp(pingRespOutboundInput, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound ping response logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackInboundInterceptorImpl.java index bf9a91d..e94aea4 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackInboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubackInboundInterceptorImpl implements PubackInboundInterceptor { private static final @NotNull Logger log = LoggerFactory.getLogger(PubackInboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubackInboundInterceptorImpl(final boolean verbose) { + public PubackInboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onInboundPuback( final @NotNull PubackInboundOutput pubackInboundOutput) { try { @NotNull final String clientId = pubackInboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPuback(pubackInboundInput.getPubackPacket(), clientId, true, verbose); + MessageLogUtil.logPuback(pubackInboundInput.getPubackPacket(), clientId, true, verbose, json); } catch (final Exception e) { log.debug("Exception thrown at inbound puback logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackOutboundInterceptorImpl.java index 36726e6..72283d6 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubackOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubackOutboundInterceptorImpl implements PubackOutboundInterceptor private static final @NotNull Logger LOG = LoggerFactory.getLogger(PubackOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubackOutboundInterceptorImpl(final boolean verbose) { + public PubackOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onOutboundPuback( final @NotNull PubackOutboundOutput pubackOutboundOutput) { try { final String clientId = pubackOutboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPuback(pubackOutboundInput.getPubackPacket(), clientId, false, verbose); + MessageLogUtil.logPuback(pubackOutboundInput.getPubackPacket(), clientId, false, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound puback logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompInboundInterceptorImpl.java index 54a7594..18ebf1c 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompInboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubcompInboundInterceptorImpl implements PubcompInboundInterceptor private static final @NotNull Logger LOG = LoggerFactory.getLogger(PubcompInboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubcompInboundInterceptorImpl(final boolean verbose) { + public PubcompInboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onInboundPubcomp( final @NotNull PubcompInboundOutput pubcompInboundOutput) { try { final String clientId = pubcompInboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPubcomp(pubcompInboundInput.getPubcompPacket(), clientId, true, verbose); + MessageLogUtil.logPubcomp(pubcompInboundInput.getPubcompPacket(), clientId, true, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound pubcomp logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompOutboundInterceptorImpl.java index 9c59e5c..6df4933 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubcompOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubcompOutboundInterceptorImpl implements PubcompOutboundIntercepto private static final @NotNull Logger LOG = LoggerFactory.getLogger(PubcompOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubcompOutboundInterceptorImpl(final boolean verbose) { + public PubcompOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onOutboundPubcomp( final @NotNull PubcompOutboundOutput pubcompOutboundOutput) { try { final String clientId = pubcompOutboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPubcomp(pubcompOutboundInput.getPubcompPacket(), clientId, false, verbose); + MessageLogUtil.logPubcomp(pubcompOutboundInput.getPubcompPacket(), clientId, false, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound pubcomp logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishInboundInterceptorImpl.java index 4cb3f1c..5d7c95f 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishInboundInterceptorImpl.java @@ -31,10 +31,12 @@ public class PublishInboundInterceptorImpl implements PublishInboundInterceptor private static final @NotNull Logger LOG = LoggerFactory.getLogger(PublishInboundInterceptorImpl.class); private final boolean verbose; private final boolean payload; + private final boolean json; - public PublishInboundInterceptorImpl(final boolean verbose, final boolean payload) { + public PublishInboundInterceptorImpl(final boolean verbose, final boolean payload, final boolean json) { this.verbose = verbose; this.payload = payload; + this.json = json; } @Override @@ -43,10 +45,19 @@ public void onInboundPublish( final @NotNull PublishInboundOutput publishInboundOutput) { try { final String clientID = publishInboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPublish(String.format("Received PUBLISH from client '%s' for topic", clientID), - publishInboundInput.getPublishPacket(), - verbose, - payload); + if(json) { + MessageLogUtil.logPublish(String.format("\"Received PUBLISH\", \"Client\": \"%s\"", clientID), + publishInboundInput.getPublishPacket(), + verbose, + payload, + true); + } else { + MessageLogUtil.logPublish(String.format("Received PUBLISH from client '%s' for topic", clientID), + publishInboundInput.getPublishPacket(), + verbose, + payload, + false); + } } catch (final Exception e) { LOG.debug("Exception thrown at inbound publish logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishOutboundInterceptorImpl.java index 94b6ec6..499850a 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PublishOutboundInterceptorImpl.java @@ -31,10 +31,12 @@ public class PublishOutboundInterceptorImpl implements PublishOutboundIntercepto private static final @NotNull Logger LOG = LoggerFactory.getLogger(PublishOutboundInterceptorImpl.class); private final boolean verbose; private final boolean payload; + private final boolean json; - public PublishOutboundInterceptorImpl(final boolean verbose, final boolean payload) { + public PublishOutboundInterceptorImpl(final boolean verbose, final boolean payload, final boolean json) { this.verbose = verbose; this.payload = payload; + this.json = json; } @Override @@ -43,10 +45,19 @@ public void onOutboundPublish( final @NotNull PublishOutboundOutput publishOutboundOutput) { try { final String clientID = publishOutboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPublish(String.format("Sent PUBLISH to client '%s' on topic", clientID), - publishOutboundInput.getPublishPacket(), - verbose, - payload); + if (json) { + MessageLogUtil.logPublish(String.format("\"Sent PUBLISH\", \"Client\": \"%s\"", clientID), + publishOutboundInput.getPublishPacket(), + verbose, + payload, + true); + } else { + MessageLogUtil.logPublish(String.format("Sent PUBLISH to client '%s' on topic", clientID), + publishOutboundInput.getPublishPacket(), + verbose, + payload, + false); + } } catch (final Exception e) { LOG.debug("Exception thrown at outbound publish logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecInboundInterceptorImpl.java index 2cf24fd..aa02d8d 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecInboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubrecInboundInterceptorImpl implements PubrecInboundInterceptor { private static final @NotNull Logger LOG = LoggerFactory.getLogger(PubrecInboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubrecInboundInterceptorImpl(final boolean verbose) { + public PubrecInboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onInboundPubrec( final @NotNull PubrecInboundOutput pubrecInboundOutput) { try { final String clientId = pubrecInboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPubrec(pubrecInboundInput.getPubrecPacket(), clientId, true, verbose); + MessageLogUtil.logPubrec(pubrecInboundInput.getPubrecPacket(), clientId, true, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound pubrec logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecOutboundInterceptorImpl.java index 3cb545d..3ff7a0a 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrecOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubrecOutboundInterceptorImpl implements PubrecOutboundInterceptor private static final @NotNull Logger LOG = LoggerFactory.getLogger(PubrecOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubrecOutboundInterceptorImpl(final boolean verbose) { + public PubrecOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onOutboundPubrec( final @NotNull PubrecOutboundOutput pubrecOutboundOutput) { try { final String clientId = pubrecOutboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPubrec(pubrecOutboundInput.getPubrecPacket(), clientId, false, verbose); + MessageLogUtil.logPubrec(pubrecOutboundInput.getPubrecPacket(), clientId, false, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound pubrec logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelInboundInterceptorImpl.java index f97f03a..1979e57 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelInboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubrelInboundInterceptorImpl implements PubrelInboundInterceptor { private static final @NotNull Logger LOG = LoggerFactory.getLogger(PubrelInboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubrelInboundInterceptorImpl(final boolean verbose) { + public PubrelInboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onInboundPubrel( final @NotNull PubrelInboundOutput pubrelInboundOutput) { try { final String clientId = pubrelInboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPubrel(pubrelInboundInput.getPubrelPacket(), clientId, true, verbose); + MessageLogUtil.logPubrel(pubrelInboundInput.getPubrelPacket(), clientId, true, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound pubrel logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelOutboundInterceptorImpl.java index bc92dff..08ba071 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/PubrelOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class PubrelOutboundInterceptorImpl implements PubrelOutboundInterceptor private static final @NotNull Logger LOG = LoggerFactory.getLogger(PubrelOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public PubrelOutboundInterceptorImpl(final boolean verbose) { + public PubrelOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -41,7 +43,7 @@ public void onOutboundPubrel( final @NotNull PubrelOutboundOutput pubrelOutboundOutput) { try { final String clientId = pubrelOutboundInput.getClientInformation().getClientId(); - MessageLogUtil.logPubrel(pubrelOutboundInput.getPubrelPacket(), clientId, false, verbose); + MessageLogUtil.logPubrel(pubrelOutboundInput.getPubrelPacket(), clientId, false, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound pubrel logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubackOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubackOutboundInterceptorImpl.java index 549220d..d5299f6 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubackOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubackOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class SubackOutboundInterceptorImpl implements SubackOutboundInterceptor private static final @NotNull Logger LOG = LoggerFactory.getLogger(SubackOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public SubackOutboundInterceptorImpl(final boolean verbose) { + public SubackOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -40,7 +42,7 @@ public void onOutboundSuback( final @NotNull SubackOutboundInput subackOutboundInput, final @NotNull SubackOutboundOutput subackOutboundOutput) { try { - MessageLogUtil.logSuback(subackOutboundInput, verbose); + MessageLogUtil.logSuback(subackOutboundInput, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound suback logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubscribeInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubscribeInboundInterceptorImpl.java index 423ebae..9f3999f 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubscribeInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/SubscribeInboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class SubscribeInboundInterceptorImpl implements SubscribeInboundIntercep private static final @NotNull Logger LOG = LoggerFactory.getLogger(SubscribeInboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public SubscribeInboundInterceptorImpl(final boolean verbose) { + public SubscribeInboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -40,7 +42,7 @@ public void onInboundSubscribe( final @NotNull SubscribeInboundInput subscribeInboundInput, final @NotNull SubscribeInboundOutput subscribeInboundOutput) { try { - MessageLogUtil.logSubscribe(subscribeInboundInput, verbose); + MessageLogUtil.logSubscribe(subscribeInboundInput, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound subscribe logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubackOutboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubackOutboundInterceptorImpl.java index 73ccc06..e904c7b 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubackOutboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubackOutboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class UnsubackOutboundInterceptorImpl implements UnsubackOutboundIntercep private static final @NotNull Logger LOG = LoggerFactory.getLogger(UnsubackOutboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public UnsubackOutboundInterceptorImpl(final boolean verbose) { + public UnsubackOutboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -40,7 +42,7 @@ public void onOutboundUnsuback( final @NotNull UnsubackOutboundInput unsubackOutboundInput, final @NotNull UnsubackOutboundOutput unsubackOutboundOutput) { try { - MessageLogUtil.logUnsuback(unsubackOutboundInput, verbose); + MessageLogUtil.logUnsuback(unsubackOutboundInput, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at outbound unsuback logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubscribeInboundInterceptorImpl.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubscribeInboundInterceptorImpl.java index 69c8b4c..7fe2479 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubscribeInboundInterceptorImpl.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/interceptor/UnsubscribeInboundInterceptorImpl.java @@ -30,9 +30,11 @@ public class UnsubscribeInboundInterceptorImpl implements UnsubscribeInboundInte private static final @NotNull Logger LOG = LoggerFactory.getLogger(UnsubscribeInboundInterceptorImpl.class); private final boolean verbose; + private final boolean json; - public UnsubscribeInboundInterceptorImpl(final boolean verbose) { + public UnsubscribeInboundInterceptorImpl(final boolean verbose, final boolean json) { this.verbose = verbose; + this.json = json; } @Override @@ -40,7 +42,7 @@ public void onInboundUnsubscribe( final @NotNull UnsubscribeInboundInput unsubscribeInboundInput, final @NotNull UnsubscribeInboundOutput unsubscribeInboundOutput) { try { - MessageLogUtil.logUnsubscribe(unsubscribeInboundInput, verbose); + MessageLogUtil.logUnsubscribe(unsubscribeInboundInput, verbose, json); } catch (final Exception e) { LOG.debug("Exception thrown at inbound unsubscribe logging: ", e); } diff --git a/src/main/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtil.java b/src/main/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtil.java index e66f72d..e5945b0 100644 --- a/src/main/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtil.java +++ b/src/main/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtil.java @@ -72,363 +72,760 @@ public class MessageLogUtil { public static void logDisconnect( final @NotNull String message, final @NotNull DisconnectEventInput disconnectEventInput, - final boolean verbose) { + final boolean verbose, + final boolean json) { if (!verbose) { - LOG.info(message + " Reason Code: '{}'", disconnectEventInput.getReasonCode().orElse(null)); + if (json) { + LOG.info("{\"Event\": " + message + "," + + " \"Reason Code\": \"{}\"}", disconnectEventInput.getReasonCode().orElse(null)); + } else { + LOG.info(message + " Reason Code: '{}'", disconnectEventInput.getReasonCode().orElse(null)); + } return; } final String userPropertiesAsString = - getUserPropertiesAsString(disconnectEventInput.getUserProperties().orElse(null)); - LOG.info(message + " Reason Code: '{}', Reason String: '{}', {}", - disconnectEventInput.getReasonCode().orElse(null), - disconnectEventInput.getReasonString().orElse(null), - userPropertiesAsString); + getUserPropertiesAsString(disconnectEventInput.getUserProperties().orElse(null), json); + if (json) { + LOG.info("{\"Event\":" + message + "," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + disconnectEventInput.getReasonCode().orElse(null), + disconnectEventInput.getReasonString().orElse(null), + userPropertiesAsString); + } else { + LOG.info(message + " Reason Code: '{}', Reason String: '{}', {}", + disconnectEventInput.getReasonCode().orElse(null), + disconnectEventInput.getReasonString().orElse(null), + userPropertiesAsString); + } } public static void logDisconnect( final @NotNull DisconnectPacket disconnectPacket, final @NotNull String clientId, final boolean inbound, - final boolean verbose) { + final boolean verbose, + final boolean json) { final DisconnectReasonCode reasonCode = disconnectPacket.getReasonCode(); if (!verbose) { if (inbound) { - LOG.info("Received DISCONNECT from client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Received DISCONNECT\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Received DISCONNECT from client '{}': Reason Code: '{}'", clientId, reasonCode); + } } else { - LOG.info("Sent DISCONNECT to client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Sent DISCONNECT\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Sent DISCONNECT to client '{}': Reason Code: '{}'", clientId, reasonCode); + } } return; } - final String userPropertiesAsString = getUserPropertiesAsString(disconnectPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(disconnectPacket.getUserProperties(), json); final String reasonString = disconnectPacket.getReasonString().orElse(null); final String serverReference = disconnectPacket.getServerReference().orElse(null); final Long sessionExpiry = disconnectPacket.getSessionExpiryInterval().orElse(null); if (inbound) { - LOG.info( - "Received DISCONNECT from client '{}': Reason Code: '{}', Reason String: '{}', Server Reference: '{}', Session Expiry: '{}', {}", - clientId, - reasonCode, - reasonString, - serverReference, - sessionExpiry, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Received DISCONNECT\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " \"Server Reference\": \"{}\"," + + " \"Session Expiry\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + serverReference, + sessionExpiry, + userPropertiesAsString); + } else { + LOG.info( + "Received DISCONNECT from client '{}': Reason Code: '{}', Reason String: '{}', Server Reference: '{}', Session Expiry: '{}', {}", + clientId, + reasonCode, + reasonString, + serverReference, + sessionExpiry, + userPropertiesAsString); + } } else { - LOG.info( - "Sent DISCONNECT to client '{}': Reason Code: '{}', Reason String: '{}', Server Reference: '{}', Session Expiry: '{}', {}", - clientId, - reasonCode, - reasonString, - serverReference, - sessionExpiry, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent DISCONNECT\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " \"Server Reference\": \"{}\"," + + " \"Session Expiry\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + serverReference, + sessionExpiry, + userPropertiesAsString); + } else { + LOG.info( + "Sent DISCONNECT to client '{}': Reason Code: '{}', Reason String: '{}', Server Reference: '{}', Session Expiry: '{}', {}", + clientId, + reasonCode, + reasonString, + serverReference, + sessionExpiry, + userPropertiesAsString); + } } } public static void logConnect( - final @NotNull ConnectPacket connectPacket, final boolean verbose, final boolean payload) { + final @NotNull ConnectPacket connectPacket, + final boolean verbose, + final boolean payload, + final boolean json) { if (!verbose) { - LOG.info( - "Received CONNECT from client '{}': Protocol version: '{}', Clean Start: '{}', Session Expiry Interval: '{}'", - connectPacket.getClientId(), - connectPacket.getMqttVersion().name(), - connectPacket.getCleanStart(), - connectPacket.getSessionExpiryInterval()); + if (json) { + LOG.info("{\"Event\": \"Received CONNECT\"," + + " \"Client\": \"{}\"," + + " \"Protocol version\": \"{}\"," + + " \"Clean Start\": \"{}\"," + + " \"Session Expiry Interval\": \"{}\"}", + connectPacket.getClientId(), + connectPacket.getMqttVersion().name(), + connectPacket.getCleanStart(), + connectPacket.getSessionExpiryInterval()); + } else { + LOG.info( + "Received CONNECT from client '{}': Protocol version: '{}', Clean Start: '{}', Session Expiry Interval: '{}'", + connectPacket.getClientId(), + connectPacket.getMqttVersion().name(), + connectPacket.getCleanStart(), + connectPacket.getSessionExpiryInterval()); + } return; } - final String userPropertiesAsString = getUserPropertiesAsString(connectPacket.getUserProperties()); - final String passwordAsString = getStringFromByteBuffer(connectPacket.getPassword().orElse(null)); + final String userPropertiesAsString = getUserPropertiesAsString(connectPacket.getUserProperties(), json); + final String passwordAsString = getStringFromByteBuffer(connectPacket.getPassword().orElse(null), false); final String passwordProperty; if (StringUtils.isAsciiPrintable(passwordAsString) || passwordAsString == null) { - passwordProperty = "Password: '" + passwordAsString + "'"; + if (json) { + passwordProperty = "\"Password\": \"" + passwordAsString + "\""; + } else { + passwordProperty = "Password: '" + passwordAsString + "'"; + } } else { - passwordProperty = - "Password (Hex): '" + getHexStringFromByteBuffer(connectPacket.getPassword().orElse(null)) + "'"; + if (json) { + passwordProperty = + "\"Password (Hex)\": \"" + getHexStringFromByteBuffer(connectPacket.getPassword().orElse(null)) + "\""; + } else { + passwordProperty = + "Password (Hex): '" + getHexStringFromByteBuffer(connectPacket.getPassword().orElse(null)) + "'"; + } } final String authDataAsString; if (connectPacket.getAuthenticationData().isPresent()) { authDataAsString = - getStringFromByteBuffer(Base64.getEncoder().encode(connectPacket.getAuthenticationData().get())); + getStringFromByteBuffer(Base64.getEncoder().encode(connectPacket.getAuthenticationData().get()), false); } else { authDataAsString = null; } final String willString; if (connectPacket.getWillPublish().isPresent()) { - willString = getWillAsString(connectPacket.getWillPublish().get(), payload); + willString = getWillAsString(connectPacket.getWillPublish().get(), payload, json); } else { willString = ""; } - LOG.info( - "Received CONNECT from client '{}': Protocol version: '{}', Clean Start: '{}', Session Expiry Interval: '{}'," + - " Keep Alive: '{}', Maximum Packet Size: '{}', Receive Maximum: '{}', Topic Alias Maximum: '{}'," + - " Request Problem Information: '{}', Request Response Information: '{}', " + - " Username: '{}', {}, Auth Method: '{}', Auth Data (Base64): '{}', {}{}", - connectPacket.getClientId(), - connectPacket.getMqttVersion().name(), - connectPacket.getCleanStart(), - connectPacket.getSessionExpiryInterval(), - connectPacket.getKeepAlive(), - connectPacket.getMaximumPacketSize(), - connectPacket.getReceiveMaximum(), - connectPacket.getTopicAliasMaximum(), - connectPacket.getRequestProblemInformation(), - connectPacket.getRequestResponseInformation(), - connectPacket.getUserName().orElse(null), - passwordProperty, - connectPacket.getAuthenticationMethod().orElse(null), - authDataAsString, - userPropertiesAsString, - willString); + if (json) { + LOG.info( + "{\"Event\": \"Received CONNECT\"," + + " \"Client\": \"{}\"," + + " \"Protocol version\": \"{}\"," + + " \"Clean Start\": \"{}\"," + + " \"Session Expiry Interval\": \"{}\"," + + " \"Keep Alive\": \"{}\"," + + " \"Maximum Packet Size\": \"{}\"," + + " \"Receive Maximum\": \"{}\"," + + " \"Topic Alias Maximum\": \"{}\"," + + " \"Request Problem Information\": \"{}\"," + + " \"Request Response Information\": \"{}\", " + + " \"Username\": \"{}\"," + + " {}," + + " \"Auth Method\": \"{}\"," + + " \"Auth Data (Base64)\": \"{}\"," + + " {}{}}", + connectPacket.getClientId(), + connectPacket.getMqttVersion().name(), + connectPacket.getCleanStart(), + connectPacket.getSessionExpiryInterval(), + connectPacket.getKeepAlive(), + connectPacket.getMaximumPacketSize(), + connectPacket.getReceiveMaximum(), + connectPacket.getTopicAliasMaximum(), + connectPacket.getRequestProblemInformation(), + connectPacket.getRequestResponseInformation(), + connectPacket.getUserName().orElse(null), + passwordProperty, + connectPacket.getAuthenticationMethod().orElse(null), + authDataAsString, + userPropertiesAsString, + willString); + } else { + LOG.info( + "Received CONNECT from client '{}': Protocol version: '{}', Clean Start: '{}', Session Expiry Interval: '{}'," + + " Keep Alive: '{}', Maximum Packet Size: '{}', Receive Maximum: '{}', Topic Alias Maximum: '{}'," + + " Request Problem Information: '{}', Request Response Information: '{}', " + + " Username: '{}', {}, Auth Method: '{}', Auth Data (Base64): '{}', {}{}", + connectPacket.getClientId(), + connectPacket.getMqttVersion().name(), + connectPacket.getCleanStart(), + connectPacket.getSessionExpiryInterval(), + connectPacket.getKeepAlive(), + connectPacket.getMaximumPacketSize(), + connectPacket.getReceiveMaximum(), + connectPacket.getTopicAliasMaximum(), + connectPacket.getRequestProblemInformation(), + connectPacket.getRequestResponseInformation(), + connectPacket.getUserName().orElse(null), + passwordProperty, + connectPacket.getAuthenticationMethod().orElse(null), + authDataAsString, + userPropertiesAsString, + willString); + } } - public static void logConnack(final @NotNull ConnackOutboundInput connackOutboundInput, final boolean verbose) { + public static void logConnack( + final @NotNull ConnackOutboundInput connackOutboundInput, + final boolean verbose, + final boolean json) { final @NotNull String clientId = connackOutboundInput.getClientInformation().getClientId(); final @NotNull ConnackPacket connackPacket = connackOutboundInput.getConnackPacket(); if (!verbose) { - LOG.info("Sent CONNACK to client '{}': Reason Code: '{}', Session Present: '{}'", - clientId, - connackPacket.getReasonCode(), - connackPacket.getSessionPresent()); + if (json) { + LOG.info("{\"Event\": \"Sent CONNACK\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Session Present\": \"{}\"}", + clientId, + connackPacket.getReasonCode(), + connackPacket.getSessionPresent()); + } else { + LOG.info("Sent CONNACK to client '{}': Reason Code: '{}', Session Present: '{}'", + clientId, + connackPacket.getReasonCode(), + connackPacket.getSessionPresent()); + } return; } - final String userPropertiesAsString = getUserPropertiesAsString(connackPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(connackPacket.getUserProperties(), json); final String authDataAsString; if (connackPacket.getAuthenticationData().isPresent()) { authDataAsString = - getStringFromByteBuffer(Base64.getEncoder().encode(connackPacket.getAuthenticationData().get())); + getStringFromByteBuffer(Base64.getEncoder().encode(connackPacket.getAuthenticationData().get()), false); } else { authDataAsString = null; } - LOG.info("Sent CONNACK to client '{}': Reason Code: '{}', Session Present: '{}', Session Expiry Interval: '{}'," + - " Assigned ClientId '{}', Maximum QoS: '{}', Maximum Packet Size: '{}', Receive Maximum: '{}'," + - " Topic Alias Maximum: '{}', Reason String: '{}', Response Information: '{}', Server Keep Alive: '{}'," + - " Server Reference: '{}', Shared Subscription Available: '{}', Wildcards Available: '{}'," + - " Retain Available: '{}', Subscription Identifiers Available: '{}'," + - " Auth Method: '{}', Auth Data (Base64): '{}', {}", - clientId, - connackPacket.getReasonCode(), - connackPacket.getSessionPresent(), - connackPacket.getSessionExpiryInterval().orElse(null), - connackPacket.getAssignedClientIdentifier().orElse(null), - connackPacket.getMaximumQoS().orElse(null), - connackPacket.getMaximumPacketSize(), - connackPacket.getReceiveMaximum(), - connackPacket.getTopicAliasMaximum(), - connackPacket.getReasonString().orElse(null), - connackPacket.getResponseInformation().orElse(null), - connackPacket.getServerKeepAlive().orElse(null), - connackPacket.getServerReference().orElse(null), - connackPacket.getSharedSubscriptionsAvailable(), - connackPacket.getWildCardSubscriptionAvailable(), - connackPacket.getRetainAvailable(), - connackPacket.getSubscriptionIdentifiersAvailable(), - connackPacket.getAuthenticationMethod().orElse(null), - authDataAsString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent CONNACK\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Session Present\": \"{}\"," + + " \"Session Expiry Interval\": \"{}\"," + + " \"Assigned ClientId\": \"{}\"," + + " \"Maximum QoS\": \"{}\"," + + " \"Maximum Packet Size\": \"{}\"," + + " \"Receive Maximum\": \"{}\"," + + " \"Topic Alias Maximum\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " \"Response Information\": \"{}\"," + + " \"Server Keep Alive\": \"{}\"," + + " \"Server Reference\": \"{}\"," + + " \"Shared Subscription Available\": \"{}\"," + + " \"Wildcards Available\": \"{}\"," + + " \"Retain Available\": \"{}\"," + + " \"Subscription Identifiers Available\": \"{}\"," + + " \"Auth Method\": \"{}\"," + + " \"Auth Data (Base64)\": \"{}\"," + + " {}}", + clientId, + connackPacket.getReasonCode(), + connackPacket.getSessionPresent(), + connackPacket.getSessionExpiryInterval().orElse(null), + connackPacket.getAssignedClientIdentifier().orElse(null), + connackPacket.getMaximumQoS().orElse(null), + connackPacket.getMaximumPacketSize(), + connackPacket.getReceiveMaximum(), + connackPacket.getTopicAliasMaximum(), + connackPacket.getReasonString().orElse(null), + connackPacket.getResponseInformation().orElse(null), + connackPacket.getServerKeepAlive().orElse(null), + connackPacket.getServerReference().orElse(null), + connackPacket.getSharedSubscriptionsAvailable(), + connackPacket.getWildCardSubscriptionAvailable(), + connackPacket.getRetainAvailable(), + connackPacket.getSubscriptionIdentifiersAvailable(), + connackPacket.getAuthenticationMethod().orElse(null), + authDataAsString, + userPropertiesAsString); + } else { + LOG.info("Sent CONNACK to client '{}': Reason Code: '{}', Session Present: '{}', Session Expiry Interval: '{}'," + + " Assigned ClientId '{}', Maximum QoS: '{}', Maximum Packet Size: '{}', Receive Maximum: '{}'," + + " Topic Alias Maximum: '{}', Reason String: '{}', Response Information: '{}', Server Keep Alive: '{}'," + + " Server Reference: '{}', Shared Subscription Available: '{}', Wildcards Available: '{}'," + + " Retain Available: '{}', Subscription Identifiers Available: '{}'," + + " Auth Method: '{}', Auth Data (Base64): '{}', {}", + clientId, + connackPacket.getReasonCode(), + connackPacket.getSessionPresent(), + connackPacket.getSessionExpiryInterval().orElse(null), + connackPacket.getAssignedClientIdentifier().orElse(null), + connackPacket.getMaximumQoS().orElse(null), + connackPacket.getMaximumPacketSize(), + connackPacket.getReceiveMaximum(), + connackPacket.getTopicAliasMaximum(), + connackPacket.getReasonString().orElse(null), + connackPacket.getResponseInformation().orElse(null), + connackPacket.getServerKeepAlive().orElse(null), + connackPacket.getServerReference().orElse(null), + connackPacket.getSharedSubscriptionsAvailable(), + connackPacket.getWildCardSubscriptionAvailable(), + connackPacket.getRetainAvailable(), + connackPacket.getSubscriptionIdentifiersAvailable(), + connackPacket.getAuthenticationMethod().orElse(null), + authDataAsString, + userPropertiesAsString); + } } private static @NotNull String getWillAsString( - final @NotNull WillPublishPacket willPublishPacket, final boolean payload) { + final @NotNull WillPublishPacket willPublishPacket, + final boolean payload, + final boolean json) { final String topic = willPublishPacket.getTopic(); - final String publishAsString = getPublishAsString(willPublishPacket, true, payload); - final String willPublishAsString = publishAsString + ", Will Delay: '" + willPublishPacket.getWillDelay() + "'"; + final String publishAsString = getPublishAsString(willPublishPacket, true, payload, json); + final String willPublishAsString; + if (json) { + willPublishAsString = publishAsString + ", \"Will Delay\": \"" + willPublishPacket.getWillDelay() + "\""; + } else { + willPublishAsString = publishAsString + ", Will Delay: '" + willPublishPacket.getWillDelay() + "'"; + } - return String.format(", Will: { Topic: '%s', %s }", topic, willPublishAsString); + if (json) { + return String.format(", \"Will\": { \"Topic\": \"%s\", %s }", topic, willPublishAsString); + } else { + return String.format(", Will: { Topic: '%s', %s }", topic, willPublishAsString); + } } public static void logPublish( final @NotNull String prefix, final @NotNull PublishPacket publishPacket, final boolean verbose, - final boolean payload) { + final boolean payload, + final boolean json) { final String topic = publishPacket.getTopic(); - final String publishString = getPublishAsString(publishPacket, verbose, payload); + final String publishString = getPublishAsString(publishPacket, verbose, payload, json); - LOG.info("{} '{}': {}", prefix, topic, publishString); + if (json) { + LOG.info("{\"Event\": {}, \"Topic\": \"{}\", {}}", prefix, topic, publishString); + } else { + LOG.info("{} '{}': {}", prefix, topic, publishString); + } } - public static void logSubscribe(final @NotNull SubscribeInboundInput subscribeInboundInput, final boolean verbose) { + public static void logSubscribe( + final @NotNull SubscribeInboundInput subscribeInboundInput, + final boolean verbose, + final boolean json) { final StringBuilder topics = new StringBuilder(); final String clientId = subscribeInboundInput.getClientInformation().getClientId(); final SubscribePacket subscribePacket = subscribeInboundInput.getSubscribePacket(); if (!verbose) { - topics.append("Topics: {"); + if (json) { + topics.append("\"Topics\": ["); + } else { + topics.append("Topics: {"); + } for (final Subscription sub : subscribePacket.getSubscriptions()) { - topics.append(" [Topic: '") + if (json) { + topics.append("{\"Topic\": \"") .append(sub.getTopicFilter()) - .append("', QoS: '") + .append("\", \"QoS\": \"") .append(sub.getQos().getQosNumber()) - .append("'],"); + .append("\"},"); + } else { + topics.append(" [Topic: '") + .append(sub.getTopicFilter()) + .append("', QoS: '") + .append(sub.getQos().getQosNumber()) + .append("'],"); + } } topics.deleteCharAt(topics.length() - 1); //delete last comma - topics.append(" }"); - LOG.info("Received SUBSCRIBE from client '{}': {}", clientId, topics); + if (json) { + topics.append(" ]"); + } else { + topics.append(" }"); + } + if (json) { + LOG.info("{\"Event\": \"Received SUBSCRIBE\"," + + " \"Client\": \"{}\"," + + " {}}", clientId, topics); + } else { + LOG.info("Received SUBSCRIBE from client '{}': {}", clientId, topics); + } return; } - topics.append("Topics: {"); + if (json) { + topics.append("\"Topics\": ["); + } else { + topics.append("Topics: {"); + } for (final Subscription sub : subscribePacket.getSubscriptions()) { - topics.append(" [Topic: '") - .append(sub.getTopicFilter()) - .append("', QoS: '") - .append(sub.getQos().getQosNumber()) - .append("', Retain As Published: '") - .append(sub.getRetainAsPublished()) - .append("', No Local: '") - .append(sub.getNoLocal()) - .append("', Retain Handling: '") - .append(sub.getRetainHandling().name()) - .append("'],"); + if (json) { + topics.append("{\"Topic\": \"") + .append(sub.getTopicFilter()) + .append("\", \"QoS\": \"") + .append(sub.getQos().getQosNumber()) + .append("\", \"Retain As Published\": \"") + .append(sub.getRetainAsPublished()) + .append("\", \"No Local\": \"") + .append(sub.getNoLocal()) + .append("\", \"Retain Handling\": \"") + .append(sub.getRetainHandling().name()) + .append("\"},"); + } else { + topics.append(" [Topic: '") + .append(sub.getTopicFilter()) + .append("', QoS: '") + .append(sub.getQos().getQosNumber()) + .append("', Retain As Published: '") + .append(sub.getRetainAsPublished()) + .append("', No Local: '") + .append(sub.getNoLocal()) + .append("', Retain Handling: '") + .append(sub.getRetainHandling().name()) + .append("'],"); + } } topics.deleteCharAt(topics.length() - 1); //delete last comma - - topics.append(" }"); + if (json) { + topics.append(" ]"); + } else { + topics.append(" }"); + } final Integer subscriptionIdentifier = subscribePacket.getSubscriptionIdentifier().orElse(null); - final String userPropertiesAsString = getUserPropertiesAsString(subscribePacket.getUserProperties()); - - LOG.info("Received SUBSCRIBE from client '{}': {}, Subscription Identifier: '{}', {}", - clientId, - topics, - subscriptionIdentifier, - userPropertiesAsString); + final String userPropertiesAsString = getUserPropertiesAsString(subscribePacket.getUserProperties(), json); + + if (json) { + LOG.info("{\"Event\": \"Received SUBSCRIBE\"," + + " \"Client\": \"{}\"," + + " {}," + + " \"Subscription Identifier\": \"{}\"," + + " {}}", + clientId, + topics, + subscriptionIdentifier, + userPropertiesAsString); + } else { + LOG.info("Received SUBSCRIBE from client '{}': {}, Subscription Identifier: '{}', {}", + clientId, + topics, + subscriptionIdentifier, + userPropertiesAsString); + } } - public static void logSuback(final @NotNull SubackOutboundInput subackOutboundInput, final boolean verbose) { + public static void logSuback( + final @NotNull SubackOutboundInput subackOutboundInput, + final boolean verbose, + final boolean json) { final StringBuilder suback = new StringBuilder(); final String clientId = subackOutboundInput.getClientInformation().getClientId(); @NotNull final SubackPacket subackPacket = subackOutboundInput.getSubackPacket(); - suback.append("Suback Reason Codes: {"); + if (json) { + suback.append("\"Suback Reason Codes (" + subackPacket.getReasonCodes().size() + ")\": ["); + } else { + suback.append("Suback Reason Codes: {"); + } for (final SubackReasonCode sub : subackPacket.getReasonCodes()) { - suback.append(" [Reason Code: '").append(sub).append("'],"); + if (json) { + suback.append("{\"Reason Code\": \"").append(sub).append("\"},"); + } else { + suback.append(" [Reason Code: '").append(sub).append("'],"); + } } suback.deleteCharAt(suback.length() - 1); //delete last comma - suback.append(" }"); + if (json) { + suback.append(" ]"); + } else { + suback.append(" }"); + } if (!verbose) { - LOG.info("Sent SUBACK to client '{}': {}", clientId, suback); + if (json) { + LOG.info("{\"Event\": \"Sent SUBACK\"," + + " \"Client\": \"{}\"," + + " {}}", clientId, suback); + } else { + LOG.info("Sent SUBACK to client '{}': {}", clientId, suback); + } return; } - final String userPropertiesAsString = getUserPropertiesAsString(subackPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(subackPacket.getUserProperties(), json); final String reasonString = subackPacket.getReasonString().orElse(null); - LOG.info("Sent SUBACK to client '{}': {}, Reason String: '{}', {}", - clientId, - suback, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent SUBACK\"," + + " \"Client\": \"{}\"," + + " {}," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + suback, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Sent SUBACK to client '{}': {}, Reason String: '{}', {}", + clientId, + suback, + reasonString, + userPropertiesAsString); + } } public static void logUnsubscribe( - final @NotNull UnsubscribeInboundInput unsubscribeInboundInput, final boolean verbose) { + final @NotNull UnsubscribeInboundInput unsubscribeInboundInput, + final boolean verbose, + final boolean json) { final StringBuilder topics = new StringBuilder(); @NotNull final String clientId = unsubscribeInboundInput.getClientInformation().getClientId(); @NotNull final UnsubscribePacket unsubscribePacket = unsubscribeInboundInput.getUnsubscribePacket(); - topics.append("Topics: {"); + if (json) { + topics.append("\"Topics\": ["); + } else { + topics.append("Topics: {"); + } for (final String unsub : unsubscribePacket.getTopicFilters()) { - topics.append(" [Topic: '").append(unsub).append("'],"); + if (json) { + topics.append(" {\"Topic\": \"").append(unsub).append("\"},"); + } else { + topics.append(" [Topic: '").append(unsub).append("'],"); + } } topics.deleteCharAt(topics.length() - 1); //delete last comma - topics.append(" }"); + if (json) { + topics.append(" ]"); + } else { + topics.append(" }"); + } if (!verbose) { - LOG.info("Received UNSUBSCRIBE from client '{}': {}", clientId, topics); + if (json) { + LOG.info("{\"Event\": \"Received UNSUBSCRIBE\"," + + " \"Client\": \"{}\"," + + " {}}", clientId, topics); + } else { + LOG.info("Received UNSUBSCRIBE from client '{}': {}", clientId, topics); + } return; } - final String userPropertiesAsString = getUserPropertiesAsString(unsubscribePacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(unsubscribePacket.getUserProperties(), json); - LOG.info("Received UNSUBSCRIBE from client '{}': {}, {}", clientId, topics, userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Received UNSUBSCRIBE\"," + + " \"Client\": \"{}\"," + + " {}, " + + " {}}", clientId, topics, userPropertiesAsString); + } else { + LOG.info("Received UNSUBSCRIBE from client '{}': {}, {}", clientId, topics, userPropertiesAsString); + } } - public static void logUnsuback(final @NotNull UnsubackOutboundInput unsubackOutboundInput, final boolean verbose) { + public static void logUnsuback( + final @NotNull UnsubackOutboundInput unsubackOutboundInput, + final boolean verbose, + final boolean json) { final StringBuilder unsuback = new StringBuilder(); final String clientId = unsubackOutboundInput.getClientInformation().getClientId(); final UnsubackPacket unsubackPacket = unsubackOutboundInput.getUnsubackPacket(); - unsuback.append("Unsuback Reason Codes: {"); + if (json) { + unsuback.append("\"Unsuback Reason Codes (" + unsubackPacket.getReasonCodes().size() + ")\": ["); + } else { + unsuback.append("Unsuback Reason Codes: {"); + } for (final UnsubackReasonCode unsubackReasonCode : unsubackPacket.getReasonCodes()) { - unsuback.append(" [Reason Code: '").append(unsubackReasonCode).append("'],"); + if (json) { + //TODO + unsuback.append(" {\"Reason Code\": \"").append(unsubackReasonCode).append("\"},"); + } else { + unsuback.append(" [Reason Code: '").append(unsubackReasonCode).append("'],"); + } } unsuback.deleteCharAt(unsuback.length() - 1); //delete last comma - unsuback.append(" }"); + if (json) { + unsuback.append(" ]"); + } else { + unsuback.append(" }"); + } if (!verbose) { - LOG.info("Sent UNSUBACK to client '{}': {}", clientId, unsuback); + if (json) { + LOG.info("{\"Event\": \"Sent UNSUBACK\"," + + " \"Client\": \"{}\"," + + " {}}", clientId, unsuback); + } else { + LOG.info("Sent UNSUBACK to client '{}': {}", clientId, unsuback); + } return; } - final String userPropertiesAsString = getUserPropertiesAsString(unsubackPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(unsubackPacket.getUserProperties(), json); final String reasonString = unsubackPacket.getReasonString().orElse(null); - LOG.info("Sent UNSUBACK to client '{}': {}, Reason String: '{}', {}", - clientId, - unsuback, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent UNSUBACK\"," + + " \"Client\": \"{}\"," + + " {}," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + unsuback, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Sent UNSUBACK to client '{}': {}, Reason String: '{}', {}", + clientId, + unsuback, + reasonString, + userPropertiesAsString); + } } - public static void logPingreq(final @NotNull PingReqInboundInput pingReqInboundInput) { + public static void logPingreq( + final @NotNull PingReqInboundInput pingReqInboundInput, + final boolean json) { final String clientId = pingReqInboundInput.getClientInformation().getClientId(); - LOG.info("Received PING REQUEST from client '{}'", clientId); + if (json) { + LOG.info("{\"Event\": \"Received PING REQUEST\"," + + " \"Client\": \"{}\"}", clientId); + } else { + LOG.info("Received PING REQUEST from client '{}'", clientId); + } } - public static void logPingresp(final @NotNull PingRespOutboundInput pingRespOutboundInput) { + public static void logPingresp( + final @NotNull PingRespOutboundInput pingRespOutboundInput, + final boolean json) { final String clientId = pingRespOutboundInput.getClientInformation().getClientId(); - LOG.info("Sent PING RESPONSE to client '{}'", clientId); + if (json) { + LOG.info("{\"Event\": \"Sent PING RESPONSE\"," + + " \"Client\": \"{}\"}", clientId); + } else { + LOG.info("Sent PING RESPONSE to client '{}'", clientId); + } } public static void logPuback( final @NotNull PubackPacket pubackPacket, final @NotNull String clientId, final boolean inbound, - final boolean verbose) { + final boolean verbose, + final boolean json) { final AckReasonCode reasonCode = pubackPacket.getReasonCode(); if (!verbose) { if (inbound) { - LOG.info("Received PUBACK from client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Received PUBACK\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Received PUBACK from client '{}': Reason Code: '{}'", clientId, reasonCode); + } } else { - LOG.info("Sent PUBACK to client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Sent PUBACK\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Sent PUBACK to client '{}': Reason Code: '{}'", clientId, reasonCode); + } } return; } - final String userPropertiesAsString = getUserPropertiesAsString(pubackPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(pubackPacket.getUserProperties(), json); final String reasonString = pubackPacket.getReasonString().orElse(null); if (inbound) { - LOG.info("Received PUBACK from client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Received PUBACK\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Received PUBACK from client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } else { - LOG.info("Sent PUBACK to client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent PUBACK\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Sent PUBACK to client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } } @@ -436,33 +833,70 @@ public static void logPubrec( final @NotNull PubrecPacket pubrecPacket, final @NotNull String clientId, final boolean inbound, - final boolean verbose) { + final boolean verbose, + final boolean json) { final AckReasonCode reasonCode = pubrecPacket.getReasonCode(); if (!verbose) { if (inbound) { - LOG.info("Received PUBREC from client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Received PUBREC\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Received PUBREC from client '{}': Reason Code: '{}'", clientId, reasonCode); + } } else { - LOG.info("Sent PUBREC to client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Sent PUBREC\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Sent PUBREC to client '{}': Reason Code: '{}'", clientId, reasonCode); + } } return; } - final String userPropertiesAsString = getUserPropertiesAsString(pubrecPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(pubrecPacket.getUserProperties(), json); final String reasonString = pubrecPacket.getReasonString().orElse(null); if (inbound) { - LOG.info("Received PUBREC from client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Received PUBREC\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Received PUBREC from client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } else { - LOG.info("Sent PUBREC to client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent PUBREC\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Sent PUBREC to client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } } @@ -470,33 +904,70 @@ public static void logPubrel( final @NotNull PubrelPacket pubrelPacket, final @NotNull String clientId, final boolean inbound, - final boolean verbose) { + final boolean verbose, + final boolean json) { final PubrelReasonCode reasonCode = pubrelPacket.getReasonCode(); if (!verbose) { if (inbound) { - LOG.info("Received PUBREL from client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Received PUBREL\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Received PUBREL from client '{}': Reason Code: '{}'", clientId, reasonCode); + } } else { - LOG.info("Sent PUBREL to client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Sent PUBREL\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + } else { + LOG.info("Sent PUBREL to client '{}': Reason Code: '{}'", clientId, reasonCode); + } } return; } - final String userPropertiesAsString = getUserPropertiesAsString(pubrelPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(pubrelPacket.getUserProperties(), json); final String reasonString = pubrelPacket.getReasonString().orElse(null); if (inbound) { - LOG.info("Received PUBREL from client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Received PUBREL\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Received PUBREL from client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } else { - LOG.info("Sent PUBREL to client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent PUBREL\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Sent PUBREL to client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } } @@ -504,65 +975,188 @@ public static void logPubcomp( final @NotNull PubcompPacket pubcompPacket, final @NotNull String clientId, final boolean inbound, - final boolean verbose) { + final boolean verbose, + final boolean json) { final PubcompReasonCode reasonCode = pubcompPacket.getReasonCode(); if (!verbose) { if (inbound) { - LOG.info("Received PUBCOMP from client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Received PUBCOMP\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + + } else { + LOG.info("Received PUBCOMP from client '{}': Reason Code: '{}'", clientId, reasonCode); + } } else { - LOG.info("Sent PUBCOMP to client '{}': Reason Code: '{}'", clientId, reasonCode); + if (json) { + LOG.info("{\"Event\": \"Sent PUBCOMP\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"}", clientId, reasonCode); + + } else { + LOG.info("Sent PUBCOMP to client '{}': Reason Code: '{}'", clientId, reasonCode); + } } return; } - final String userPropertiesAsString = getUserPropertiesAsString(pubcompPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(pubcompPacket.getUserProperties(), json); final String reasonString = pubcompPacket.getReasonString().orElse(null); if (inbound) { - LOG.info("Received PUBCOMP from client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Received PUBCOMP\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Received PUBCOMP from client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } else { - LOG.info("Sent PUBCOMP to client '{}': Reason Code: '{}', Reason String: '{}', {}", - clientId, - reasonCode, - reasonString, - userPropertiesAsString); + if (json) { + LOG.info("{\"Event\": \"Sent PUBCOMP\"," + + " \"Client\": \"{}\"," + + " \"Reason Code\": \"{}\"," + + " \"Reason String\": \"{}\"," + + " {}}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } else { + LOG.info("Sent PUBCOMP to client '{}': Reason Code: '{}', Reason String: '{}', {}", + clientId, + reasonCode, + reasonString, + userPropertiesAsString); + } } } private static @NotNull String getPublishAsString( - final @NotNull PublishPacket publishPacket, final boolean verbose, final boolean payload) { + final @NotNull PublishPacket publishPacket, + final boolean verbose, + final boolean payload, + final boolean json) { final int qos = publishPacket.getQos().getQosNumber(); final boolean retained = publishPacket.getRetain(); final String payloadAsString; if (payload && publishPacket.getPayload().isPresent()) { - payloadAsString = getStringFromByteBuffer(publishPacket.getPayload().get()); + payloadAsString = getStringFromByteBuffer(publishPacket.getPayload().get(), json); } else { payloadAsString = null; } if (!verbose && !payload) { - return String.format("QoS: '%s'," + " Retained: '%s'", qos, retained); + if (json) { + return String.format("\"QoS\": \"%s\"," + + " \"Retained\": \"%s\"", qos, retained); + } else { + return String.format("QoS: '%s'," + " Retained: '%s'", qos, retained); + } } else if (!verbose) { - return String.format("Payload: '%s'," + " QoS: '%s'," + " Retained: '%s'", payloadAsString, qos, retained); + if (json) { + return String.format("\"Payload (Base64)\": \"%s\"," + + " \"QoS\": \"%s\"," + + " \"Retained\": \"%s\"", payloadAsString, qos, retained); + } else { + return String.format("Payload: '%s'," + " QoS: '%s'," + " Retained: '%s'", payloadAsString, qos, retained); + } } final Optional contentType = publishPacket.getContentType(); - final String correlationDataString = getStringFromByteBuffer(publishPacket.getCorrelationData().orElse(null)); + final String correlationDataString = getStringFromByteBuffer(publishPacket.getCorrelationData().orElse(null), json); final Optional responseTopic = publishPacket.getResponseTopic(); final Optional messageExpiryInterval = publishPacket.getMessageExpiryInterval(); final boolean dupFlag = publishPacket.getDupFlag(); final Optional payloadFormatIndicator = publishPacket.getPayloadFormatIndicator(); final List subscriptionIdentifiers = publishPacket.getSubscriptionIdentifiers(); - final String userPropertiesAsString = getUserPropertiesAsString(publishPacket.getUserProperties()); + final String userPropertiesAsString = getUserPropertiesAsString(publishPacket.getUserProperties(), json); if (!payload) { - return String.format("QoS: '%s'," + + if (json) { + return String.format("\"QoS\": \"%s\"," + + " \"Retained\": \"%s\"," + + " \"Message Expiry Interval\": \"%s\"," + + " \"Duplicate Delivery\": \"%s\"," + + " \"Correlation Data\": \"%s\"," + + " \"Response Topic\": \"%s\"," + + " \"Content Type\": \"%s\"," + + " \"Payload Format Indicator\": \"%s\"," + + " \"Subscription Identifiers\": \"%s\"," + + " %s", + qos, + retained, + messageExpiryInterval.orElse(null), + dupFlag, + correlationDataString, + responseTopic.orElse(null), + contentType.orElse(null), + payloadFormatIndicator.orElse(null), + subscriptionIdentifiers, + userPropertiesAsString); + } else { + return String.format("QoS: '%s'," + + " Retained: '%s'," + + " Message Expiry Interval: '%s'," + + " Duplicate Delivery: '%s'," + + " Correlation Data: '%s'," + + " Response Topic: '%s'," + + " Content Type: '%s'," + + " Payload Format Indicator: '%s'," + + " Subscription Identifiers: '%s'," + + " %s", + qos, + retained, + messageExpiryInterval.orElse(null), + dupFlag, + correlationDataString, + responseTopic.orElse(null), + contentType.orElse(null), + payloadFormatIndicator.orElse(null), + subscriptionIdentifiers, + userPropertiesAsString); + } + } + + if (json) { + return String.format("\"Payload (Base64)\": \"%s\"," + + " \"QoS\": \"%s\"," + + " \"Retained\": \"%s\"," + + " \"Message Expiry Interval\": \"%s\"," + + " \"Duplicate Delivery\": \"%s\"," + + " \"Correlation Data\": \"%s\"," + + " \"Response Topic\": \"%s\"," + + " \"Content Type\": \"%s\"," + + " \"Payload Format Indicator\": \"%s\"," + + " \"Subscription Identifiers\": \"%s\"," + + " %s", + payloadAsString, + qos, + retained, + messageExpiryInterval.orElse(null), + dupFlag, + correlationDataString, + responseTopic.orElse(null), + contentType.orElse(null), + payloadFormatIndicator.orElse(null), + subscriptionIdentifiers, + userPropertiesAsString); + } else { + return String.format("Payload: '%s'," + + " QoS: '%s'," + " Retained: '%s'," + " Message Expiry Interval: '%s'," + " Duplicate Delivery: '%s'," + @@ -572,6 +1166,7 @@ public static void logPubcomp( " Payload Format Indicator: '%s'," + " Subscription Identifiers: '%s'," + " %s", + payloadAsString, qos, retained, messageExpiryInterval.orElse(null), @@ -583,32 +1178,9 @@ public static void logPubcomp( subscriptionIdentifiers, userPropertiesAsString); } - - return String.format("Payload: '%s'," + - " QoS: '%s'," + - " Retained: '%s'," + - " Message Expiry Interval: '%s'," + - " Duplicate Delivery: '%s'," + - " Correlation Data: '%s'," + - " Response Topic: '%s'," + - " Content Type: '%s'," + - " Payload Format Indicator: '%s'," + - " Subscription Identifiers: '%s'," + - " %s", - payloadAsString, - qos, - retained, - messageExpiryInterval.orElse(null), - dupFlag, - correlationDataString, - responseTopic.orElse(null), - contentType.orElse(null), - payloadFormatIndicator.orElse(null), - subscriptionIdentifiers, - userPropertiesAsString); } - private static @Nullable String getStringFromByteBuffer(final @Nullable ByteBuffer buffer) { + private static @Nullable String getStringFromByteBuffer(final @Nullable ByteBuffer buffer, final boolean json) { if (buffer == null) { return null; } @@ -616,7 +1188,11 @@ public static void logPubcomp( for (int i = 0; i < buffer.remaining(); i++) { bytes[i] = buffer.get(i); } - return new String(bytes, UTF_8); + if (json) { + return Base64.getEncoder().encodeToString(bytes); + } else { + return new String(bytes, UTF_8); + } } private static @Nullable String getHexStringFromByteBuffer(final @Nullable ByteBuffer buffer) { @@ -641,24 +1217,46 @@ public static void logPubcomp( return new String(out); } - private static @NotNull String getUserPropertiesAsString(final @Nullable UserProperties userProperties) { + private static @NotNull String getUserPropertiesAsString( + final @Nullable UserProperties userProperties, + final boolean json) { if (userProperties == null) { - return "User Properties: 'null'"; + if (json) { + return "\"User Properties\": \"null\""; + } else { + return "User Properties: 'null'"; + } } final List userPropertyList = userProperties.asList(); if (userPropertyList.isEmpty()) { - return "User Properties: 'null'"; + if (json) { + return "\"User Properties\": \"null\""; + } else { + return "User Properties: 'null'"; + } } final StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < userPropertyList.size(); i++) { final UserProperty userProperty = userPropertyList.get(i); if (i == 0) { - stringBuilder.append("User Properties: "); + if (json) { + stringBuilder.append("\"User Properties (" + userPropertyList.size() + ")\": ["); + } else { + stringBuilder.append("User Properties: "); + } } else { stringBuilder.append(", "); } - stringBuilder.append("[Name: '").append(userProperty.getName()); - stringBuilder.append("', Value: '").append(userProperty.getValue()).append("']"); + if (json) { + stringBuilder.append("{\"Name (" + i + ")\": \"").append(userProperty.getName()); + stringBuilder.append("\", \"Value (" + i + ")\": \"").append(userProperty.getValue()).append("\"}"); + if (i == userPropertyList.size() - 1) { + stringBuilder.append("]"); + } + } else { + stringBuilder.append("[Name: '").append(userProperty.getName()); + stringBuilder.append("', Value: '").append(userProperty.getValue()).append("']"); + } } return stringBuilder.toString(); } diff --git a/src/main/resources/config.xsd b/src/main/resources/config.xsd index 722c1db..dd6be61 100644 --- a/src/main/resources/config.xsd +++ b/src/main/resources/config.xsd @@ -22,6 +22,7 @@ + diff --git a/src/test/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReaderTest.java b/src/test/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReaderTest.java index 0728c21..4daa218 100644 --- a/src/test/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReaderTest.java +++ b/src/test/java/com/hivemq/extensions/log/mqtt/message/config/ExtensionConfigReaderTest.java @@ -35,7 +35,7 @@ */ class ExtensionConfigReaderTest { - private final int totalAvailableFlags = 21; + private final int totalAvailableFlags = 22; private final @NotNull List defaultProperties = List.of(ExtensionConfigProperties.CLIENT_CONNECT, ExtensionConfigProperties.CONNACK_SEND, @@ -57,7 +57,8 @@ class ExtensionConfigReaderTest { ExtensionConfigProperties.PUBCOMP_RECEIVED, ExtensionConfigProperties.PUBCOMP_SEND, ExtensionConfigProperties.VERBOSE, - ExtensionConfigProperties.PAYLOAD); + ExtensionConfigProperties.PAYLOAD, + ExtensionConfigProperties.JSON); @Test void defaultPropertiesWhenNoPropertyFileInConfigFolder(@TempDir final @NotNull Path tempDir) { @@ -92,6 +93,7 @@ void defaultPropertiesWhenNoPropertyFileInConfigFolder(@TempDir final @NotNull P assertTrue(extensionConfigProperties.isPubcompSend()); assertFalse(extensionConfigProperties.isVerbose()); assertTrue(extensionConfigProperties.isPayload()); + assertFalse(extensionConfigProperties.isJson()); } @Test @@ -109,6 +111,7 @@ void nonEmptyPropertiesWhenPropertyFileInConfigFolder() { assertFalse(extensionConfigProperties.isVerbose()); assertTrue(extensionConfigProperties.isPayload()); + assertFalse(extensionConfigProperties.isJson()); assertFalse(extensionConfigProperties.isPublishReceived()); assertFalse(extensionConfigProperties.isPublishSend()); } @@ -123,6 +126,7 @@ void nonEmptyPropertiesWhenConfigFileInConfFolder() { assertFalse(extensionConfigXml.isVerbose()); assertTrue(extensionConfigXml.isPayload()); + assertFalse(extensionConfigXml.isJson()); assertFalse(extensionConfigXml.isPublishReceived()); assertFalse(extensionConfigXml.isPublishSend()); } @@ -156,6 +160,7 @@ void defaultPropertiesWhenInvalidConfigFileInConfFolder() { assertTrue(extensionConfigXml.isPubcompSend()); assertFalse(extensionConfigXml.isVerbose()); assertTrue(extensionConfigXml.isPayload()); + assertFalse(extensionConfigXml.isJson()); } } diff --git a/src/test/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtilTest.java b/src/test/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtilTest.java index a459819..ec2ea36 100644 --- a/src/test/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtilTest.java +++ b/src/test/java/com/hivemq/extensions/log/mqtt/message/util/MessageLogUtilTest.java @@ -66,11 +66,11 @@ void test_lifecycle_and_interceptor_disconnect_logs_have_same_format() { MessageLogUtil.logDisconnect("Received DISCONNECT from client 'clientId':", new TestDisconnect(DisconnectedReasonCode.BAD_AUTHENTICATION_METHOD, "Okay", new TestUserProperties(3)), - false); + false,false); assertEquals(expectedLog, logbackTestAppender.getEvents().get(0).getFormattedMessage()); - MessageLogUtil.logDisconnect(createLifeCycleCompareDisconnect(), "clientId", true, false); + MessageLogUtil.logDisconnect(createLifeCycleCompareDisconnect(), "clientId", true,false,false); assertEquals(expectedLog, logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @@ -80,7 +80,7 @@ void test_log_lifecycle_disconnect_verbose_all_set() { new TestDisconnect(DisconnectedReasonCode.BAD_AUTHENTICATION_METHOD, "ReasonString", new TestUserProperties(5)), - true); + true,false); assertEquals( "Received DISCONNECT from client 'clientid': Reason Code: 'BAD_AUTHENTICATION_METHOD', Reason String: 'ReasonString', User Properties: [Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1'], [Name: 'name2', Value: 'value2'], [Name: 'name3', Value: 'value3'], [Name: 'name4', Value: 'value4']", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -90,7 +90,7 @@ void test_log_lifecycle_disconnect_verbose_all_set() { void test_log_lifecycle_disconnect_verbose_none_set() { MessageLogUtil.logDisconnect("Received DISCONNECT from client 'clientid':", new TestDisconnect(null, null, null), - true); + true,false); assertEquals( "Received DISCONNECT from client 'clientid': Reason Code: 'null', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -100,7 +100,7 @@ void test_log_lifecycle_disconnect_verbose_none_set() { void test_log_lifecycle_disconnect_verbose_user_properties_empty() { MessageLogUtil.logDisconnect("Received DISCONNECT from client 'clientid':", new TestDisconnect(null, null, new TestUserProperties(0)), - true); + true,false); assertEquals( "Received DISCONNECT from client 'clientid': Reason Code: 'null', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -110,14 +110,14 @@ void test_log_lifecycle_disconnect_verbose_user_properties_empty() { void test_log_lifecycle_disconnect_not_verbose() { MessageLogUtil.logDisconnect("Received DISCONNECT from client 'clientid':", new TestDisconnect(null, null, null), - false); + false,false); assertEquals("Received DISCONNECT from client 'clientid': Reason Code: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_inbound_disconnect_verbose_all_set() { - MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", true, true); + MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", true, true,false); assertEquals( "Received DISCONNECT from client 'clientId': Reason Code: 'NOT_AUTHORIZED', Reason String: 'Okay', Server Reference: 'Server2', Session Expiry: '123', User Properties: [Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1']", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -125,7 +125,7 @@ void test_log_inbound_disconnect_verbose_all_set() { @Test void test_log_inbound_disconnect_verbose_none_set() { - MessageLogUtil.logDisconnect(createEmptyDisconnect(), "clientId", true, true); + MessageLogUtil.logDisconnect(createEmptyDisconnect(), "clientId", true, true,false); assertEquals( "Received DISCONNECT from client 'clientId': Reason Code: 'NOT_AUTHORIZED', Reason String: 'null', Server Reference: 'null', Session Expiry: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -133,21 +133,21 @@ void test_log_inbound_disconnect_verbose_none_set() { @Test void test_log_inbound_disconnect_not_verbose_all_set() { - MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", true, false); + MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", true, false,false); assertEquals("Received DISCONNECT from client 'clientId': Reason Code: 'NOT_AUTHORIZED'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_inbound_disconnect_not_verbose_none_set() { - MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", true, false); + MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", true, false,false); assertEquals("Received DISCONNECT from client 'clientId': Reason Code: 'NOT_AUTHORIZED'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_outound_disconnect_verbose_all_set() { - MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", false, true); + MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", false, true,false); assertEquals( "Sent DISCONNECT to client 'clientId': Reason Code: 'NOT_AUTHORIZED', Reason String: 'Okay', Server Reference: 'Server2', Session Expiry: '123', User Properties: [Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1']", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -155,7 +155,7 @@ void test_log_outound_disconnect_verbose_all_set() { @Test void test_log_outound_disconnect_verbose_none_set() { - MessageLogUtil.logDisconnect(createEmptyDisconnect(), "clientId", false, true); + MessageLogUtil.logDisconnect(createEmptyDisconnect(), "clientId", false, true,false); assertEquals( "Sent DISCONNECT to client 'clientId': Reason Code: 'NOT_AUTHORIZED', Reason String: 'null', Server Reference: 'null', Session Expiry: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -163,21 +163,21 @@ void test_log_outound_disconnect_verbose_none_set() { @Test void test_log_outound_disconnect_not_verbose_all_set() { - MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", false, false); + MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", false, false,false); assertEquals("Sent DISCONNECT to client 'clientId': Reason Code: 'NOT_AUTHORIZED'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_outound_disconnect_not_verbose_none_set() { - MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", false, false); + MessageLogUtil.logDisconnect(createFullDisconnect(), "clientId", false, false,false); assertEquals("Sent DISCONNECT to client 'clientId': Reason Code: 'NOT_AUTHORIZED'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_connect_verbose_all_set() { - MessageLogUtil.logConnect(createFullConnect(), true, true); + MessageLogUtil.logConnect(createFullConnect(), true, true,false); assertEquals("Received CONNECT from client 'clientid': Protocol version: 'V_5', Clean Start: 'false', " + "Session Expiry Interval: '10000', Keep Alive: '20000', Maximum Packet Size: '40000', " + "Receive Maximum: '30000', Topic Alias Maximum: '50000', Request Problem Information: 'true', " + @@ -195,7 +195,7 @@ void test_log_connect_verbose_all_set() { @Test void test_log_connect_verbose_no_payload_all_set() { - MessageLogUtil.logConnect(createFullConnect(), true, false); + MessageLogUtil.logConnect(createFullConnect(), true,false,false); assertEquals("Received CONNECT from client 'clientid': Protocol version: 'V_5', Clean Start: 'false', " + "Session Expiry Interval: '10000', Keep Alive: '20000', Maximum Packet Size: '40000', " + "Receive Maximum: '30000', Topic Alias Maximum: '50000', Request Problem Information: 'true', " + @@ -213,7 +213,7 @@ void test_log_connect_verbose_no_payload_all_set() { @Test void test_log_connect_verbose_none_set() { - MessageLogUtil.logConnect(createEmptyConnect(), true, true); + MessageLogUtil.logConnect(createEmptyConnect(), true, true,false); assertEquals("Received CONNECT from client 'clientid': Protocol version: 'V_5', Clean Start: 'false', " + "Session Expiry Interval: '10000', Keep Alive: '0', Maximum Packet Size: '0', Receive Maximum: '0', " + "Topic Alias Maximum: '0', Request Problem Information: 'false', Request Response Information: 'false', " + @@ -223,14 +223,14 @@ void test_log_connect_verbose_none_set() { @Test void test_log_connect_not_verbose_all_set() { - MessageLogUtil.logConnect(createFullConnect(), false, true); + MessageLogUtil.logConnect(createFullConnect(), false, true,false); assertEquals("Received CONNECT from client 'clientid': Protocol version: 'V_5', Clean Start: 'false', " + "Session Expiry Interval: '10000'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_connack_verbose_all_set() { - MessageLogUtil.logConnack(createFullConnack(), true); + MessageLogUtil.logConnack(createFullConnack(), true,false); assertEquals("Sent CONNACK to client 'clientid': Reason Code: 'SUCCESS', Session Present: 'false'," + " Session Expiry Interval: '100', Assigned ClientId 'overwriteClientId', Maximum QoS: 'AT_MOST_ONCE'," + @@ -244,14 +244,14 @@ void test_log_connack_verbose_all_set() { @Test void test_log_connack_not_verbose_all_set() { - MessageLogUtil.logConnack(createFullConnack(), false); + MessageLogUtil.logConnack(createFullConnack(), false,false); assertEquals("Sent CONNACK to client 'clientid': Reason Code: 'SUCCESS', Session Present: 'false'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_connack_verbose_none_set() { - MessageLogUtil.logConnack(createEmptyConnack(), true); + MessageLogUtil.logConnack(createEmptyConnack(), true,false); assertEquals("Sent CONNACK to client 'clientid': Reason Code: 'SUCCESS', Session Present: 'false'," + " Session Expiry Interval: 'null', Assigned ClientId 'null', Maximum QoS: 'null'," + " Maximum Packet Size: '2', Receive Maximum: '1', Topic Alias Maximum: '3', Reason String: 'null'," + @@ -264,14 +264,14 @@ void test_log_connack_verbose_none_set() { @Test void test_log_connack_not_verbose_none_set() { - MessageLogUtil.logConnack(createEmptyConnack(), false); + MessageLogUtil.logConnack(createEmptyConnack(), false,false); assertEquals("Sent CONNACK to client 'clientid': Reason Code: 'SUCCESS', Session Present: 'false'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_publish_verbose_all_set() { - MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), true, true); + MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), true, true,false); assertEquals( "Sent PUBLISH to client 'clientid' on topic 'topic': Payload: 'message', QoS: '1', Retained: 'false', " + "Message Expiry Interval: '10000', Duplicate Delivery: 'false', Correlation Data: 'data', " + @@ -283,7 +283,7 @@ void test_log_publish_verbose_all_set() { @Test void test_log_publish_verbose_no_payload_all_set() { - MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), true, false); + MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), true, false,false); assertEquals( "Sent PUBLISH to client 'clientid' on topic 'topic': QoS: '1', Retained: 'false', " + "Message Expiry Interval: '10000', Duplicate Delivery: 'false', Correlation Data: 'data', " + @@ -295,7 +295,7 @@ void test_log_publish_verbose_no_payload_all_set() { @Test void test_log_publish_not_verbose_all_set() { - MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), false, true); + MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), false, true,false); assertEquals( "Sent PUBLISH to client 'clientid' on topic 'topic': Payload: 'message', QoS: '1', Retained: 'false'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -303,7 +303,7 @@ void test_log_publish_not_verbose_all_set() { @Test void test_log_publish_not_verbose_no_payload_all_set() { - MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), false, false); + MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createFullPublish(), false, false,false); assertEquals( "Sent PUBLISH to client 'clientid' on topic 'topic': QoS: '1', Retained: 'false'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -311,7 +311,7 @@ void test_log_publish_not_verbose_no_payload_all_set() { @Test void test_log_publish_verbose_none_set() { - MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createEmptyPublish(), true, true); + MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createEmptyPublish(), true, true,false); assertEquals( "Sent PUBLISH to client 'clientid' on topic 'topic': Payload: 'message', QoS: '1', Retained: 'false'," + " Message Expiry Interval: 'null', Duplicate Delivery: 'false', Correlation Data: 'null'," + @@ -322,7 +322,7 @@ void test_log_publish_verbose_none_set() { @Test void test_log_publish_verbose_no_payload_none_set() { - MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createEmptyPublish(), true, false); + MessageLogUtil.logPublish("Sent PUBLISH to client 'clientid' on topic", createEmptyPublish(), true, false,false); assertEquals( "Sent PUBLISH to client 'clientid' on topic 'topic': QoS: '1', Retained: 'false'," + " Message Expiry Interval: 'null', Duplicate Delivery: 'false', Correlation Data: 'null'," + @@ -333,7 +333,7 @@ void test_log_publish_verbose_no_payload_none_set() { @Test void test_log_subscribe_verbose_all_set() { - MessageLogUtil.logSubscribe(createFullSubsribe(), true); + MessageLogUtil.logSubscribe(createFullSubsribe(), true,false); assertEquals("Received SUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic1', QoS: '2', Retain As Published: 'false', No Local: 'false', Retain Handling: 'DO_NOT_SEND'], " + "[Topic: 'topic2', QoS: '0', Retain As Published: 'true', No Local: 'true', Retain Handling: 'SEND_IF_NEW_SUBSCRIPTION'] }, " + @@ -343,7 +343,7 @@ void test_log_subscribe_verbose_all_set() { @Test void test_log_subscribe_not_verbose_all_set() { - MessageLogUtil.logSubscribe(createFullSubsribe(), false); + MessageLogUtil.logSubscribe(createFullSubsribe(), false,false); assertEquals("Received SUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic1', QoS: '2'], [Topic: 'topic2', QoS: '0'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -351,7 +351,7 @@ void test_log_subscribe_not_verbose_all_set() { @Test void test_log_subscribe_verbose_none_set() { - MessageLogUtil.logSubscribe(createEmptySubscribe(), true); + MessageLogUtil.logSubscribe(createEmptySubscribe(), true,false); assertEquals("Received SUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic', QoS: '0', Retain As Published: 'false', No Local: 'false', Retain Handling: 'SEND'] }, " + "Subscription Identifier: 'null', User Properties: 'null'", @@ -360,14 +360,14 @@ void test_log_subscribe_verbose_none_set() { @Test void test_log_subscribe_not_verbose_none_set() { - MessageLogUtil.logSubscribe(createEmptySubscribe(), false); + MessageLogUtil.logSubscribe(createEmptySubscribe(), false,false); assertEquals("Received SUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic', QoS: '0'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_suback_verbose_all_set() { - MessageLogUtil.logSuback(createFullSuback(), true); + MessageLogUtil.logSuback(createFullSuback(), true,false); assertEquals("Sent SUBACK to client 'clientid': Suback Reason Codes: { " + "[Reason Code: 'GRANTED_QOS_1'], [Reason Code: 'GRANTED_QOS_0'] }, Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1']", @@ -376,7 +376,7 @@ void test_log_suback_verbose_all_set() { @Test void test_log_suback_not_verbose_all_set() { - MessageLogUtil.logSuback(createFullSuback(), false); + MessageLogUtil.logSuback(createFullSuback(), false,false); assertEquals("Sent SUBACK to client 'clientid': Suback Reason Codes: { " + "[Reason Code: 'GRANTED_QOS_1'], [Reason Code: 'GRANTED_QOS_0'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -384,7 +384,7 @@ void test_log_suback_not_verbose_all_set() { @Test void test_log_suback_verbose_none_set() { - MessageLogUtil.logSuback(createEmptySuback(), true); + MessageLogUtil.logSuback(createEmptySuback(), true,false); assertEquals("Sent SUBACK to client 'clientid': Suback Reason Codes: { " + "[Reason Code: 'GRANTED_QOS_1'] }, Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -392,14 +392,14 @@ void test_log_suback_verbose_none_set() { @Test void test_log_suback_not_verbose_none_set() { - MessageLogUtil.logSuback(createEmptySuback(), false); + MessageLogUtil.logSuback(createEmptySuback(), false,false); assertEquals("Sent SUBACK to client 'clientid': Suback Reason Codes: { " + "[Reason Code: 'GRANTED_QOS_1'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_unsuback_verbose_all_set() { - MessageLogUtil.logUnsuback(createFullUnsuback(), true); + MessageLogUtil.logUnsuback(createFullUnsuback(), true,false); assertEquals("Sent UNSUBACK to client 'clientid': Unsuback Reason Codes: { " + "[Reason Code: 'NOT_AUTHORIZED'], [Reason Code: 'SUCCESS'] }, Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1'], [Name: 'name2', Value: 'value2']", @@ -408,7 +408,7 @@ void test_log_unsuback_verbose_all_set() { @Test void test_log_unsuback_not_verbose_all_set() { - MessageLogUtil.logUnsuback(createFullUnsuback(), false); + MessageLogUtil.logUnsuback(createFullUnsuback(), false,false); assertEquals("Sent UNSUBACK to client 'clientid': Unsuback Reason Codes: { " + "[Reason Code: 'NOT_AUTHORIZED'], [Reason Code: 'SUCCESS'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -416,7 +416,7 @@ void test_log_unsuback_not_verbose_all_set() { @Test void test_log_unsuback_verbose_none_set() { - MessageLogUtil.logUnsuback(createEmptyUnsuback(), true); + MessageLogUtil.logUnsuback(createEmptyUnsuback(), true,false); assertEquals("Sent UNSUBACK to client 'clientid': Unsuback Reason Codes: { " + "[Reason Code: 'NOT_AUTHORIZED'] }, Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -424,14 +424,14 @@ void test_log_unsuback_verbose_none_set() { @Test void test_log_unsuback_not_verbose_none_set() { - MessageLogUtil.logUnsuback(createEmptyUnsuback(), false); + MessageLogUtil.logUnsuback(createEmptyUnsuback(), false,false); assertEquals("Sent UNSUBACK to client 'clientid': Unsuback Reason Codes: { " + "[Reason Code: 'NOT_AUTHORIZED'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_unsubscribe_verbose_all_set() { - MessageLogUtil.logUnsubscribe(createFullUnsubsribe(), true); + MessageLogUtil.logUnsubscribe(createFullUnsubsribe(), true,false); assertEquals("Received UNSUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic1'] }, User Properties: " + "[Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1']", @@ -440,14 +440,14 @@ void test_log_unsubscribe_verbose_all_set() { @Test void test_log_unsubscribe_not_verbose_all_set() { - MessageLogUtil.logUnsubscribe(createFullUnsubsribe(), false); + MessageLogUtil.logUnsubscribe(createFullUnsubsribe(), false,false); assertEquals("Received UNSUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic1'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_unsubscribe_verbose_none_set() { - MessageLogUtil.logUnsubscribe(createEmptyUnsubscribe(), true); + MessageLogUtil.logUnsubscribe(createEmptyUnsubscribe(), true,false); assertEquals("Received UNSUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic1'], [Topic: 'topic2'] }, User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -455,28 +455,28 @@ void test_log_unsubscribe_verbose_none_set() { @Test void test_log_unsubscribe_not_verbose_none_set() { - MessageLogUtil.logUnsubscribe(createEmptyUnsubscribe(), false); + MessageLogUtil.logUnsubscribe(createEmptyUnsubscribe(), false,false); assertEquals("Received UNSUBSCRIBE from client 'clientid': Topics: { " + "[Topic: 'topic1'], [Topic: 'topic2'] }", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pingreq() { - MessageLogUtil.logPingreq(createPingreq()); + MessageLogUtil.logPingreq(createPingreq(),false); assertEquals("Received PING REQUEST from client 'clientid'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pingresp() { - MessageLogUtil.logPingresp(createPingresp()); + MessageLogUtil.logPingresp(createPingresp(),false); assertEquals("Sent PING RESPONSE to client 'clientid'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_puback_inbound_verbose_all_set() { - MessageLogUtil.logPuback(createFullPuback(), "clientid", true, true); + MessageLogUtil.logPuback(createFullPuback(), "clientid", true, true,false); assertEquals( "Received PUBACK from client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1']", @@ -485,14 +485,14 @@ void test_log_puback_inbound_verbose_all_set() { @Test void test_log_puback_inbound_not_verbose_all_set() { - MessageLogUtil.logPuback(createFullPuback(), "clientid", true, false); + MessageLogUtil.logPuback(createFullPuback(), "clientid", true, false,false); assertEquals("Received PUBACK from client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_puback_inbound_verbose_none_set() { - MessageLogUtil.logPuback(createEmptyPuback(), "clientid", true, true); + MessageLogUtil.logPuback(createEmptyPuback(), "clientid", true, true,false); assertEquals( "Received PUBACK from client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -500,14 +500,14 @@ void test_log_puback_inbound_verbose_none_set() { @Test void test_log_puback_inbound_not_verbose_none_set() { - MessageLogUtil.logPuback(createEmptyPuback(), "clientid", true, false); + MessageLogUtil.logPuback(createEmptyPuback(), "clientid", true, false,false); assertEquals("Received PUBACK from client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_puback_outbound_verbose_all_set() { - MessageLogUtil.logPuback(createFullPuback(), "clientid", false, true); + MessageLogUtil.logPuback(createFullPuback(), "clientid", false, true,false); assertEquals( "Sent PUBACK to client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0'], [Name: 'name1', Value: 'value1']", @@ -516,14 +516,14 @@ void test_log_puback_outbound_verbose_all_set() { @Test void test_log_puback_outbound_not_verbose_all_set() { - MessageLogUtil.logPuback(createFullPuback(), "clientid", false, false); + MessageLogUtil.logPuback(createFullPuback(), "clientid", false, false,false); assertEquals("Sent PUBACK to client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_puback_outbound_verbose_none_set() { - MessageLogUtil.logPuback(createEmptyPuback(), "clientid", false, true); + MessageLogUtil.logPuback(createEmptyPuback(), "clientid", false, true,false); assertEquals( "Sent PUBACK to client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -531,14 +531,14 @@ void test_log_puback_outbound_verbose_none_set() { @Test void test_log_puback_outbound_not_verbose_none_set() { - MessageLogUtil.logPuback(createEmptyPuback(), "clientid", false, false); + MessageLogUtil.logPuback(createEmptyPuback(), "clientid", false, false,false); assertEquals("Sent PUBACK to client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrec_inbound_verbose_all_set() { - MessageLogUtil.logPubrec(createFullPubrec(), "clientid", true, true); + MessageLogUtil.logPubrec(createFullPubrec(), "clientid", true, true,false); assertEquals( "Received PUBREC from client 'clientid': Reason Code: 'SUCCESS', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0']", @@ -547,14 +547,14 @@ void test_log_pubrec_inbound_verbose_all_set() { @Test void test_log_pubrec_inbound_not_verbose_all_set() { - MessageLogUtil.logPubrec(createFullPubrec(), "clientid", true, false); + MessageLogUtil.logPubrec(createFullPubrec(), "clientid", true, false,false); assertEquals("Received PUBREC from client 'clientid': Reason Code: 'SUCCESS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrec_inbound_verbose_none_set() { - MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", true, true); + MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", true, true,false); assertEquals( "Received PUBREC from client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -562,14 +562,14 @@ void test_log_pubrec_inbound_verbose_none_set() { @Test void test_log_pubrec_inbound_not_verbose_none_set() { - MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", true, false); + MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", true, false,false); assertEquals("Received PUBREC from client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrec_outbound_verbose_all_set() { - MessageLogUtil.logPubrec(createFullPubrec(), "clientid", false, true); + MessageLogUtil.logPubrec(createFullPubrec(), "clientid", false, true,false); assertEquals( "Sent PUBREC to client 'clientid': Reason Code: 'SUCCESS', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0']", @@ -578,14 +578,14 @@ void test_log_pubrec_outbound_verbose_all_set() { @Test void test_log_pubrec_outbound_not_verbose_all_set() { - MessageLogUtil.logPubrec(createFullPubrec(), "clientid", false, false); + MessageLogUtil.logPubrec(createFullPubrec(), "clientid", false, false,false); assertEquals("Sent PUBREC to client 'clientid': Reason Code: 'SUCCESS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrec_outbound_verbose_none_set() { - MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", false, true); + MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", false, true,false); assertEquals( "Sent PUBREC to client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -593,14 +593,14 @@ void test_log_pubrec_outbound_verbose_none_set() { @Test void test_log_pubrec_outbound_not_verbose_none_set() { - MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", false, false); + MessageLogUtil.logPubrec(createEmptyPubrec(), "clientid", false, false,false); assertEquals("Sent PUBREC to client 'clientid': Reason Code: 'NO_MATCHING_SUBSCRIBERS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrel_inbound_verbose_all_set() { - MessageLogUtil.logPubrel(createFullPubrel(), "clientid", true, true); + MessageLogUtil.logPubrel(createFullPubrel(), "clientid", true, true,false); assertEquals( "Received PUBREL from client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0']", @@ -609,14 +609,14 @@ void test_log_pubrel_inbound_verbose_all_set() { @Test void test_log_pubrel_inbound_not_verbose_all_set() { - MessageLogUtil.logPubrel(createFullPubrel(), "clientid", true, false); + MessageLogUtil.logPubrel(createFullPubrel(), "clientid", true, false,false); assertEquals("Received PUBREL from client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrel_inbound_verbose_none_set() { - MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", true, true); + MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", true, true,false); assertEquals( "Received PUBREL from client 'clientid': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -624,14 +624,14 @@ void test_log_pubrel_inbound_verbose_none_set() { @Test void test_log_pubrel_inbound_not_verbose_none_set() { - MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", true, false); + MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", true, false,false); assertEquals("Received PUBREL from client 'clientid': Reason Code: 'SUCCESS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrel_outbound_verbose_all_set() { - MessageLogUtil.logPubrel(createFullPubrel(), "clientid", false, true); + MessageLogUtil.logPubrel(createFullPubrel(), "clientid", false, true,false); assertEquals( "Sent PUBREL to client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0']", @@ -640,14 +640,14 @@ void test_log_pubrel_outbound_verbose_all_set() { @Test void test_log_pubrel_outbound_not_verbose_all_set() { - MessageLogUtil.logPubrel(createFullPubrel(), "clientid", false, false); + MessageLogUtil.logPubrel(createFullPubrel(), "clientid", false, false,false); assertEquals("Sent PUBREL to client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubrel_outbound_verbose_none_set() { - MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", false, true); + MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", false, true,false); assertEquals( "Sent PUBREL to client 'clientid': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -655,14 +655,14 @@ void test_log_pubrel_outbound_verbose_none_set() { @Test void test_log_pubrel_outbound_not_verbose_none_set() { - MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", false, false); + MessageLogUtil.logPubrel(createEmptyPubrel(), "clientid", false, false,false); assertEquals("Sent PUBREL to client 'clientid': Reason Code: 'SUCCESS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubcomp_inbound_verbose_all_set() { - MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", true, true); + MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", true, true,false); assertEquals( "Received PUBCOMP from client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0']", @@ -671,14 +671,14 @@ void test_log_pubcomp_inbound_verbose_all_set() { @Test void test_log_pubcomp_inbound_not_verbose_all_set() { - MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", true, false); + MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", true, false,false); assertEquals("Received PUBCOMP from client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubcomp_inbound_verbose_none_set() { - MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", true, true); + MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", true, true,false); assertEquals( "Received PUBCOMP from client 'clientid': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -686,14 +686,14 @@ void test_log_pubcomp_inbound_verbose_none_set() { @Test void test_log_pubcomp_inbound_not_verbose_none_set() { - MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", true, false); + MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", true, false,false); assertEquals("Received PUBCOMP from client 'clientid': Reason Code: 'SUCCESS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubcomp_outbound_verbose_all_set() { - MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", false, true); + MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", false, true,false); assertEquals( "Sent PUBCOMP to client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND', Reason String: 'Okay', User Properties: " + "[Name: 'name0', Value: 'value0']", @@ -702,14 +702,14 @@ void test_log_pubcomp_outbound_verbose_all_set() { @Test void test_log_pubcomp_outbound_not_verbose_all_set() { - MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", false, false); + MessageLogUtil.logPubcomp(createFullPubcomp(), "clientid", false, false,false); assertEquals("Sent PUBCOMP to client 'clientid': Reason Code: 'PACKET_IDENTIFIER_NOT_FOUND'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); } @Test void test_log_pubcomp_outbound_verbose_none_set() { - MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", false, true); + MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", false, true,false); assertEquals( "Sent PUBCOMP to client 'clientid': Reason Code: 'SUCCESS', Reason String: 'null', User Properties: 'null'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); @@ -717,7 +717,7 @@ void test_log_pubcomp_outbound_verbose_none_set() { @Test void test_log_pubcomp_outbound_not_verbose_none_set() { - MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", false, false); + MessageLogUtil.logPubcomp(createEmptyPubcomp(), "clientid", false, false,false); assertEquals("Sent PUBCOMP to client 'clientid': Reason Code: 'SUCCESS'", logbackTestAppender.getEvents().get(0).getFormattedMessage()); }