You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ta...@apache.org on 2020/02/10 09:42:47 UTC
[skywalking] 01/02: support gRPC hook.
This is an automated email from the ASF dual-hosted git repository.
tanjian pushed a commit to branch grpc_alarm
in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit 788a416b90e721cfffc300023ebd1ff05c50d6d8
Author: JaredTan95 <ji...@daocloud.io>
AuthorDate: Mon Feb 10 17:37:55 2020 +0800
support gRPC hook.
---
docs/en/setup/backend/backend-alarm.md | 19 ++++
oap-server/server-alarm-plugin/pom.xml | 34 +++++++
.../core/alarm/provider/AlarmRulesWatcher.java | 21 +++--
.../server/core/alarm/provider/NotifyHandler.java | 2 +
.../oap/server/core/alarm/provider/Rules.java | 2 +
.../server/core/alarm/provider/RulesReader.java | 29 +++++-
.../{Rules.java => grpc/GRPCAlarmSetting.java} | 25 +++--
.../core/alarm/provider/grpc/GRPCCallback.java | 102 +++++++++++++++++++++
.../provider/Rules.java => proto/alarm-hook.proto} | 32 ++++---
.../core/alarm/provider/AlarmRulesWatcherTest.java | 13 ++-
.../alarm/provider/grpc/AlarmMockReceiver.java | 73 +++++++++++++++
.../alarm/provider/grpc/GRPChookCallbackTest.java | 72 +++++++++++++++
.../src/test/resources/alarm-settings.yml | 4 +
.../src/main/resources/alarm-settings.yml | 4 +
14 files changed, 388 insertions(+), 44 deletions(-)
diff --git a/docs/en/setup/backend/backend-alarm.md b/docs/en/setup/backend/backend-alarm.md
index d277958..2787f95 100644
--- a/docs/en/setup/backend/backend-alarm.md
+++ b/docs/en/setup/backend/backend-alarm.md
@@ -3,6 +3,7 @@ Alarm core is driven by a collection of rules, which are defined in `config/alar
There are two parts in alarm rule definition.
1. [Alarm rules](#rules). They define how metrics alarm should be triggered, what conditions should be considered.
1. [Webhooks](#webhook). The list of web service endpoint, which should be called after the alarm is triggered.
+1. [gRPCHook](#gRPCHook). The host and port of remote gRPC method, which should be called after the alarm is triggered.
## Rules
Alarm rule is constituted by following keys
@@ -113,6 +114,24 @@ Example as following
}]
```
+## gRPCHook
+The alarm message will send through remote gRPC method by `Protobuf` content type.
+The message format with following key information which are defined in `oap-server/server-alarm-plugin/src/main/proto/alarm-hook.proto`.
+
+Example as following
+```text
+message AlarmMessage {
+ int64 scopeId = 1;
+ string scope = 2;
+ string name = 3;
+ int64 id0 = 4;
+ int64 id1 = 5;
+ string ruleName = 6;
+ string alarmMessage = 7;
+ int64 startTime = 8;
+}
+```
+
## Update the settings dynamically
Since 6.5.0, the alarm settings can be updated dynamically at runtime by [Dynamic Configuration](dynamic-config.md),
which will override the settings in `alarm-settings.yml`.
diff --git a/oap-server/server-alarm-plugin/pom.xml b/oap-server/server-alarm-plugin/pom.xml
index 362902d..24fe8bf 100644
--- a/oap-server/server-alarm-plugin/pom.xml
+++ b/oap-server/server-alarm-plugin/pom.xml
@@ -26,6 +26,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>server-alarm-plugin</artifactId>
+
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
@@ -37,7 +38,40 @@
<artifactId>library-util</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-testing</artifactId>
+ </dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.xolstice.maven.plugins</groupId>
+ <artifactId>protobuf-maven-plugin</artifactId>
+ <version>${protobuf-maven-plugin.version}</version>
+ <configuration>
+ <!--
+ The version of protoc must match protobuf-java. If you don't depend on
+ protobuf-java directly, you will be transitively depending on the
+ protobuf-java version that grpc depends on.
+ -->
+ <protocArtifact>com.google.protobuf:protoc:${com.google.protobuf.protoc.version}:exe:${os.detected.classifier}
+ </protocArtifact>
+ <pluginId>grpc-java</pluginId>
+ <pluginArtifact>io.grpc:protoc-gen-grpc-java:${protoc-gen-grpc-java.plugin.version}:exe:${os.detected.classifier}
+ </pluginArtifact>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ <goal>compile-custom</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
\ No newline at end of file
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcher.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcher.java
index abfecc9..513eff3 100644
--- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcher.java
+++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcher.java
@@ -18,22 +18,21 @@
package org.apache.skywalking.oap.server.core.alarm.provider;
-import lombok.Getter;
-import org.apache.skywalking.oap.server.configuration.api.ConfigChangeWatcher;
-import org.apache.skywalking.oap.server.core.Const;
-import org.apache.skywalking.oap.server.core.alarm.AlarmModule;
-import org.apache.skywalking.oap.server.library.module.ModuleProvider;
-
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import lombok.Getter;
+import org.apache.skywalking.oap.server.configuration.api.ConfigChangeWatcher;
+import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.alarm.AlarmModule;
+import org.apache.skywalking.oap.server.core.alarm.provider.grpc.GRPCAlarmSetting;
+import org.apache.skywalking.oap.server.library.module.ModuleProvider;
/**
- * Alarm rules' settings can be dynamically updated via configuration center(s),
- * this class is responsible for monitoring the configuration and parsing them
- * into {@link Rules} and {@link #runningContext}.
+ * Alarm rules' settings can be dynamically updated via configuration center(s), this class is responsible for
+ * monitoring the configuration and parsing them into {@link Rules} and {@link #runningContext}.
*
* @author kezhenxu94
* @since 6.5.0
@@ -104,4 +103,8 @@ public class AlarmRulesWatcher extends ConfigChangeWatcher {
public List<String> getWebHooks() {
return this.rules.getWebhooks();
}
+
+ public GRPCAlarmSetting getGrpchookSetting() {
+ return this.rules.getGrpchookSetting();
+ }
}
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java
index 8fbedcb..8b72fb4 100644
--- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java
+++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java
@@ -21,6 +21,7 @@ package org.apache.skywalking.oap.server.core.alarm.provider;
import java.util.*;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.alarm.*;
+import org.apache.skywalking.oap.server.core.alarm.provider.grpc.GRPCCallback;
import org.apache.skywalking.oap.server.core.analysis.metrics.*;
import org.apache.skywalking.oap.server.core.cache.*;
import org.apache.skywalking.oap.server.core.register.*;
@@ -97,6 +98,7 @@ public class NotifyHandler implements MetricsNotify {
public void init(AlarmCallback... callbacks) {
List<AlarmCallback> allCallbacks = new ArrayList<>(Arrays.asList(callbacks));
allCallbacks.add(new WebhookCallback(alarmRulesWatcher));
+ allCallbacks.add(new GRPCCallback(alarmRulesWatcher));
core.start(allCallbacks);
}
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java
index e7a2e34..872ef44 100644
--- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java
+++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java
@@ -20,12 +20,14 @@ package org.apache.skywalking.oap.server.core.alarm.provider;
import java.util.*;
import lombok.*;
+import org.apache.skywalking.oap.server.core.alarm.provider.grpc.GRPCAlarmSetting;
@Setter(AccessLevel.PUBLIC)
@Getter(AccessLevel.PUBLIC)
public class Rules {
private List<AlarmRule> rules;
private List<String> webhooks;
+ private GRPCAlarmSetting grpchookSetting;
public Rules() {
this.rules = new ArrayList<>();
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java
index 74fb9da..97cbd69 100644
--- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java
+++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java
@@ -18,8 +18,13 @@
package org.apache.skywalking.oap.server.core.alarm.provider;
-import java.io.*;
-import java.util.*;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import org.apache.skywalking.oap.server.core.alarm.provider.grpc.GRPCAlarmSetting;
import org.yaml.snakeyaml.Yaml;
/**
@@ -74,9 +79,23 @@ public class RulesReader {
List webhooks = (List)yamlData.get("webhooks");
if (webhooks != null) {
rules.setWebhooks(new ArrayList<>());
- webhooks.forEach(url -> {
- rules.getWebhooks().add((String)url);
- });
+ webhooks.forEach(url -> rules.getWebhooks().add((String)url));
+ }
+
+ Map grpchooks = (Map)yamlData.get("gRPCHook");
+ if (grpchooks != null) {
+ GRPCAlarmSetting grpcAlarmSetting = new GRPCAlarmSetting();
+ Object targetHost = grpchooks.get("target_host");
+ if (targetHost != null) {
+ grpcAlarmSetting.setTargetHost((String)targetHost);
+ }
+
+ Object targetPort = grpchooks.get("target_port");
+ if (targetPort != null) {
+ grpcAlarmSetting.setTargetPort((Integer)targetPort);
+ }
+
+ rules.setGrpchookSetting(grpcAlarmSetting);
}
}
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPCAlarmSetting.java
similarity index 69%
copy from oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java
copy to oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPCAlarmSetting.java
index e7a2e34..f8a0361 100644
--- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java
+++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPCAlarmSetting.java
@@ -16,19 +16,18 @@
*
*/
-package org.apache.skywalking.oap.server.core.alarm.provider;
+package org.apache.skywalking.oap.server.core.alarm.provider.grpc;
-import java.util.*;
-import lombok.*;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.library.module.ModuleConfig;
-@Setter(AccessLevel.PUBLIC)
-@Getter(AccessLevel.PUBLIC)
-public class Rules {
- private List<AlarmRule> rules;
- private List<String> webhooks;
-
- public Rules() {
- this.rules = new ArrayList<>();
- this.webhooks = new ArrayList<>();
- }
+/**
+ * @author jian.tan
+ */
+@Setter
+@Getter
+public class GRPCAlarmSetting extends ModuleConfig {
+ private String targetHost;
+ private int targetPort;
}
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPCCallback.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPCCallback.java
new file mode 100644
index 0000000..d69f732
--- /dev/null
+++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPCCallback.java
@@ -0,0 +1,102 @@
+/*
+ * 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.skywalking.oap.server.core.alarm.provider.grpc;
+
+import io.grpc.stub.StreamObserver;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.oap.server.core.alarm.AlarmCallback;
+import org.apache.skywalking.oap.server.core.alarm.AlarmMessage;
+import org.apache.skywalking.oap.server.core.alarm.grpc.AlarmServiceGrpc;
+import org.apache.skywalking.oap.server.core.alarm.grpc.Response;
+import org.apache.skywalking.oap.server.core.alarm.provider.AlarmRulesWatcher;
+import org.apache.skywalking.oap.server.library.client.grpc.GRPCClient;
+
+/**
+ * Use SkyWalking alarm grpc API call a remote methods.
+ *
+ * @author jian.tan
+ */
+@Slf4j
+public class GRPCCallback implements AlarmCallback {
+
+ GRPCAlarmSetting alarmSetting;
+
+ private AlarmServiceGrpc.AlarmServiceStub alarmServiceStub;
+
+ public GRPCCallback(AlarmRulesWatcher alarmRulesWatcher) {
+ alarmSetting = alarmRulesWatcher.getGrpchookSetting();
+ if (alarmSetting != null) {
+ GRPCClient client = new GRPCClient(alarmSetting.getTargetHost(), alarmSetting.getTargetPort());
+ client.connect();
+ alarmServiceStub = AlarmServiceGrpc.newStub(client.getChannel());
+ }
+ }
+
+ @Override public void doAlarm(List<AlarmMessage> alarmMessage) {
+
+ if (alarmServiceStub == null) {
+ return;
+ }
+
+ StreamObserver<org.apache.skywalking.oap.server.core.alarm.grpc.AlarmMessage> streamObserver =
+ alarmServiceStub.withDeadlineAfter(10, TimeUnit.SECONDS).doAlarm(new StreamObserver<Response>() {
+ @Override public void onNext(Response response) {
+
+ }
+
+ @Override public void onError(Throwable throwable) {
+ if (log.isDebugEnabled()) {
+ log.debug("Send alarm message failed: {}", throwable.getMessage());
+ }
+
+ }
+
+ @Override public void onCompleted() {
+ if (log.isDebugEnabled()) {
+ log.debug("Send alarm message successful.");
+ }
+ }
+ });
+
+ alarmMessage.forEach(message -> {
+ org.apache.skywalking.oap.server.core.alarm.grpc.AlarmMessage.Builder builder =
+ org.apache.skywalking.oap.server.core.alarm.grpc.AlarmMessage.newBuilder();
+
+ builder.setScopeId(message.getScopeId());
+ builder.setScope(message.getScope());
+ builder.setName(message.getName());
+ builder.setId0(message.getId0());
+ builder.setId1(message.getId1());
+ builder.setRuleName(message.getRuleName());
+ builder.setAlarmMessage(message.getAlarmMessage());
+ builder.setStartTime(message.getStartTime());
+
+ streamObserver.onNext(builder.build());
+ });
+
+ streamObserver.onCompleted();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Send {} alarm message to {}:{}.", alarmMessage.size(),
+ alarmSetting.getTargetHost(), alarmSetting.getTargetPort());
+ }
+ }
+}
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java b/oap-server/server-alarm-plugin/src/main/proto/alarm-hook.proto
similarity index 64%
copy from oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java
copy to oap-server/server-alarm-plugin/src/main/proto/alarm-hook.proto
index e7a2e34..1e2e638 100644
--- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/Rules.java
+++ b/oap-server/server-alarm-plugin/src/main/proto/alarm-hook.proto
@@ -16,19 +16,27 @@
*
*/
-package org.apache.skywalking.oap.server.core.alarm.provider;
+syntax = "proto3";
-import java.util.*;
-import lombok.*;
+option java_multiple_files = true;
+option java_package = "org.apache.skywalking.oap.server.core.alarm.grpc";
-@Setter(AccessLevel.PUBLIC)
-@Getter(AccessLevel.PUBLIC)
-public class Rules {
- private List<AlarmRule> rules;
- private List<String> webhooks;
-
- public Rules() {
- this.rules = new ArrayList<>();
- this.webhooks = new ArrayList<>();
+service AlarmService {
+ rpc doAlarm (stream AlarmMessage) returns (Response) {
}
}
+
+message AlarmMessage {
+ int64 scopeId = 1;
+ string scope = 2;
+ string name = 3;
+ int64 id0 = 4;
+ int64 id1 = 5;
+ string ruleName = 6;
+ string alarmMessage = 7;
+ int64 startTime = 8;
+}
+
+message Response {
+}
+
diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcherTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcherTest.java
index 8535c1d..26b8d45 100644
--- a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcherTest.java
+++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/AlarmRulesWatcherTest.java
@@ -18,6 +18,10 @@
package org.apache.skywalking.oap.server.core.alarm.provider;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
import org.apache.skywalking.oap.server.configuration.api.ConfigChangeWatcher;
import org.apache.skywalking.oap.server.library.util.ResourceUtils;
import org.junit.Before;
@@ -25,13 +29,9 @@ import org.junit.Test;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Arrays;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.spy;
@@ -82,6 +82,8 @@ public class AlarmRulesWatcherTest {
assertEquals(2, alarmRulesWatcher.getRules().size());
assertEquals(2, alarmRulesWatcher.getWebHooks().size());
+ assertNotNull(alarmRulesWatcher.getGrpchookSetting());
+ assertEquals(9888, alarmRulesWatcher.getGrpchookSetting().getTargetPort());
assertEquals(2, alarmRulesWatcher.getRunningContext().size());
}
@@ -96,6 +98,7 @@ public class AlarmRulesWatcherTest {
assertEquals(0, alarmRulesWatcher.getRules().size());
assertEquals(0, alarmRulesWatcher.getWebHooks().size());
+ assertNull(alarmRulesWatcher.getGrpchookSetting());
assertEquals(0, alarmRulesWatcher.getRunningContext().size());
}
diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/AlarmMockReceiver.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/AlarmMockReceiver.java
new file mode 100644
index 0000000..0052ef1
--- /dev/null
+++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/AlarmMockReceiver.java
@@ -0,0 +1,73 @@
+/*
+ * 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.skywalking.oap.server.core.alarm.provider.grpc;
+
+import io.grpc.stub.StreamObserver;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.oap.server.core.alarm.grpc.AlarmMessage;
+import org.apache.skywalking.oap.server.core.alarm.grpc.AlarmServiceGrpc;
+import org.apache.skywalking.oap.server.core.alarm.grpc.Response;
+import org.apache.skywalking.oap.server.library.server.ServerException;
+import org.apache.skywalking.oap.server.library.server.grpc.GRPCHandler;
+import org.apache.skywalking.oap.server.library.server.grpc.GRPCServer;
+
+@Slf4j
+public class AlarmMockReceiver {
+ public static void main(String[] args) throws ServerException, InterruptedException {
+ GRPCServer server = new GRPCServer("localhost", 9888);
+ server.initialize();
+ server.addHandler(new MockAlarmHandler());
+ server.start();
+
+ while (true) {
+ Thread.sleep(20000L);
+ }
+ }
+
+ public static class MockAlarmHandler extends AlarmServiceGrpc.AlarmServiceImplBase implements GRPCHandler {
+
+ @Override public StreamObserver<AlarmMessage> doAlarm(StreamObserver<Response> responseObserver) {
+ return new StreamObserver<AlarmMessage>() {
+ @Override
+ public void onNext(AlarmMessage value) {
+ System.out.println(value.toString());
+ log.info("received alarm message: {}", value.toString());
+ }
+
+ @Override
+ public void onError(Throwable throwable) {
+ responseObserver.onError(throwable);
+ if (log.isDebugEnabled()) {
+ log.debug("received alarm message error.");
+ }
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void onCompleted() {
+ responseObserver.onNext(Response.newBuilder().build());
+ responseObserver.onCompleted();
+ if (log.isDebugEnabled()) {
+ log.debug("received alarm message completed.");
+ }
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPChookCallbackTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPChookCallbackTest.java
new file mode 100644
index 0000000..bc58ba3
--- /dev/null
+++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/grpc/GRPChookCallbackTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.skywalking.oap.server.core.alarm.provider.grpc;
+
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.apache.skywalking.oap.server.core.alarm.AlarmMessage;
+import org.apache.skywalking.oap.server.core.alarm.provider.AlarmRulesWatcher;
+import org.apache.skywalking.oap.server.core.alarm.provider.Rules;
+import org.apache.skywalking.oap.server.core.query.entity.Scope;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author jian.tan
+ */
+public class GRPChookCallbackTest {
+
+ private GRPCCallback grpcCallback;
+
+ private AlarmRulesWatcher alarmRulesWatcher;
+
+ private List<AlarmMessage> alarmMessageList;
+
+ @Before
+ public void init() throws Exception {
+ GRPCAlarmSetting setting = new GRPCAlarmSetting();
+ setting.setTargetHost("127.0.0.1");
+ setting.setTargetPort(9888);
+
+ Rules rules = new Rules();
+ rules.setGrpchookSetting(setting);
+
+ alarmRulesWatcher = new AlarmRulesWatcher(rules, null);
+ grpcCallback = new GRPCCallback(alarmRulesWatcher);
+ mockAlarmMessage();
+ }
+
+ @Test
+ public void doAlarm() {
+ grpcCallback.doAlarm(alarmMessageList);
+ }
+
+ private void mockAlarmMessage() {
+ AlarmMessage alarmMessage = new AlarmMessage();
+ alarmMessage.setId0(1);
+ alarmMessage.setId1(2);
+ alarmMessage.setScope(Scope.Service.name());
+ alarmMessage.setName("mock alarm message");
+ alarmMessage.setAlarmMessage("message");
+ alarmMessage.setRuleName("mock_rule");
+ alarmMessage.setStartTime(System.currentTimeMillis());
+
+ alarmMessageList = Lists.newArrayList(alarmMessage);
+ }
+}
diff --git a/oap-server/server-alarm-plugin/src/test/resources/alarm-settings.yml b/oap-server/server-alarm-plugin/src/test/resources/alarm-settings.yml
index 880e21f..144e94d 100755
--- a/oap-server/server-alarm-plugin/src/test/resources/alarm-settings.yml
+++ b/oap-server/server-alarm-plugin/src/test/resources/alarm-settings.yml
@@ -44,3 +44,7 @@ webhooks:
- http://127.0.0.1/notify/
- http://127.0.0.1/go-wechat/
+gRPCHook:
+ target_host: 127.0.0.1
+ target_port: 9888
+
diff --git a/oap-server/server-bootstrap/src/main/resources/alarm-settings.yml b/oap-server/server-bootstrap/src/main/resources/alarm-settings.yml
index 0c224d5..c161092 100755
--- a/oap-server/server-bootstrap/src/main/resources/alarm-settings.yml
+++ b/oap-server/server-bootstrap/src/main/resources/alarm-settings.yml
@@ -43,3 +43,7 @@ webhooks:
# - http://127.0.0.1/notify/
# - http://127.0.0.1/go-wechat/
+gRPCHook:
+# target_host: 127.0.0.1
+# target_port: 9888
+