diff --git a/Mirth/Mirthix_channel.xml b/Mirth/Mirthix_channel.xml
new file mode 100644
index 0000000..a230c1b
--- /dev/null
+++ b/Mirth/Mirthix_channel.xml
@@ -0,0 +1,708 @@
+
+ ae0b7d75-5ce1-484b-afe0-aff6fa412073
+ 2
+ Zabbix Monitoring
+ MIRTHIX - Zabbix agent implementation for Mirth Connect.
+https://github.com/cboyer/mirth-zabbix
+ true
+
+
+ America/Toronto
+
+ 445
+
+ 0
+ sourceConnector
+
+
+
+ 0.0.0.0
+ 10050
+
+
+ d1
+ true
+ false
+ true
+
+ Default Resource
+
+
+
+ Basic
+
+ 0A
+
+ true
+
+
+ false
+ 5000
+ 0
+ 65536
+ 1000
+ true
+ true
+ DEFAULT_ENCODING
+ 0
+
+
+
+
+
+
+ 0
+ Decode base64
+
+ JavaScript
+
+
+ Script
+ /**
+ * MIRTHIX - Zabbix agent implementation for Mirth Connect.
+ * Copyright (C) 2018 Cyril Boyer
+ * https://github.com/cboyer/mirth-zabbix
+ *
+ * source_transformer.js
+ * Decode base 64 data from TCP Listener (binary mode).
+ *
+ * Released under the GNU General Public License v3 (GPLv3)
+ */
+
+ msg = new java.lang.String(FileUtil.decode(msg));
+
+
+
+
+
+
+ RAW
+ RAW
+
+
+ JavaScript
+
+
+
+
+
+ JavaScript
+
+
+
+
+
+
+
+ TCP Listener
+ SOURCE
+ true
+ true
+
+
+
+ 1
+ Zabbix Server
+
+
+
+ false
+ false
+ 10000
+ false
+ 0
+ false
+ false
+ 1
+
+ false
+
+ Default Resource
+
+
+
+
+
+
+
+ 0
+ Zabbix request processing
+
+ JavaScript
+
+
+ Script
+ /**
+ * MIRTHIX - Zabbix agent implementation for Mirth Connect.
+ * Copyright (C) 2018 Cyril Boyer
+ * https://github.com/cboyer/mirth-zabbix
+ *
+ * destination_transformer.js
+ * Process requested data (discovery, item).
+ *
+ * Released under the GNU General Public License v3 (GPLv3)
+ */
+
+var agent_version = '1.0.0';
+var item_requested = msg.toString();
+//logger.info("Zabbix requested: " + item_requested); //Debug
+
+//Parse parameters in requested item
+if (item_requested.indexOf('[') != -1 && item_requested.indexOf(']') != -1 ) {
+ var connector_id = '';
+ var channel_id = '';
+ var metric = '';
+
+ //Get connector id and/or channel id
+ if (item_requested.indexOf('_') != -1) {
+
+ if (item_requested.indexOf(',') != -1) {
+ connector_id = item_requested.split('_')[1];
+ connector_id = connector_id.split(',')[0];
+ }
+ else {
+ connector_id = item_requested.split('_')[1].replace(']', '');
+ }
+
+ connector_id = parseInt(connector_id);
+ channel_id = item_requested.split('_')[0];
+ channel_id = channel_id.split('[')[1];
+ }
+ else {
+ channel_id = item_requested.split('[')[1];
+ channel_id = channel_id.replace(']', '');
+ }
+
+ //Get metric parameter
+ if (item_requested.indexOf(',') != -1) {
+ metric = item_requested.split(',')[1].replace(']', '');
+ }
+
+ item_requested = item_requested.split('[')[0];
+}
+
+
+/*
+ * Zabbix agent passive checks implementation
+ * https://www.zabbix.com/documentation/4.0/manual/appendix/items/activepassive
+ */
+
+switch (item_requested) {
+
+ case 'agent.ping':
+ msg = 1;
+ //logger.info("Agent ping: " + msg); //Debug
+ break;
+
+ case 'agent.version':
+ msg = 'Mirthix ' + agent_version;
+ //logger.info("Agent version: " + msg); //Debug
+ break;
+
+ case 'agent.hostname':
+ case 'system.uname':
+ msg = com.mirth.connect.server.controllers.ConfigurationController.getInstance().getServerName();
+ //logger.info("System name: " + msg); //Debug
+ break;
+
+ case 'mirth.deployementdate':
+ var controller = com.mirth.connect.server.controllers.ControllerFactory.getFactory().createEngineController();
+ msg = controller.getChannelStatus(channel_id).getDeployedDate().getTime().toString();
+ //logger.info("Deployment date: " + channel_id + " " + msg); //Debug
+ break;
+
+ case 'mirth.statistics':
+ switch (metric) {
+ case 'received':
+ msg = ChannelUtil.getReceivedCount(channel_id, connector_id);
+ //logger.info("Received: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'sent':
+ msg = ChannelUtil.getSentCount(channel_id, connector_id);
+ //logger.info("Sent: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'errored':
+ msg = ChannelUtil.getErrorCount(channel_id, connector_id);
+ //logger.info("Errored: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'queued':
+ msg = ChannelUtil.getQueuedCount(channel_id, connector_id);
+ //logger.info("Queued: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'filtered':
+ msg = ChannelUtil.getFilteredCount(channel_id, connector_id);
+ //logger.info("Filtered: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ default:
+ msg = "ZBX_NOTSUPPORTED\x00Metric not implemented in Mirthix: " + msg;
+ }
+ break;
+
+ case 'mirth.channel.status':
+ case 'mirth.connector.status':
+ var item_status = '';
+ if (item_requested == 'mirth.connector.status')
+ item_status = ChannelUtil.getConnectorState(channel_id, connector_id) + ""; //toString() not effective in switch
+
+ if (item_requested == 'mirth.channel.status')
+ item_status = ChannelUtil.getChannelState(channel_id) + ""; //toString() not effective in switch
+
+ switch (item_status) {
+ case 'Started':
+ msg = 0;
+ break;
+ case 'Stopped':
+ msg = 1;
+ break;
+ case 'Paused':
+ msg = 2;
+ break;
+ case 'Deploying':
+ msg = 3;
+ break;
+ case 'Pausing':
+ msg = 4;
+ break;
+ case 'Starting':
+ msg = 5;
+ break;
+ case 'Stopping':
+ msg = 6;
+ break;
+ case 'Undeploying':
+ msg = 7;
+ break;
+ case null:
+ msg = 8;
+ break;
+ default:
+ msg = 9;
+ }
+
+ //logger.info("Status: " + msg); //Debug
+ break;
+
+ /*
+ * Zabbix low level discovery implementation (JSON) for deployed channels and enabled connectors
+ * https://www.zabbix.com/documentation/4.0/manual/discovery/low_level_discovery
+ */
+
+ //Autodiscovery for deployed channels
+ case 'mirth.discovery.channel':
+ var deployed_channel_ids = ChannelUtil.getDeployedChannelIds().toArray();
+ var controller = com.mirth.connect.server.controllers.ControllerFactory.getFactory().createChannelController();
+ var zabbix_autodiscovery = {
+ "data" : []
+ };
+
+ //Loop over deployed channels
+ for (var i = 0; i < deployed_channel_ids.length; i++) {
+ var channel_id = deployed_channel_ids[i];
+ var channel_name = ChannelUtil.getDeployedChannelName(channel_id);
+ var channel = {
+ "{#ID}" : new String(channel_id),
+ "{#NAME}" : new String(channel_name)
+ }
+
+ zabbix_autodiscovery.data.push(channel);
+ }
+
+ msg = JSON.stringify(zabbix_autodiscovery);
+ break;
+
+ //Autodiscovery for enabled connectors
+ case 'mirth.discovery.connector':
+ var deployed_channel_ids = ChannelUtil.getDeployedChannelIds().toArray();
+ var controller = com.mirth.connect.server.controllers.ControllerFactory.getFactory().createChannelController();
+ var zabbix_autodiscovery = {
+ "data" : []
+ };
+
+ //Loop over deployed channels
+ for (var i = 0; i < deployed_channel_ids.length; i++) {
+ var channel_id = deployed_channel_ids[i];
+ var channel_name = ChannelUtil.getDeployedChannelName(channel_id);
+
+ //Deployed channel always has a Source connector with MetaDataId=0
+ //MetaDataId only unique in channel context, so concatenate with ChannelId
+ if (ChannelUtil.getConnectorState(channel_id, 0) != null) {
+ var source_connector = {
+ "{#ID}" : new String(channel_id + "_0"),
+ "{#NAME}" : new String(channel_name + " | Source")
+ }
+
+ zabbix_autodiscovery.data.push(source_connector);
+ }
+
+ //Loop over destination connectors
+ var channel_controller = controller.getChannelById(channel_id);
+ for (var destination in Iterator(channel_controller.getDestinationConnectors())) {
+
+ if (ChannelUtil.getConnectorState(channel_id, destination.getMetaDataId()) != null) {
+ var destination_connector = {
+ "{#ID}" : new String(channel_id + "_" + destination.getMetaDataId()),
+ "{#NAME}" : new String(channel_name+" | "+destination.getName())
+ }
+
+ zabbix_autodiscovery.data.push(destination_connector);
+ }
+ }
+ }
+
+ msg = JSON.stringify(zabbix_autodiscovery);
+ break;
+
+ default:
+ msg = "ZBX_NOTSUPPORTED\x00Key not implemented in Mirthix: " + msg;
+}
+
+
+
+
+
+
+ RAW
+ RAW
+
+
+ JavaScript
+
+
+
+
+
+ JavaScript
+
+
+
+
+
+
+ RAW
+ RAW
+
+
+ JavaScript
+
+
+
+
+
+ JavaScript
+
+
+
+
+
+
+
+ JavaScript Writer
+ DESTINATION
+ true
+ true
+
+
+ // Modify the message variable below to pre process data
+return message;
+ // This script executes once after a message has been processed
+// Responses returned from here will be stored as "Postprocessor" in the response map
+return;
+ // This script executes once when the channel is deployed
+// You only have access to the globalMap and globalChannelMap here to persist data
+return;
+ // This script executes once when the channel is undeployed
+// You only have access to the globalMap and globalChannelMap here to persist data
+return;
+
+ true
+ DISABLED
+ false
+ false
+ false
+ STARTED
+ false
+
+
+
+ None
+
+
+ 1
+ 1
+ false
+
+ Default Resource
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 067d529..9b98b45 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,54 @@
-# mirth-zabbix
-Zabbix protocol implementation for Mirth Connect integration engine.
+# MIRTHIX
+
+Zabbix protocol implementation for [Mirth Connect](https://www.nextgen.com/products-and-services/NextGen-Connect-Integration-Engine-Downloads) integration engine. Provides direct monitoring capabilities with a channel acting like Zabbix agent.
+
+## Implemented functionalities
+
+- [Low level discovery](https://www.zabbix.com/documentation/4.0/manual/discovery/low_level_discovery) for deployed channels and enabled connectors in Mirth Connect.
+- [Passive agent checks](https://www.zabbix.com/documentation/4.0/manual/appendix/items/activepassive) for data collection (polling):
+ - Agent ping (agent.ping)
+ - Host name of zabbix_agentd running (agent.hostname, system.uname)
+ - Version of zabbix_agent(d) running (agent.version)
+ - Channel deployment date (mirth.deployementdate)
+ - Connector statistics: received, errored, filtered, queued, sent (mirth.statistics)
+ - Channel status (mirth.channel.status)
+ - Connector status (mirth.connector.status)
+
+## Getting Started
+
+### Prerequisites
+
+- Mirth Connect ≥ 3.2.1
+- Zabbix ≥ 3.4.12
+- Zabbix template (Zabbix_template.xml)
+- Zabbix value map (Zabbix_valuemap.xml)
+- Mirthix channel (Mirthix_channel.xml)
+
+
+### Installing
+
+1. Import Mirthix channel `Mirthix_channel.xml` in Mirth Connect Administrator.
+2. Configuration settings for Mirthix channel:
+ - TCP Listener: don't use port 10050 if Zabbix agent is already running on the server.
+ - Message storage/pruning is disabled by default because the channel will produce a lot of messages and full your database/file system. It should be activated only for debug purposes.
+3. Import Zabbix template `Zabbix_template.xml` and value map `Zabbix_valuemap.xml` in Zabbix console.
+4. Create host (or use an existing one) in Zabbix console with Mirth server IP address as Agent interface (with TCP Listener port) and add templates `Template App Mirth` and `Template App Zabbix Agent` (default agent availability template provided by Zabbix).
+
+
+### Trigger adjustment
+
+Trigger adjustment is done with template [macros](https://www.zabbix.com/documentation/3.4/manual/config/macros/usermacros) and [macro contexts](https://www.zabbix.com/documentation/3.4/manual/config/macros/usermacros#user_macro_context): Templates > Template App Mirth > Macro
+
+Example:
+To trigger "Queue on Zabbix Monitoring | Zabbix Server" problem when queued > 20, add macro `{$QUEUED:"Zabbix Monitoring | Zabbix Server"}` with value `20`. If no context is set on a macro, default macro `{$QUEUED}` will be used.
+
+To disable unwanted item/trigger creation, you have to disable item/trigger prototype in template discovery rules (Templates > Template App Mirth > Discovery rules).
+
+## What's next ?
+
+- IP source filtering for security
+- [UserParameter](https://www.zabbix.com/documentation/4.0/manual/config/items/userparameters) functionality to trigger custom actions in Mirth.
+
+## License
+
+This project is licensed under the GNU General Public License v3 (GPLv3) - see the [LICENSE](LICENSE) file for details.
diff --git a/Zabbix/Zabbix_template.xml b/Zabbix/Zabbix_template.xml
new file mode 100644
index 0000000..a6055c3
--- /dev/null
+++ b/Zabbix/Zabbix_template.xml
@@ -0,0 +1,608 @@
+
+
+ 3.4
+ 2018-11-22T23:46:46Z
+
+
+ Templates
+
+
+
+
+ Template App Mirth
+ Template App Mirth
+ Mirth Connect monitoring template.
+https://github.com/cboyer/mirth-zabbix
+
+
+ Templates
+
+
+
+
+ Mirth
+
+
+
+
+
+ Channel discovery
+ 0
+
+
+ mirth.discovery.channel
+ 1h
+ 0
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+
+ 1w
+ Discovery for Mirth channels.
+
+
+ {#NAME}: Status
+ 0
+
+
+ mirth.channel.status[{#ID}]
+ 1m
+ 1w
+ 365d
+ 0
+ 3
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+ Mirth
+
+
+
+ Mirth channel status
+
+
+
+
+
+
+
+
+ {#NAME}: Deployment date
+ 0
+
+
+ mirth.deployementdate[{#ID}]
+ 10m
+ 1w
+ 0
+ 0
+ 4
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+ Mirth
+
+
+
+
+
+
+
+
+
+
+
+
+ {Template App Mirth:mirth.deployementdate[{#ID}].diff()} = 1
+ 0
+
+ New deployment: {#NAME}
+ 0
+
+
+ 0
+ 1
+
+ 0
+ 0
+
+
+
+
+ {Template App Mirth:mirth.channel.status[{#ID}].last()} <> 0
+ 0
+
+ Status {ITEM.LASTVALUE} on channel {#NAME}
+ 0
+
+
+ 0
+ 4
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+ Connector discovery
+ 0
+
+
+ mirth.discovery.connector
+ 1h
+ 0
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+
+ 1w
+ Discovery for Mirth connectors.
+
+
+ {#NAME}: Status
+ 0
+
+
+ mirth.connector.status[{#ID}]
+ 1m
+ 1w
+ 365d
+ 0
+ 3
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+ Started = 0
+Stopped = 1
+Paused = 2
+Deploying = 3
+Pausing = 4
+Starting = 5
+Stopping = 6
+Undeploying = 7
+Unknown = 8
+ 0
+
+
+ Mirth
+
+
+
+ Mirth channel status
+
+
+
+
+
+
+
+
+ {#NAME}: Errors
+ 0
+
+
+ mirth.statistics[{#ID},errored]
+ 1m
+ 1w
+ 365d
+ 0
+ 3
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+ Mirth
+
+
+
+
+
+
+
+
+
+
+ {#NAME}: Filtered
+ 0
+
+
+ mirth.statistics[{#ID},filtered]
+ 1m
+ 1w
+ 365d
+ 0
+ 3
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+ Mirth
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+
+ {#NAME}: Queued
+ 0
+
+
+ mirth.statistics[{#ID},queued]
+ 1m
+ 1w
+ 365d
+ 0
+ 3
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+ Mirth
+
+
+
+
+
+
+
+
+
+
+ {#NAME}: Received
+ 0
+
+
+ mirth.statistics[{#ID},received]
+ 1m
+ 1w
+ 365d
+ 0
+ 3
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+ Mirth
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+
+ {#NAME}: Sent
+ 0
+
+
+ mirth.statistics[{#ID},sent]
+ 1m
+ 1w
+ 365d
+ 0
+ 3
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+ Mirth
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+
+
+
+ {Template App Mirth:mirth.statistics[{#ID},errored].last()} <> 0
+ 0
+
+ Errors on {#NAME}
+ 0
+
+
+ 0
+ 4
+
+ 0
+ 0
+
+
+
+
+ {Template App Mirth:mirth.statistics[{#ID},queued].last()} > {$QUEUED: "{#NAME}" }
+ 0
+
+ Queue on {#NAME}
+ 0
+
+
+ 0
+ 3
+
+ 0
+ 0
+
+
+
+
+ {Template App Mirth:mirth.connector.status[{#ID}].last()} <> 0
+ 0
+
+ Status {ITEM.LASTVALUE} on connector {#NAME}
+ 0
+
+
+ 0
+ 4
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+ {$QUEUED}
+ 10
+
+
+
+
+
+
+
+
+ Mirth channel status
+
+
+ 0
+ Started
+
+
+ 1
+ Stopped
+
+
+ 2
+ Paused
+
+
+ 3
+ Deploying
+
+
+ 4
+ Pausing
+
+
+ 5
+ Starting
+
+
+ 6
+ Stopping
+
+
+ 7
+ Undeploying
+
+
+ 8
+ Disabled
+
+
+ 9
+ Unknown
+
+
+
+
+
diff --git a/Zabbix/Zabbix_valuemap.xml b/Zabbix/Zabbix_valuemap.xml
new file mode 100644
index 0000000..7ae93c5
--- /dev/null
+++ b/Zabbix/Zabbix_valuemap.xml
@@ -0,0 +1,52 @@
+
+
+ 3.4
+ 2018-11-18T22:56:54Z
+
+
+ Mirth channel status
+
+
+ 0
+ Started
+
+
+ 1
+ Stopped
+
+
+ 2
+ Paused
+
+
+ 3
+ Deploying
+
+
+ 4
+ Pausing
+
+
+ 5
+ Starting
+
+
+ 6
+ Stopping
+
+
+ 7
+ Undeploying
+
+
+ 8
+ Disabled
+
+
+ 9
+ Unknown
+
+
+
+
+
diff --git a/src/destination.js b/src/destination.js
new file mode 100644
index 0000000..363d280
--- /dev/null
+++ b/src/destination.js
@@ -0,0 +1,38 @@
+/**
+ * MIRTHIX - Zabbix agent implementation for Mirth Connect.
+ * Copyright (C) 2018 Cyril Boyer
+ * https://github.com/cboyer/mirth-zabbix
+ *
+ * destination.js
+ * Build response for Zabbix server
+ *
+ * Released under the GNU General Public License v3 (GPLv3)
+ */
+
+/*
+ * Zabbix Protocol
+ * https://www.zabbix.com/documentation/4.0/manual/appendix/protocols/header_datalen
+ */
+
+var header = "ZBXD\x01";
+var data = connectorMessage.getEncodedData();
+
+//logger.info("Sent to Zabbix: "+ data); //Debug
+
+var header_bytes = new java.lang.String(header).getBytes('UTF-8');
+var data_bytes = new java.lang.String(data).getBytes('UTF-8');
+
+if (data_bytes.length + 1 >= 134217728) { // +1 for final 0x0A (LF)
+ throw('Message exceeds the maximum size 134217728 bytes.');
+}
+
+var length_bytes = Packages.java.nio.ByteBuffer.allocate(8);
+length_bytes.order(java.nio.ByteOrder.LITTLE_ENDIAN);
+length_bytes.putInt(data_bytes.length + 1); // +1 for final 0x0A (LF)
+
+var zabbix_message_bytes = Packages.java.nio.ByteBuffer.allocate(header_bytes.length + length_bytes.array().length + data_bytes.length);
+zabbix_message_bytes.put(header_bytes);
+zabbix_message_bytes.put(length_bytes.array());
+zabbix_message_bytes.put(data_bytes);
+
+return Packages.org.apache.commons.codec.binary.Base64.encodeBase64String(zabbix_message_bytes.array());
diff --git a/src/destination_transformer.js b/src/destination_transformer.js
new file mode 100644
index 0000000..3d4e7fd
--- /dev/null
+++ b/src/destination_transformer.js
@@ -0,0 +1,223 @@
+/**
+ * MIRTHIX - Zabbix agent implementation for Mirth Connect.
+ * Copyright (C) 2018 Cyril Boyer
+ * https://github.com/cboyer/mirth-zabbix
+ *
+ * destination_transformer.js
+ * Process requested data (discovery, item).
+ *
+ * Released under the GNU General Public License v3 (GPLv3)
+ */
+
+var agent_version = '1.0.0';
+var item_requested = msg.toString();
+//logger.info("Zabbix requested: " + item_requested); //Debug
+
+//Parse parameters in requested item
+if (item_requested.indexOf('[') != -1 && item_requested.indexOf(']') != -1 ) {
+ var connector_id = '';
+ var channel_id = '';
+ var metric = '';
+
+ //Get connector id and/or channel id
+ if (item_requested.indexOf('_') != -1) {
+
+ if (item_requested.indexOf(',') != -1) {
+ connector_id = item_requested.split('_')[1];
+ connector_id = connector_id.split(',')[0];
+ }
+ else {
+ connector_id = item_requested.split('_')[1].replace(']', '');
+ }
+
+ connector_id = parseInt(connector_id);
+ channel_id = item_requested.split('_')[0];
+ channel_id = channel_id.split('[')[1];
+ }
+ else {
+ channel_id = item_requested.split('[')[1];
+ channel_id = channel_id.replace(']', '');
+ }
+
+ //Get metric parameter
+ if (item_requested.indexOf(',') != -1) {
+ metric = item_requested.split(',')[1].replace(']', '');
+ }
+
+ item_requested = item_requested.split('[')[0];
+}
+
+
+/*
+ * Zabbix agent passive checks implementation
+ * https://www.zabbix.com/documentation/4.0/manual/appendix/items/activepassive
+ */
+
+switch (item_requested) {
+
+ case 'agent.ping':
+ msg = 1;
+ //logger.info("Agent ping: " + msg); //Debug
+ break;
+
+ case 'agent.version':
+ msg = 'Mirthix ' + agent_version;
+ //logger.info("Agent version: " + msg); //Debug
+ break;
+
+ case 'agent.hostname':
+ case 'system.uname':
+ msg = com.mirth.connect.server.controllers.ConfigurationController.getInstance().getServerName();
+ //logger.info("System name: " + msg); //Debug
+ break;
+
+ case 'mirth.deployementdate':
+ var controller = com.mirth.connect.server.controllers.ControllerFactory.getFactory().createEngineController();
+ msg = controller.getChannelStatus(channel_id).getDeployedDate().getTime().toString();
+ //logger.info("Deployment date: " + channel_id + " " + msg); //Debug
+ break;
+
+ case 'mirth.statistics':
+ switch (metric) {
+ case 'received':
+ msg = ChannelUtil.getReceivedCount(channel_id, connector_id);
+ //logger.info("Received: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'sent':
+ msg = ChannelUtil.getSentCount(channel_id, connector_id);
+ //logger.info("Sent: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'errored':
+ msg = ChannelUtil.getErrorCount(channel_id, connector_id);
+ //logger.info("Errored: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'queued':
+ msg = ChannelUtil.getQueuedCount(channel_id, connector_id);
+ //logger.info("Queued: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ case 'filtered':
+ msg = ChannelUtil.getFilteredCount(channel_id, connector_id);
+ //logger.info("Filtered: " + channel_id + " " + connector_id + " : " + msg); //Debug
+ break;
+ default:
+ msg = "ZBX_NOTSUPPORTED\x00Metric not implemented in Mirthix: " + msg;
+ }
+ break;
+
+ case 'mirth.channel.status':
+ case 'mirth.connector.status':
+ var item_status = '';
+ if (item_requested == 'mirth.connector.status')
+ item_status = ChannelUtil.getConnectorState(channel_id, connector_id) + ""; //toString() not effective in switch
+
+ if (item_requested == 'mirth.channel.status')
+ item_status = ChannelUtil.getChannelState(channel_id) + ""; //toString() not effective in switch
+
+ switch (item_status) {
+ case 'Started':
+ msg = 0;
+ break;
+ case 'Stopped':
+ msg = 1;
+ break;
+ case 'Paused':
+ msg = 2;
+ break;
+ case 'Deploying':
+ msg = 3;
+ break;
+ case 'Pausing':
+ msg = 4;
+ break;
+ case 'Starting':
+ msg = 5;
+ break;
+ case 'Stopping':
+ msg = 6;
+ break;
+ case 'Undeploying':
+ msg = 7;
+ break;
+ case null:
+ msg = 8;
+ break;
+ default:
+ msg = 9;
+ }
+
+ //logger.info("Status: " + msg); //Debug
+ break;
+
+ /*
+ * Zabbix low level discovery implementation (JSON) for deployed channels and enabled connectors
+ * https://www.zabbix.com/documentation/4.0/manual/discovery/low_level_discovery
+ */
+
+ //Autodiscovery for deployed channels
+ case 'mirth.discovery.channel':
+ var deployed_channel_ids = ChannelUtil.getDeployedChannelIds().toArray();
+ var controller = com.mirth.connect.server.controllers.ControllerFactory.getFactory().createChannelController();
+ var zabbix_autodiscovery = {
+ "data" : []
+ };
+
+ //Loop over deployed channels
+ for (var i = 0; i < deployed_channel_ids.length; i++) {
+ var channel_id = deployed_channel_ids[i];
+ var channel_name = ChannelUtil.getDeployedChannelName(channel_id);
+ var channel = {
+ "{#ID}" : new String(channel_id),
+ "{#NAME}" : new String(channel_name)
+ }
+
+ zabbix_autodiscovery.data.push(channel);
+ }
+
+ msg = JSON.stringify(zabbix_autodiscovery);
+ break;
+
+ //Autodiscovery for enabled connectors
+ case 'mirth.discovery.connector':
+ var deployed_channel_ids = ChannelUtil.getDeployedChannelIds().toArray();
+ var controller = com.mirth.connect.server.controllers.ControllerFactory.getFactory().createChannelController();
+ var zabbix_autodiscovery = {
+ "data" : []
+ };
+
+ //Loop over deployed channels
+ for (var i = 0; i < deployed_channel_ids.length; i++) {
+ var channel_id = deployed_channel_ids[i];
+ var channel_name = ChannelUtil.getDeployedChannelName(channel_id);
+
+ //Deployed channel always has a Source connector with MetaDataId=0
+ //MetaDataId only unique in channel context, so concatenate with ChannelId
+ if (ChannelUtil.getConnectorState(channel_id, 0) != null) {
+ var source_connector = {
+ "{#ID}" : new String(channel_id + "_0"),
+ "{#NAME}" : new String(channel_name + " | Source")
+ }
+
+ zabbix_autodiscovery.data.push(source_connector);
+ }
+
+ //Loop over destination connectors
+ var channel_controller = controller.getChannelById(channel_id);
+ for (var destination in Iterator(channel_controller.getDestinationConnectors())) {
+
+ if (ChannelUtil.getConnectorState(channel_id, destination.getMetaDataId()) != null) {
+ var destination_connector = {
+ "{#ID}" : new String(channel_id + "_" + destination.getMetaDataId()),
+ "{#NAME}" : new String(channel_name+" | "+destination.getName())
+ }
+
+ zabbix_autodiscovery.data.push(destination_connector);
+ }
+ }
+ }
+
+ msg = JSON.stringify(zabbix_autodiscovery);
+ break;
+
+ default:
+ msg = "ZBX_NOTSUPPORTED\x00Key not implemented in Mirthix: " + msg;
+}
diff --git a/src/source_transformer.js b/src/source_transformer.js
new file mode 100644
index 0000000..a89faa1
--- /dev/null
+++ b/src/source_transformer.js
@@ -0,0 +1,12 @@
+/**
+ * MIRTHIX - Zabbix agent implementation for Mirth Connect.
+ * Copyright (C) 2018 Cyril Boyer
+ * https://github.com/cboyer/mirth-zabbix
+ *
+ * source_transformer.js
+ * Decode base 64 data from TCP Listener (binary mode).
+ *
+ * Released under the GNU General Public License v3 (GPLv3)
+ */
+
+ msg = new java.lang.String(FileUtil.decode(msg));