【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

一、特殊名词介绍

二、背景、场景介绍

帆软决策平台自9.0开始引入了短信服务功能。但一部分用户因为之前已经有自己在使用的短信提供商了,所以无法选择直接使用帆软本身的短信服务。为了接入其他短信服务商的服务,在10.0中单独开放了SMSServiceProvider这个短信接入的接口。

三、接口介绍

SMSServiceProvider.java
package com.fr.stable.fun;

import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.mark.Selectable;

import java.util.List;
import java.util.Map;

/**
 * 第三方sms服务接入接口
 *
 * @author Lanlan
 */
public interface SMSServiceProvider extends Selectable {

    int CURRENT_LEVEL = 1;

    String XML_TAG = "SMSServiceProvider";

    /**
     * 根据内置的短信模板编号,转换成实际的第三方短信平台的短信模板
     *
     * @return 编号和实际模板的键值对集合
     */
    Map<String, String> mapping();

    /**
     * 发送测试短信
     *
     * @param mobile 接收短信的手机号
     * @return 结果
     */
    Response sendTest(String mobile);

    /**
     * FR包含的短信发送功能
     *
     * @param template 发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
     * @param mobile   接收短信的手机号
     * @param para     生成最终短信需要的参数
     * @param receiver 接收者(用户)
     * @return 结果
     * @throws Exception 异常
     */
    Response send(String template, String mobile, JSONObject para, String receiver) throws Exception;

    /**
     * FR包含的批量发送短信的功能
     *
     * @param template  发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
     * @param mobiles   接收短信的手机号列表
     * @param params    对应的生成最终短信需要的参数JSON数组
     * @param receivers 接收者(用户)列表,三个列表/数组,根据序号一一对应
     * @return 结果
     * @throws Exception 异常
     */
    Response batchSendSMS(String template, List<String> mobiles, JSONArray params, List<String> receivers) throws Exception;

    /**
     * 第三方sms服务响应
     */
    class Response {

        public final static String RES_STATUS_SUCCESS = "success";
        public final static String RES_STATUS_FAILED = "failed";

        private String status;
        private String msg;
        private JSONObject content;

        public static Response create(String status, String msg, JSONObject content) {
            if (StringUtils.isEmpty(status) || StringUtils.isEmpty(msg)) {
                return null;
            }
            if (content == null) {
                content = JSONObject.create();
            }
            return new Response(status, msg, content);
        }

        private Response(String status, String msg, JSONObject content) {
            this.status = status;
            this.msg = msg;
            this.content = content;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public JSONObject getContent() {
            if (!content.has("status")) {
                content.put("status", status);
            }
            if (!content.has("msg")) {
                content.put("msg", msg);
            }
            return content;
        }

        public void setContent(JSONObject content) {
            this.content = content;
        }
    }

    /**
     * sms监听器
     *
     * @author Lanlan
     * @date 2019/1/29
     */
    interface Listener {

        /**
         * 短信发送前事件处理接口
         *
         * @param text      发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
         * @param mobiles   接收短信的手机号列表
         * @param params    生成最终短信需要的参数JSON数组
         * @param receivers 接收者(用户)列表
         */
        void beforeSend(String text, List<String> mobiles, JSONArray params, List<String> receivers);

        /**
         * 短信发送后事件处理接口
         *
         * @param text      发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
         * @param mobiles   接收短信的手机号列表
         * @param params    生成最终短信需要的参数JSON数组
         * @param receivers 接收者(用户)列表
         * @param response  响应(仅在使用了第三方服务接口后且仅在发送结束后事件有效!)
         */
        void afterSend(String text, List<String> mobiles, JSONArray params, List<String> receivers, Response response);
    }
}


SMSContext.java
package com.fr.base.sms;

import com.fr.stable.fun.SMSServiceProvider;
import com.fr.json.JSONArray;
import com.fr.plugin.solution.sandbox.collection.PluginSandboxCollections;
import com.fr.stable.fun.SMSServiceProvider;

import java.util.List;

/**
 * sms监听管理,目前主要用于sms第三方服务
 *
 * @author Lanlan
 * @date 2019/1/29
 */
public class SMSContext {

    private static List<SMSServiceProvider.Listener> smsListeners = PluginSandboxCollections.newSandboxList();

    /**
     * 注册SMS监听
     *
     * @param smsListener sms监听器
     */
    public static void addSmsListener(SMSServiceProvider.Listener smsListener) {
        smsListeners.add(smsListener);
    }

    /**
     * 短信发送前事件处理
     *
     * @param text      发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
     * @param mobiles   接收短信的手机号列表
     * @param para      生成最终短信需要的参数JSON数组
     * @param receivers 接收者(用户)列表
     */
    public static void fireBeforeSendSmsListeners(String text, List<String> mobiles, JSONArray para, List<String> receivers) {
        for (SMSServiceProvider.Listener smsListener : smsListeners) {
            smsListener.beforeSend(text, mobiles, para, receivers);
        }
    }

    /**
     * 短信发送后事件处理
     *
     * @param text      发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
     * @param mobiles   接收短信的手机号列表
     * @param para      生成最终短信需要的参数JSON数组
     * @param receivers 接收者(用户)列表
     */
    public static void fireAfterSendSmsListeners(String text, List<String> mobiles, JSONArray para, List<String> receivers, SMSServiceProvider.Response response) {
        for (SMSServiceProvider.Listener smsListener : smsListeners) {
            smsListener.afterSend(text, mobiles, para, receivers, response);
        }
    }
}



四、支持版本

产品线

版本

支持情况

备注

FR10.0支持

五、插件注册

plugin.xml
<extra-core>
        <SMSServiceProvider class="your class name"/>
</extra-core>

六、原理说明

该接口在需要调用的地方通过:Set<SMSServiceProvider> providers = PluginModule.ExtraCore.getAgent().getArray(SMSServiceProvider.XML_TAG); 获取到插件中所有申明的第三方短信服务扩展实现。

在产品中主要通过以下方式生效:

决策平台所有的短信服务都通过SMSManager进行入口管理。跟接口对应的该管理类也提供了batchSendSMS/sendSMS/sendTestSMS一共三种发送短信的入口。当管理类被具体的业务逻辑触发短信事件时,会先检测是否有插件申明了扩展短信服务,如果有则使用扩展的短信进行发送,否则则使用产品自带的短信服务。

七、特殊限制说明

1.因为帆软本身的短信服务是通过ID和文本短信模板匹配的,调用的时候都是用的ID,所以,要使用该接口接入第三方短信,必须是在能连通帆软短信服务的前提下。

2.需要使用mapping();返回所有可能用到的帆软短信服务ID跟第三方短信服务模板的映射关系。比如短信验证码的ID 是20 那么就要 有一个 <20,“短信验证码:${code}”>这样的键值对。

3.send接口中的template参数就是 mapping中键值对对应的文本了。

4.需要在决策平台中开始短信服务(注册帆软短信服务账号,申请相应的短信模板)后该接口方能正常使用。

5.短信的before和after事件,只能对第三方短信服务生效!不能监听帆软自己的短信服务!

内置各类短信时间的编号和模板列表:

项目短信编号默认模板内容
定时任务发送失败提醒10

【信息平台】尊敬的管理员,#taskname##time#运行失败,请知晓。

短信平台告警17

【信息平台】您好,#webname#系统内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。

短信平台测试结果18

【信息平台】恭喜!您的短信服务已经配置成功。

短信平台开通通知19

【信息平台】您好,#taskname##time#运行成功。

短息登录验证码20

【信息平台】您的手机验证码为#verifiecode#,请于10分钟内正确输入。

日志清理预警49

【信息平台】您好,#webname#系统日志文件已大于#logsize#M,请及时登录平台进行日志清理。

短信平台告警50

【信息平台】您好,#webname#系统#clustername#内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。

定时任务发送失败提醒51

【信息平台】你好,#task#出错,请及时处理。该任务开始执行时间:#time#

上报流程预警53

【信息平台】上报任务 #task#,已经到您这里#time#,请尽快处理!

上报流程提醒54

【信息平台】#name#您好,上报任务#task#已经发起,请尽快处理!

集群状态异常提醒63

【信息平台】系统检测到,节点#node_id#的系统时间与其他节点不一致。请配置时间服务器,实现节点时间的自动同步。

集群状态异常提醒64

【信息平台】节点#node_id#,非正常脱离集群环境。请重启该节点,加入集群。

集群状态异常提醒89

【信息平台】节点#nodename#,与节点#node1name#jar包不一致,将影响集群工程的稳定性,请前往集群节点管理页面查看详细异常信息,并及时处理。

集群状态异常提醒

90

【信息平台】节点#nodename#情况异常,用户不能正常访问,请及时检查该节点状态。

任务提醒125

【信息平台】您有个#proname#任务即将过期,请您尽快办理。

任务提醒127

【信息平台】您有个#proname#任务需要处理,请您尽快办理。发起人:#startpeople#,发起时间:#starttime#

集群状态异常提醒134

【信息平台】Redis集群#ip_port#节点已无法正常使用,可能原因为:节点宕机、内存已满、其他异常。为避免影响用户使用,请前往状态服务器配置页面查看详情,并及时处理。

文件服务器异常提醒135

【信息平台】文件服务器出现无法读写的情况,可能原因为:文件服务器宕机、磁盘已满、其他异常。为避免影响用户使用,请及时检查文件服务器状态。

短信平台告警136

【信息平台】您好,#webname#系统#clustername#当前负载状态过高,可能存在宕机风险,请及时关注。建议使用管理系统-智能运维-云端运维功能分析当前系统存在的性能问题。

预警任务触发239【帆软软件】您好,预警任务#warningname#达到阈值被触发,请及时关注!模板路径:#templatePath#。
更新任务结束264【信息平台】更新任务「#job_name#」结束。任务开始于#year#年#month#月#day#日#hr_min#,累计耗时#c_hr#时#c_min#分#c_sec#秒,完成任务:基础表更新 #success_basetable#/#total_basetable# ,自助数据集更新 #success_dataset#/#total_dataset# , 关联更新 #success_relation#/#total_relation#。
报表系统已宕机265【信息平台】报表系统已宕机,请访问运维工具关注问题处理状态或及时进行系统重启。
报表系统宕机重启失败266【信息平台】报表系统已宕机,自动重启系统失败,请及时进行手动重启。
环境配置不合理269【信息平台】检查到系统环境配置存有不合理项,请及时查看并改正不合理项。
备份失败276【信息平台】你好,[#taskname#]备份失败,请及时处理,备份时间:#time#。
文件不一致且无法自动同步367【信息平台】集群节点#node_name#与基准节点存在不一致文件,且无法自动同步。请检查该节点状态。
文件不一致自动同步368【信息平台】集群节点#node_name#与基准节点存在不一致文件,已自动同步与基准节点一致,不一致文件备份在该节点工程WEB-INF/#directory#/下。
节点通信异常998【信息平台】节点#nodename1#与节点#nodename2#之间通信异常,无法加入节点管理,请检查集群节点间通信端口是否已开放[TCP:7800,7810, 7820,7830, 7840, 7850,7860,7870][UDP:45588~65536 随机端口]。
节点模块异常999【信息平台】节点#node_name#的#type#模块存在异常,暂无法正常提供服务,请及时对异常状况进行排查

八、常用链接

10.0 demo地址:demo-sms-provider

11.0 demo地址:https://code.fanruan.com/pioneer/demo-third-sms-v2

九、开源案例

免责声明:所有文档中的开源示例,均为开发者自行开发并提供。仅用于参考和学习使用,开发者和官方均无义务对开源案例所涉及的所有成果进行教学和指导。禁止用于任何商业用途,若作为商用一切后果责任由使用者自行承担。

open-JSD-8144

demo-third-sms

  • No labels