From a0e07e99572e17ea1d2c2d2e31aa0e45577ceacc Mon Sep 17 00:00:00 2001 From: mzp0514 Date: Mon, 26 Apr 2021 10:29:08 +0800 Subject: [PATCH] update --- docs/UserGuide/Advanced-Features/Alerting.md | 113 ++++++------- .../UserGuide/Advanced-Features/Alerting.md | 113 ++++++------- ...iggerExample.java => AlertingExample.java} | 16 +- .../AlertManagerConfiguration.java | 28 --- .../sink/alertmanager/AlertManagerEvent.java | 59 ++++++- .../alertmanager/AlertManagerHandler.java | 70 ++++---- .../db/sink/ts/TimeSeriesConfiguration.java | 51 ------ .../iotdb/db/sink/ts/TimeSeriesEvent.java | 41 ----- .../iotdb/db/sink/ts/TimeSeriesHandler.java | 72 -------- .../iotdb/db/sink/AlertManagerTest.java | 160 ++++++++++++++++++ 10 files changed, 365 insertions(+), 358 deletions(-) rename example/trigger/src/main/java/org/apache/iotdb/trigger/{AlertingTriggerExample.java => AlertingExample.java} (88%) delete mode 100644 server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesConfiguration.java delete mode 100644 server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesEvent.java delete mode 100644 server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesHandler.java diff --git a/docs/UserGuide/Advanced-Features/Alerting.md b/docs/UserGuide/Advanced-Features/Alerting.md index 6ff4e283b5ee9..c970dae96fb00 100644 --- a/docs/UserGuide/Advanced-Features/Alerting.md +++ b/docs/UserGuide/Advanced-Features/Alerting.md @@ -250,7 +250,7 @@ or `/alertmanager/api/v2/alerts`. The user defines a trigger by creating a Java class and writing the logic in the hook. Please refer to [Triggers](Triggers.md) for the specific configuration process and the usage method of `AlertManagerSink` related tools provided by the Sink module. -The following example creates the `org.apache.iotdb.trigger.AlertingTriggerExample` class, +The following example creates the `org.apache.iotdb.trigger.AlertingExample` class, Its alertManagerHandler member variables can send alerts to the AlertManager instance at the address of `http://127.0.0.1:9093/`. @@ -264,76 +264,73 @@ package org.apache.iotdb.trigger; package importing is omitted here */ -public class AlertingTriggerExample implements Trigger { +public class AlertingExample implements Trigger { - AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); + private final AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); - String alertname; + private String alertname; - HashMap labels = new HashMap<>(); + private final HashMap labels = new HashMap<>(); - HashMap annotations = new HashMap<>(); + private final HashMap annotations = new HashMap<>(); - @Override - public void onCreate(TriggerAttributes attributes) throws Exception { + @Override + public void onCreate(TriggerAttributes attributes) throws Exception { - AlertManagerConfiguration alertManagerConfiguration = - new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts"); + AlertManagerConfiguration alertManagerConfiguration = + new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts"); - alertManagerHandler.open(alertManagerConfiguration); + alertManagerHandler.open(alertManagerConfiguration); - alertname = "alert_test"; + alertname = "alert_test"; - labels.put("series", "root.ln.wf01.wt01.temperature"); - labels.put("value", ""); - labels.put("severity", ""); + labels.put("series", "root.ln.wf01.wt01.temperature"); + labels.put("value", ""); + labels.put("severity", ""); - annotations.put("summary", "high temperature"); - annotations.put("description", "{{.alertname}}: {{.series}} is {{.value}}"); - } - - @Override - public Double fire(long timestamp, Double value) throws Exception { - if (value > 100.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "critical"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); - - } else if (value > 50.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "warning"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); + annotations.put("summary", "high temperature"); + annotations.put("description", "{{.alertname}}: {{.series}} is {{.value}}"); + } - } + @Override + public void onDrop() throws IOException { + alertManagerHandler.close(); + } - return value; + @Override + public Double fire(long timestamp, Double value) throws Exception { + if (value > 100.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "critical"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); + } else if (value > 50.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "warning"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); } - @Override - public double[] fire(long[] timestamps, double[] values) throws Exception { - for (double value : values) { - if (value > 100.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "critical"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); - - } else if (value > 50.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "warning"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); - - } - } - return values; + return value; + } + + @Override + public double[] fire(long[] timestamps, double[] values) throws Exception { + for (double value : values) { + if (value > 100.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "critical"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); + } else if (value > 50.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "warning"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); + } } + return values; + } } ```` @@ -343,13 +340,13 @@ The following SQL statement registered the trigger named `root-ln-wf01-wt01-alert` on the `root.ln.wf01.wt01.temperature` time series, whose operation logic is defined -by `org.apache.iotdb.trigger.AlertingTriggerExample` java class. +by `org.apache.iotdb.trigger.AlertingExample` java class. ``` sql CREATE TRIGGER root-ln-wf01-wt01-alert AFTER INSERT ON root.ln.wf01.wt01.temperature - AS "org.apache.iotdb.trigger.AlertingTriggerExample" + AS "org.apache.iotdb.trigger.AlertingExample" ``` diff --git a/docs/zh/UserGuide/Advanced-Features/Alerting.md b/docs/zh/UserGuide/Advanced-Features/Alerting.md index 356645f6d3983..d19041b3b2485 100644 --- a/docs/zh/UserGuide/Advanced-Features/Alerting.md +++ b/docs/zh/UserGuide/Advanced-Features/Alerting.md @@ -250,7 +250,7 @@ inhibit_rules: 用户通过自行创建 Java 类、编写钩子中的逻辑来定义一个触发器。 具体配置流程以及 Sink 模块提供的 `AlertManagerSink` 相关工具类的使用方法参见 [Triggers](Triggers.md)。 -下面的示例创建了 `org.apache.iotdb.trigger.AlertingTriggerExample` 类, +下面的示例创建了 `org.apache.iotdb.trigger.AlertingExample` 类, 其 `alertManagerHandler` 成员变量可发送告警至地址为 `http://127.0.0.1:9093/` 的 AlertManager 实例。 @@ -264,76 +264,73 @@ package org.apache.iotdb.trigger; 此处省略包的引入 */ -public class AlertingTriggerExample implements Trigger { +public class AlertingExample implements Trigger { - AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); + private final AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); - String alertname; + private String alertname; - HashMap labels = new HashMap<>(); + private final HashMap labels = new HashMap<>(); - HashMap annotations = new HashMap<>(); + private final HashMap annotations = new HashMap<>(); - @Override - public void onCreate(TriggerAttributes attributes) throws Exception { + @Override + public void onCreate(TriggerAttributes attributes) throws Exception { - AlertManagerConfiguration alertManagerConfiguration = - new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts"); + AlertManagerConfiguration alertManagerConfiguration = + new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts"); - alertManagerHandler.open(alertManagerConfiguration); + alertManagerHandler.open(alertManagerConfiguration); - alertname = "alert_test"; + alertname = "alert_test"; - labels.put("series", "root.ln.wf01.wt01.temperature"); - labels.put("value", ""); - labels.put("severity", ""); + labels.put("series", "root.ln.wf01.wt01.temperature"); + labels.put("value", ""); + labels.put("severity", ""); - annotations.put("summary", "high temperature"); - annotations.put("description", "{{.alertname}}: {{.series}} is {{.value}}"); - } - - @Override - public Double fire(long timestamp, Double value) throws Exception { - if (value > 100.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "critical"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); - - } else if (value > 50.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "warning"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); + annotations.put("summary", "high temperature"); + annotations.put("description", "{{.alertname}}: {{.series}} is {{.value}}"); + } - } + @Override + public void onDrop() throws IOException { + alertManagerHandler.close(); + } - return value; + @Override + public Double fire(long timestamp, Double value) throws Exception { + if (value > 100.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "critical"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); + } else if (value > 50.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "warning"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); } - @Override - public double[] fire(long[] timestamps, double[] values) throws Exception { - for (double value : values) { - if (value > 100.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "critical"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); - - } else if (value > 50.0) { - - labels.put("value", String.valueOf(value)); - labels.put("severity", "warning"); - AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); - alertManagerHandler.onEvent(alertManagerEvent); - - } - } - return values; + return value; + } + + @Override + public double[] fire(long[] timestamps, double[] values) throws Exception { + for (double value : values) { + if (value > 100.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "critical"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); + } else if (value > 50.0) { + labels.put("value", String.valueOf(value)); + labels.put("severity", "warning"); + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertname, labels, annotations); + alertManagerHandler.onEvent(alertManagerEvent); + } } + return values; + } } ```` @@ -341,14 +338,14 @@ public class AlertingTriggerExample implements Trigger { 如下的 sql 语句在 `root.ln.wf01.wt01.temperature` 时间序列上注册了名为 `root-ln-wf01-wt01-alert`、 -运行逻辑由 `org.apache.iotdb.trigger.AlertingTriggerExample` +运行逻辑由 `org.apache.iotdb.trigger.AlertingExample` 类定义的触发器。 ``` sql CREATE TRIGGER root-ln-wf01-wt01-alert AFTER INSERT ON root.ln.wf01.wt01.temperature - AS "org.apache.iotdb.trigger.AlertingTriggerExample" + AS "org.apache.iotdb.trigger.AlertingExample" ``` ## 写入数据 diff --git a/example/trigger/src/main/java/org/apache/iotdb/trigger/AlertingTriggerExample.java b/example/trigger/src/main/java/org/apache/iotdb/trigger/AlertingExample.java similarity index 88% rename from example/trigger/src/main/java/org/apache/iotdb/trigger/AlertingTriggerExample.java rename to example/trigger/src/main/java/org/apache/iotdb/trigger/AlertingExample.java index 1515fae33dbdb..825fb5be2d3c3 100644 --- a/example/trigger/src/main/java/org/apache/iotdb/trigger/AlertingTriggerExample.java +++ b/example/trigger/src/main/java/org/apache/iotdb/trigger/AlertingExample.java @@ -25,17 +25,18 @@ import org.apache.iotdb.db.sink.alertmanager.AlertManagerEvent; import org.apache.iotdb.db.sink.alertmanager.AlertManagerHandler; +import java.io.IOException; import java.util.HashMap; -public class AlertingTriggerExample implements Trigger { +public class AlertingExample implements Trigger { - AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); + private final AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); - String alertname; + private String alertname; - HashMap labels = new HashMap<>(); + private final HashMap labels = new HashMap<>(); - HashMap annotations = new HashMap<>(); + private final HashMap annotations = new HashMap<>(); @Override public void onCreate(TriggerAttributes attributes) throws Exception { @@ -55,6 +56,11 @@ public void onCreate(TriggerAttributes attributes) throws Exception { annotations.put("description", "{{.alertname}}: {{.series}} is {{.value}}"); } + @Override + public void onDrop() throws IOException { + alertManagerHandler.close(); + } + @Override public Double fire(long timestamp, Double value) throws Exception { if (value > 100.0) { diff --git a/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerConfiguration.java b/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerConfiguration.java index 00dd9eec7dabe..3ed4c37038aba 100644 --- a/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerConfiguration.java +++ b/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerConfiguration.java @@ -21,43 +21,15 @@ import org.apache.iotdb.db.sink.api.Configuration; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; - public class AlertManagerConfiguration implements Configuration { private final String endpoint; public AlertManagerConfiguration(String endpoint) { - this.endpoint = endpoint; } public String getEndpoint() { return endpoint; } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof org.apache.iotdb.db.sink.alertmanager.AlertManagerConfiguration)) { - return false; - } - - org.apache.iotdb.db.sink.alertmanager.AlertManagerConfiguration that = - (org.apache.iotdb.db.sink.alertmanager.AlertManagerConfiguration) o; - - return new EqualsBuilder() - .appendSuper(super.equals(o)) - .append(endpoint, that.endpoint) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37).appendSuper(super.hashCode()).append(endpoint).toHashCode(); - } } diff --git a/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerEvent.java b/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerEvent.java index ea63898aa1a84..d26de46e349ee 100644 --- a/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerEvent.java +++ b/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerEvent.java @@ -20,7 +20,12 @@ package org.apache.iotdb.db.sink.alertmanager; import org.apache.iotdb.db.sink.api.Event; +import org.apache.iotdb.db.sink.exception.SinkException; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; @@ -28,27 +33,43 @@ public class AlertManagerEvent implements Event { + private static final String PARAMETER_NULL_ERROR_STR = "parameter null error"; + + private static final String ALERTNAME_KEY = "alertname"; + private final Map labels; private final Map annotations; - public AlertManagerEvent(String alertname) { + private static final Pattern pattern = Pattern.compile("\\{\\{\\.\\w+}}"); + + public AlertManagerEvent(String alertname) throws SinkException { + if (alertname == null) { + throw new SinkException(PARAMETER_NULL_ERROR_STR); + } this.labels = new HashMap<>(); - this.labels.put("alertname", alertname); + this.labels.put(ALERTNAME_KEY, alertname); this.annotations = null; } - public AlertManagerEvent(String alertname, Map extraLabels) { + public AlertManagerEvent(String alertname, Map extraLabels) throws SinkException { + if (alertname == null || extraLabels == null) { + throw new SinkException(PARAMETER_NULL_ERROR_STR); + } this.labels = extraLabels; - this.labels.put("alertname", alertname); + this.labels.put(ALERTNAME_KEY, alertname); this.annotations = null; } public AlertManagerEvent( - String alertname, Map extraLabels, Map annotations) { + String alertname, Map extraLabels, Map annotations) + throws SinkException { + if (alertname == null || extraLabels == null || annotations == null) { + throw new SinkException(PARAMETER_NULL_ERROR_STR); + } this.labels = extraLabels; - this.labels.put("alertname", alertname); + this.labels.put(ALERTNAME_KEY, alertname); this.annotations = new HashMap<>(); for (Map.Entry entry : annotations.entrySet()) { @@ -64,10 +85,32 @@ public Map getLabels() { return labels; } + public String toJsonString() { + Gson gson = new Gson(); + Type gsonType = new TypeToken() {}.getType(); + + StringBuilder sb = new StringBuilder(); + sb.append("{\"labels\":"); + + String labelsString = gson.toJson(this.labels, gsonType); + sb.append(labelsString); + + if (this.annotations != null) { + String annotationsString = gson.toJson(this.annotations, gsonType); + sb.append(","); + sb.append("\"annotations\":"); + sb.append(annotationsString); + } + sb.append("}"); + return sb.toString(); + } + private static String fillTemplate(Map map, String template) { - if (template == null || map == null) return null; + if (template == null || map == null) { + return null; + } StringBuffer sb = new StringBuffer(); - Matcher m = Pattern.compile("\\{\\{\\.\\w+}}").matcher(template); + Matcher m = pattern.matcher(template); while (m.find()) { String param = m.group(); String key = param.substring(3, param.length() - 2).trim(); diff --git a/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerHandler.java b/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerHandler.java index 5bb81aa6b1fea..47eb68229046c 100644 --- a/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerHandler.java +++ b/server/src/main/java/org/apache/iotdb/db/sink/alertmanager/AlertManagerHandler.java @@ -22,16 +22,16 @@ import org.apache.iotdb.db.sink.api.Handler; import org.apache.iotdb.db.sink.exception.SinkException; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; +import org.apache.http.HttpStatus; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import java.lang.reflect.Type; -import java.util.Map; +import java.io.IOException; public class AlertManagerHandler implements Handler< @@ -40,9 +40,32 @@ public class AlertManagerHandler private HttpPost request; + private final CloseableHttpClient client; + + { + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + cm.setMaxTotal(200); + cm.setDefaultMaxPerRoute(20); + RequestConfig requestConfig = + RequestConfig.custom() + .setConnectTimeout(1000) + .setSocketTimeout(1000) + .setConnectionRequestTimeout(1000) + .build(); + client = + HttpClients.custom() + .setConnectionManager(cm) + .setDefaultRequestConfig(requestConfig) + .build(); + } + @Override - public void open(org.apache.iotdb.db.sink.alertmanager.AlertManagerConfiguration configuration) - throws Exception { + public void close() throws IOException { + client.close(); + } + + @Override + public void open(org.apache.iotdb.db.sink.alertmanager.AlertManagerConfiguration configuration) { this.request = new HttpPost(configuration.getEndpoint()); request.setHeader("Accept", "application/json"); request.setHeader("Content-type", "application/json"); @@ -51,41 +74,14 @@ public void open(org.apache.iotdb.db.sink.alertmanager.AlertManagerConfiguration @Override public void onEvent(AlertManagerEvent event) throws Exception { - String json = eventToJson(event); + String json = "[" + event.toJsonString() + "]"; request.setEntity(new StringEntity(json)); - try (CloseableHttpClient client = HttpClients.createDefault()) { - - CloseableHttpResponse response = client.execute(request); - - if (response.getStatusLine().getStatusCode() != 200) { - throw new SinkException(response.getStatusLine().toString()); - } - } - } - - private static String eventToJson(AlertManagerEvent event) throws SinkException { - Gson gson = new Gson(); - Type gsonType = new TypeToken() {}.getType(); - - StringBuilder sb = new StringBuilder(); - sb.append("[{\"labels\":"); - - if (event.getLabels() == null) { - throw new SinkException("labels empty error"); - } - - String labelsString = gson.toJson(event.getLabels(), gsonType); - sb.append(labelsString); + CloseableHttpResponse response = client.execute(request); - if (event.getAnnotations() != null) { - String annotationsString = gson.toJson(event.getAnnotations(), gsonType); - sb.append(","); - sb.append("\"annotations\":"); - sb.append(annotationsString); + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + throw new SinkException(response.getStatusLine().toString()); } - sb.append("}]"); - return sb.toString(); } } diff --git a/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesConfiguration.java b/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesConfiguration.java deleted file mode 100644 index 19066036c46e6..0000000000000 --- a/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.iotdb.db.sink.ts; - -import org.apache.iotdb.db.exception.metadata.IllegalPathException; -import org.apache.iotdb.db.metadata.PartialPath; -import org.apache.iotdb.db.sink.api.Configuration; -import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; - -public class TimeSeriesConfiguration implements Configuration { - - private final PartialPath device; - private final String[] measurements; - private final TSDataType[] dataTypes; - - public TimeSeriesConfiguration(String device, String[] measurements, TSDataType[] dataTypes) - throws IllegalPathException { - this.device = new PartialPath(device); - this.measurements = measurements; - this.dataTypes = dataTypes; - } - - public PartialPath getDevice() { - return device; - } - - public String[] getMeasurements() { - return measurements; - } - - public TSDataType[] getDataTypes() { - return dataTypes; - } -} diff --git a/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesEvent.java b/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesEvent.java deleted file mode 100644 index 008c1baab086c..0000000000000 --- a/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesEvent.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.iotdb.db.sink.ts; - -import org.apache.iotdb.db.sink.api.Event; - -public class TimeSeriesEvent implements Event { - - private final long timestamp; - private final Object[] values; - - public TimeSeriesEvent(long timestamp, Object... values) { - this.timestamp = timestamp; - this.values = values; - } - - public long getTimestamp() { - return timestamp; - } - - public Object[] getValues() { - return values; - } -} diff --git a/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesHandler.java b/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesHandler.java deleted file mode 100644 index e9b5e014b1411..0000000000000 --- a/server/src/main/java/org/apache/iotdb/db/sink/ts/TimeSeriesHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.iotdb.db.sink.ts; - -import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.StorageEngineException; -import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException; -import org.apache.iotdb.db.exception.query.QueryProcessException; -import org.apache.iotdb.db.metadata.PartialPath; -import org.apache.iotdb.db.qp.executor.IPlanExecutor; -import org.apache.iotdb.db.qp.executor.PlanExecutor; -import org.apache.iotdb.db.qp.physical.PhysicalPlan; -import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan; -import org.apache.iotdb.db.sink.api.Handler; -import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; - -public class TimeSeriesHandler implements Handler { - - private IPlanExecutor executor; - - private PartialPath device; - private String[] measurements; - private TSDataType[] dataTypes; - - @Override - public void open(TimeSeriesConfiguration configuration) throws Exception { - executor = new PlanExecutor(); - - device = configuration.getDevice(); - measurements = configuration.getMeasurements(); - dataTypes = configuration.getDataTypes(); - } - - @Override - public void onEvent(TimeSeriesEvent event) - throws QueryProcessException, StorageEngineException, StorageGroupNotSetException { - InsertRowPlan plan = new InsertRowPlan(); - plan.setNeedInferType(true); - plan.setDeviceId(device); - plan.setMeasurements(measurements); - plan.setDataTypes(dataTypes); - plan.setTime(event.getTimestamp()); - plan.setValues(event.getValues()); - executeNonQuery(plan); - } - - private void executeNonQuery(PhysicalPlan plan) - throws QueryProcessException, StorageGroupNotSetException, StorageEngineException { - if (IoTDBDescriptor.getInstance().getConfig().isReadOnly()) { - throw new QueryProcessException( - "Current system mode is read-only, non-query operation is not supported."); - } - executor.processNonQuery(plan); - } -} diff --git a/server/src/test/java/org/apache/iotdb/db/sink/AlertManagerTest.java b/server/src/test/java/org/apache/iotdb/db/sink/AlertManagerTest.java index 7b56fe6decc10..003ebf960f047 100644 --- a/server/src/test/java/org/apache/iotdb/db/sink/AlertManagerTest.java +++ b/server/src/test/java/org/apache/iotdb/db/sink/AlertManagerTest.java @@ -23,14 +23,56 @@ import org.apache.iotdb.db.sink.alertmanager.AlertManagerEvent; import org.apache.iotdb.db.sink.alertmanager.AlertManagerHandler; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; import org.junit.Test; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; import java.util.HashMap; +import static org.junit.Assert.assertEquals; + public class AlertManagerTest { + class TestHandler implements HttpHandler { + + String correctRequest; + + public TestHandler(String correctRequest) { + this.correctRequest = correctRequest; + } + + @Override + public void handle(HttpExchange exchange) throws IOException { + InputStreamReader isr = + new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8); + BufferedReader br = new BufferedReader(isr); + String query = br.readLine(); + + assertEquals(correctRequest, query); + + byte[] response = "{\"success\": true}".getBytes(); + exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length); + exchange.getResponseBody().write(response); + exchange.close(); + } + } + @Test public void alertmanagerTest0() throws Exception { + + HttpServer httpServer = HttpServer.create(new InetSocketAddress(9093), 0); + httpServer.createContext( + "/api/v2/alerts", new TestHandler("[{\"labels\":{\"alertname\":\"test0\"}}]")); + + httpServer.start(); + AlertManagerConfiguration alertManagerConfiguration = new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts"); AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); @@ -42,10 +84,29 @@ public void alertmanagerTest0() throws Exception { AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertName); alertManagerHandler.onEvent(alertManagerEvent); + + assertEquals("test0", alertManagerEvent.getLabels().get("alertname")); + + alertManagerHandler.close(); + + httpServer.stop(0); } @Test public void alertmanagerTest1() throws Exception { + + HttpServer httpServer = HttpServer.create(new InetSocketAddress(9093), 0); + httpServer.createContext( + "/api/v2/alerts", + new TestHandler( + "[{\"labels\":" + + "{\"severity\":\"critical\"," + + "\"series\":\"root.ln.wt01.wf01.temperature\"," + + "\"alertname\":\"test1\"," + + "\"value\":\"100.0\"}}]")); + + httpServer.start(); + AlertManagerConfiguration alertManagerConfiguration = new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts"); AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); @@ -62,10 +123,35 @@ public void alertmanagerTest1() throws Exception { AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertName, extraLabels); alertManagerHandler.onEvent(alertManagerEvent); + + assertEquals("test1", alertManagerEvent.getLabels().get("alertname")); + assertEquals("critical", alertManagerEvent.getLabels().get("severity")); + assertEquals("root.ln.wt01.wf01.temperature", alertManagerEvent.getLabels().get("series")); + assertEquals(String.valueOf(100.0), alertManagerEvent.getLabels().get("value")); + + alertManagerHandler.close(); + + httpServer.stop(0); } @Test public void alertmanagerTest2() throws Exception { + + HttpServer httpServer = HttpServer.create(new InetSocketAddress(9093), 0); + httpServer.createContext( + "/api/v2/alerts", + new TestHandler( + "[{\"labels\":" + + "{\"severity\":\"critical\"," + + "\"series\":\"root.ln.wt01.wf01.temperature\"," + + "\"alertname\":\"test2\"," + + "\"value\":\"100.0\"}," + + "\"annotations\":" + + "{\"summary\":\"high temperature\"," + + "\"description\":\"test2: root.ln.wt01.wf01.temperature is 100.0\"}}]")); + + httpServer.start(); + AlertManagerConfiguration alertManagerConfiguration = new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts"); AlertManagerHandler alertManagerHandler = new AlertManagerHandler(); @@ -87,5 +173,79 @@ public void alertmanagerTest2() throws Exception { new AlertManagerEvent(alertName, extraLabels, annotations); alertManagerHandler.onEvent(alertManagerEvent); + + assertEquals("test2", alertManagerEvent.getLabels().get("alertname")); + assertEquals("critical", alertManagerEvent.getLabels().get("severity")); + assertEquals("root.ln.wt01.wf01.temperature", alertManagerEvent.getLabels().get("series")); + assertEquals(String.valueOf(100.0), alertManagerEvent.getLabels().get("value")); + + assertEquals("high temperature", alertManagerEvent.getAnnotations().get("summary")); + assertEquals( + "test2: root.ln.wt01.wf01.temperature is 100.0", + alertManagerEvent.getAnnotations().get("description")); + + alertManagerHandler.close(); + + httpServer.stop(0); + } + + @Test + public void alertmanagerEventToJsonTest0() throws Exception { + + String alertName = "test0"; + + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertName); + + assertEquals("{\"labels\":{\"alertname\":\"test0\"}}", alertManagerEvent.toJsonString()); + } + + @Test + public void alertmanagerEventToJsonTest1() throws Exception { + + String alertName = "test1"; + + HashMap extraLabels = new HashMap<>(); + extraLabels.put("severity", "critical"); + extraLabels.put("series", "root.ln.wt01.wf01.temperature"); + extraLabels.put("value", String.valueOf(100.0)); + + AlertManagerEvent alertManagerEvent = new AlertManagerEvent(alertName, extraLabels); + + assertEquals( + "{\"labels\":" + + "{\"severity\":\"critical\"," + + "\"series\":\"root.ln.wt01.wf01.temperature\"," + + "\"alertname\":\"test1\"," + + "\"value\":\"100.0\"}}", + alertManagerEvent.toJsonString()); + } + + @Test + public void alertmanagerEventToJsonTest2() throws Exception { + + String alertName = "test2"; + + HashMap extraLabels = new HashMap<>(); + extraLabels.put("severity", "critical"); + extraLabels.put("series", "root.ln.wt01.wf01.temperature"); + extraLabels.put("value", String.valueOf(100.0)); + + HashMap annotations = new HashMap<>(); + annotations.put("summary", "high temperature"); + annotations.put("description", "{{.alertname}}: {{.series}} is {{.value}}"); + + AlertManagerEvent alertManagerEvent = + new AlertManagerEvent(alertName, extraLabels, annotations); + + assertEquals( + "{\"labels\":" + + "{\"severity\":\"critical\"," + + "\"series\":\"root.ln.wt01.wf01.temperature\"," + + "\"alertname\":\"test2\"," + + "\"value\":\"100.0\"}," + + "\"annotations\":" + + "{\"summary\":\"high temperature\"," + + "\"description\":\"test2: root.ln.wt01.wf01.temperature is 100.0\"}}", + alertManagerEvent.toJsonString()); } }