diff --git a/db/knex_migrations/2024-03-25-0000-json-data-operators.js b/db/knex_migrations/2024-03-25-0000-json-data-operators.js new file mode 100644 index 00000000..4cf0f808 --- /dev/null +++ b/db/knex_migrations/2024-03-25-0000-json-data-operators.js @@ -0,0 +1,22 @@ +exports.up = function (knex) { + return knex.schema + .alterTable("monitor", (table) => { + table.string("json_path_operator"); + }) + .then(() => + knex("monitor") + .where({ + type: "json-query" + }) + .update({ + "json_path_operator": "==" + }) + ); +}; + +exports.down = function (knex) { + return knex.schema + .alterTable("monitor", (table) => { + table.dropColumn("json_path_operator"); + }); +}; diff --git a/db/knex_migrations/README.md b/db/knex_migrations/README.md index d2b8470b..9d34dee8 100644 --- a/db/knex_migrations/README.md +++ b/db/knex_migrations/README.md @@ -38,12 +38,12 @@ exports.up = function(knex) { table.increments('id'); table.decimal('price').notNullable(); table.string('name', 1000).notNullable(); - }).then(() => { + }).then(() => knex("products").insert([ { price: 10, name: "Apple" }, { price: 20, name: "Orange" }, ]); - }); + ); }; exports.down = function(knex) { diff --git a/server/model/monitor.js b/server/model/monitor.js index 1667b83a..f74f73ed 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -153,6 +153,7 @@ class Monitor extends BeanModel { gamedigGivenPortOnly: this.getGameDigGivenPortOnly(), httpBodyEncoding: this.httpBodyEncoding, jsonPath: this.jsonPath, + jsonPathOperator: this.jsonPathOperator, expectedValue: this.expectedValue, kafkaProducerTopic: this.kafkaProducerTopic, kafkaProducerBrokers: JSON.parse(this.kafkaProducerBrokers), @@ -607,7 +608,7 @@ class Monitor extends BeanModel { let result = await expression.evaluate(data); - if (result.toString() === this.expectedValue) { + if (this.isJsonPathMatching(result)) { bean.msg += ", expected value is found"; bean.status = UP; } else { @@ -1615,6 +1616,25 @@ class Monitor extends BeanModel { return oAuthAccessToken; } + /** + * Evaluates the provided value with the expected value based on the defined operator. Fallback is the equals operator + * @param {any} value + * @returns {boolean} Is the JsonPath matching the expected value with the defined operator? + */ + isJsonPathMatching(value) { + const operators = { + "==": (value) => value == this.expectedValue, + "!=": (value) => value != this.expectedValue, + "<": (value) => value < this.expectedValue, + "<=": (value) => value <= this.expectedValue, + ">": (value) => value > this.expectedValue, + ">=": (value) => value >= this.expectedValue, + }; + + const operator = operators[this.jsonPathOperator] ?? operators["=="]; + + return operator(value?.toString()); + } } module.exports = Monitor; diff --git a/server/monitor-types/mqtt.js b/server/monitor-types/mqtt.js index 9b2db43d..fd9238d4 100644 --- a/server/monitor-types/mqtt.js +++ b/server/monitor-types/mqtt.js @@ -41,7 +41,7 @@ class MqttMonitorType extends MonitorType { let result = await expression.evaluate(parsedMessage); - if (result?.toString() === monitor.expectedValue) { + if (monitor.isJsonPathMatching(result)) { heartbeat.msg = "Message received, expected value is found"; heartbeat.status = UP; } else { diff --git a/server/server.js b/server/server.js index 753f88b8..60f9359e 100644 --- a/server/server.js +++ b/server/server.js @@ -818,8 +818,9 @@ let needSetup = false; bean.radiusCallingStationId = monitor.radiusCallingStationId; bean.radiusSecret = monitor.radiusSecret; bean.httpBodyEncoding = monitor.httpBodyEncoding; - bean.expectedValue = monitor.expectedValue; bean.jsonPath = monitor.jsonPath; + bean.jsonPathOperator = monitor.jsonPathOperator; + bean.expectedValue = monitor.expectedValue; bean.kafkaProducerTopic = monitor.kafkaProducerTopic; bean.kafkaProducerBrokers = JSON.stringify(monitor.kafkaProducerBrokers); bean.kafkaProducerAllowAutoTopicCreation = monitor.kafkaProducerAllowAutoTopicCreation; diff --git a/src/lang/de-DE.json b/src/lang/de-DE.json index 0d233636..04bc9ad4 100644 --- a/src/lang/de-DE.json +++ b/src/lang/de-DE.json @@ -817,6 +817,13 @@ "filterActivePaused": "Pausiert", "Expected Value": "Erwarteter Wert", "Json Query": "Json-Abfrage", + "Json Query Operator": "Json-Abfrage Operator", + "Json Query Equals": "Wert muss gleich sein", + "Json Query Not Equals": "Wert muss unterschiedlich sein", + "Json Query Less Than": "Wert muss kleiner sein", + "Json Query Less Than Or Equals": "Wert muss kleiner oder gleich sein", + "Json Query Greater Than": "Wert muss größer sein", + "Json Query Greater Than Or Equals": "Wert muss größer oder gleich sein", "jsonQueryDescription": "Führe eine JSON-Abfrage gegen die Antwort durch und prüfe den erwarteten Wert (der Rückgabewert wird zum Vergleich in eine Zeichenkette umgewandelt). Auf {0} findest du die Dokumentation zur Abfragesprache. {1} kannst du Abfragen üben.", "tailscalePingWarning": "Um den Tailscale Ping Monitor nutzen zu können, musst du Uptime Kuma ohne Docker installieren und den Tailscale Client auf dem Server installieren.", "Server URL should not contain the nfty topic": "Die Server-URL sollte das nfty-Thema nicht enthalten", diff --git a/src/lang/en.json b/src/lang/en.json index 11190a08..d3afb30c 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -60,6 +60,13 @@ "Invert Keyword": "Invert Keyword", "Expected Value": "Expected Value", "Json Query": "Json Query", + "Json Query Operator": "Json Query Operator", + "Json Query Equals": "value must be equal", + "Json Query Not Equals": "value must not be equal", + "Json Query Less Than": "value must be less", + "Json Query Less Than Or Equals": "value must be less or equal", + "Json Query Greater Than": "value must be greater", + "Json Query Greater Than Or Equals": "value must be greater or equal", "Friendly Name": "Friendly Name", "URL": "URL", "Hostname": "Hostname", diff --git a/src/pages/Details.vue b/src/pages/Details.vue index 8582b82c..92c6d85e 100644 --- a/src/pages/Details.vue +++ b/src/pages/Details.vue @@ -29,6 +29,8 @@
{{ $t("Json Query") }}: {{ monitor.jsonPath }}
+ {{ $t("Json Query Operator") }}: {{ monitor.jsonPathOperator }} +
{{ $t("Expected Value") }}: {{ monitor.expectedValue }} [{{ monitor.dns_resolve_type }}] {{ monitor.hostname }} diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index e9f3ac83..e4ab629a 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -179,6 +179,16 @@
+ + + @@ -375,6 +385,16 @@
+ + +