DataCap 自定义 Notify 通知器

DataCap 支持自定义通知器,使用者可以编写自己的通知器集成到 DataCap 中。该文档主要讲解如何快速集成一个通知器到 DataCap 系统中。

该模块我们主要使用到的是 notify 模块内的代码,我们本文使用钉钉通知器来做示例。

项目配置


新建项目后在 pom.xml 文件中增加以下内容:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>io.edurt.datacap</groupId>
        <artifactId>datacap-notify-spi</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>

我们添加 datacap-notify-spi 依赖,这样我们就可以实现集成通知器。

模块加载器


kotlin 复制代码
package io.edurt.datacap.notify.dingtalk

import com.google.inject.multibindings.Multibinder
import io.edurt.datacap.notify.Notify
import io.edurt.datacap.notify.NotifyModule

class DingTalkModule : NotifyModule()
{
    override fun configure()
    {
        Multibinder.newSetBinder(this.binder(), Notify::class.java)
            .addBinding()
            .to(DingTalkNotify::class.java)
    }
}

通知器


kotlin 复制代码
package io.edurt.datacap.notify.dingtalk

import io.edurt.datacap.notify.Notify
import io.edurt.datacap.notify.model.NotifyRequest
import io.edurt.datacap.notify.model.NotifyResponse

class DingTalkNotify : Notify
{
    override fun send(request: NotifyRequest): NotifyResponse
    {
        return DingTalkUtils.send(request)
    }
}

在转换器中我们只需要实现以下两个方法:

  • fun send(request: NotifyRequest): NotifyResponse 用于实现发送器执行逻辑

DingTalkUtils 工具类


kotlin 复制代码
package io.edurt.datacap.notify.dingtalk

import io.edurt.datacap.common.utils.JsonUtils
import io.edurt.datacap.common.utils.SignUtils
import io.edurt.datacap.lib.http.HttpClient
import io.edurt.datacap.lib.http.HttpConfigure
import io.edurt.datacap.lib.http.HttpMethod
import io.edurt.datacap.notify.NotifyType
import io.edurt.datacap.notify.dingtalk.model.ReturnModel
import io.edurt.datacap.notify.dingtalk.model.TextModel
import io.edurt.datacap.notify.model.NotifyRequest
import io.edurt.datacap.notify.model.NotifyResponse
import org.apache.commons.lang3.StringUtils.isNotEmpty
import org.slf4j.Logger
import org.slf4j.LoggerFactory.getLogger

object DingTalkUtils
{
    private val log: Logger = getLogger(DingTalkUtils::class.java)

    @JvmStatic
    fun send(request: NotifyRequest): NotifyResponse
    {
        val configure = HttpConfigure()
        configure.autoConnected = false
        configure.retry = 0
        configure.protocol = "https"
        configure.host = "oapi.dingtalk.com"
        configure.port = 443
        configure.path = "robot/send"
        configure.method = HttpMethod.POST

        val params = mutableMapOf("access_token" to request.access)
        if (isNotEmpty(request.secret))
        {
            val signResponse = SignUtils.sign(request.secret)
            log.info("Sign response: ${JsonUtils.toJSON(signResponse)}")
            params["sign"] = signResponse.sign
            params["timestamp"] = signResponse.timestamp.toString()
        }
        configure.params = params
        log.info("Notify request params: ${JsonUtils.toJSON(params)}")

        val text = TextModel()
        text.content = request.content
        configure.body = JsonUtils.toJSON(mapOf("text" to text, "msgtype" to formatMessageType(request)))
        log.info("Notify request body: ${configure.body}")

        val client = HttpClient(configure)
        val returnModel = JsonUtils.toObject(client.execute(), ReturnModel::class.java)
        val response = NotifyResponse()
        if (returnModel.code == 0)
        {
            response.successful = true
            response.message = null
        }
        else
        {
            response.successful = false
            response.message = returnModel.message
        }
        return response
    }

    private fun formatMessageType(request: NotifyRequest): String
    {
        if (request.type == NotifyType.TEXT)
        {
            return "text"
        }
        else
        {
            return "markdown"
        }
    }
}

在工具类中我们主要实现发送钉钉消息操作。

Notify SPI 加载器


resources 源目录下添加 META-INFservices 目录,格式为 resources/META-INF/services,创建 io.edurt.datacap.fs.FsModule 文件,内容如下

kotlin 复制代码
io.edurt.datacap.notify.dingtalk.DingTalkModule

通过以上内容我们实现了 DingTalk 通知器的支持。我们只需要在要使用 DingTalk 通知器器的地方引用该模块即可。比如我们在 server 模块中使用到该模块,则在 server/pom.xml 文件中增加以下内容

xml 复制代码
<dependency>
    <groupId>io.edurt.datacap</groupId>
    <artifactId>datacap-notify-dingtalk</artifactId>
    <version>${project.version}</version>
</dependency>

DingTalk Utils 测试

kotlin 复制代码
package io.edurt.datacap.notify.dingtalk

import io.edurt.datacap.notify.model.NotifyRequest
import org.junit.Assert
import org.junit.Before
import org.junit.Test

class DingTalkUtilsTest
{
    private val request: NotifyRequest = NotifyRequest()

    @Before
    fun before()
    {
        request.access = "ACCESS"
        request.content = "Test Message"
        request.secret = "SECRET"
    }

    @Test
    fun testSend()
    {
        Assert.assertFalse(
            DingTalkUtils.send(request)
                .successful
        )
    }
}

DingTalk Module 测试

kotlin 复制代码
package io.edurt.datacap.notify.dingtalk

import com.google.inject.Guice
import com.google.inject.Injector
import com.google.inject.Key
import com.google.inject.TypeLiteral
import io.edurt.datacap.notify.Notify
import io.edurt.datacap.notify.NotifyManager
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test

class DingTalkModuleTest
{
    private val name = "DingTalk"
    private var injector: Injector? = null

    @Before
    fun before()
    {
        injector = Guice.createInjector(NotifyManager())
    }

    @Test
    fun test()
    {
        val notify: Notify? = injector?.getInstance(Key.get(object : TypeLiteral<Set<Notify>>()
        {}))
            ?.first { it.name() == name }
        assertNotNull(notify)
    }
}

DingTalk SPI 测试

kotlin 复制代码
package io.edurt.datacap.notify.dingtalk

import com.google.inject.Guice
import com.google.inject.Injector
import com.google.inject.Key
import com.google.inject.TypeLiteral
import io.edurt.datacap.notify.Notify
import io.edurt.datacap.notify.NotifyManager
import io.edurt.datacap.notify.model.NotifyRequest
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test

class DingTalkNotifyTest
{
    private val name = "DingTalk"
    private var injector: Injector? = null
    private val request: NotifyRequest = NotifyRequest()

    @Before
    fun before()
    {
        injector = Guice.createInjector(NotifyManager())

        request.access = "ACCESS"
        request.content = "Test Message"
        request.secret = "SECRET"
    }

    @Test
    fun test()
    {
        val notify: Notify? = injector?.getInstance(Key.get(object : TypeLiteral<Set<Notify>>()
        {}))
            ?.first { it.name() == name }
        assertNotNull(notify?.send(request))
    }
}
相关推荐
llwszx1 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
云泽野2 小时前
【Java|集合类】list遍历的6种方式
java·python·list
二进制person2 小时前
Java SE--方法的使用
java·开发语言·算法
小阳拱白菜3 小时前
java异常学习
java
说私域4 小时前
基于开源AI智能名片链动2+1模式S2B2C商城小程序的超级文化符号构建路径研究
人工智能·小程序·开源
FrankYoou4 小时前
Jenkins 与 GitLab CI/CD 的核心对比
java·docker
麦兜*5 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
KK溜了溜了5 小时前
JAVA-springboot 整合Redis
java·spring boot·redis
天河归来5 小时前
使用idea创建springboot单体项目
java·spring boot·intellij-idea
weixin_478689765 小时前
十大排序算法汇总
java·算法·排序算法