• Rule-Engine-Starter V1.0.0


    一个轻量级的规则引擎、搜索引擎,让条件匹配简单、优雅。


    GIT地址

    https://gitcode.cosmoplat.com/15011240224/rule-engine-starter

    介绍

    Rule-Engine-Starter 是一个轻量级规则引擎,V1.0.0主要解决条件匹配问题。比如飞书文档,每个文档都可以设置访问权限,可以限制哪些人、哪些部门可以访问、是否对互联网用户公开等等,这些条件可以看成每个文档设置的访问规则,一个文档可以设置多个规则。

    校验一个用户是否能访问目标文档,只需要校验规则中的条件,可以使用SPEL等表达式来实现;但是如果想获取一个用户有访问权限的所有文档,如果再用SPEL实现岂不是需要遍历所有文档的所有规则,这种方案无疑是低效的。因此自研 Rule-Engine-Starter 解决这个问题,只需要将用户的属性作为条件输入给规则引擎,规则引擎会快速返回所有匹配的规则:

    Rule-Engine-Starter 通过拉平条件和MySQL的B+Tree索引实现快速匹配。

    Demo

    访问地址:https://gitcode.cosmoplat.com/15011240224/rule-engine-demo

    修改数据库配置后,可本地执行com.cosmoplat.rule.RuleTest。

    使用

    1. MySQL初始化,执行src/main/sql/init.sql

    2. POM引入依赖和卡奥斯仓库

    <dependency>
       <groupId>com.cosmoplat.rule</groupId>
       <artifactId>rule-engine-starter</artifactId>
       <version>1.0.0</version>
    </dependency>
    
    <repository>
        <id>maven-public</id>
        <name>maven-public</name>
        <url>http://nexus.cosmoplat.com/repository/maven-public/</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 修改配置文件

      spring:
          datasource:
              url: jdbc:mysql://xxx.xxx.xxx.xxx:xxxxx/库名
              username: 用户名
              password: 密码
              driver-class-name: com.mysql.cj.jdbc.Driver
      
      # 启用规则引擎      
      rule:
          engine:
              enabled: true
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    2. 创建维度

      Dimension dimension = Dimension.builder().namespaceId(NAMESPACE_ID)
              .code(dimensionEnum.getCode())
              .description(dimensionEnum.getName()).build();
      ruleEngineService.createDimensions(Collections.singletonList(dimension));
      
      • 1
      • 2
      • 3
      • 4
    3. 创建分类

      List<String> dimension = Lists.newArrayList(DimensionEnum.WORK_NO.getCode(), 
               DimensionEnum.DEPT_NO.getCode());
      Type ruleType = Type.builder().code(DOC_READ_RULE_TYPE_CODE).description("文档阅读规则")
              .namespaceId(NAMESPACE_ID).dimensionCodes(dimension).build();
      ruleEngineService.createTypes(Lists.newArrayList(ruleType));
      
      • 1
      • 2
      • 3
      • 4
      • 5
    4. 添加规则

    String docId1= "11111";
    String docId2= "22222";
    String docId3= "33333";
    // 允许体验云和海云智造的员工阅读文档1
    createDocReadRule(docId1, Lists.newArrayList(ALL), Lists.newArrayList("tiYanYun", "haiyunzhizao"));
    // 只允许工号22038425阅读文档2
    createDocReadRule(docId2, Lists.newArrayList("22038425"), Lists.newArrayList(ALL));
    // 只允许工号77889998阅读文档3
    createDocReadRule(docId3, Lists.newArrayList("77889998"), Lists.newArrayList(ALL));
    
    
    private void createDocReadRule(String docId, List<String> workNos, List<String> deptNos) throws RuleConflictException {
        Package rule = new Package();
        rule.setNamespaceId(NAMESPACE_ID);
        rule.setTypeCode(DOC_READ_RULE_TYPE_CODE);
        rule.setName("文档阅读规则");
        rule.setCreateInfo();
        // 匹配结果
        rule.setConfigInfo(docId);
        // 规则条件
        Map<String, List<String>> searchKeyMap = Maps.newHashMap();
        searchKeyMap.put(DimensionEnum.WORK_NO.getCode(), workNos);
        searchKeyMap.put(DimensionEnum.DEPT_NO.getCode(), deptNos);
        ruleEngineService.createRule(rule, searchKeyMap);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    1. 规则匹配

      // 规则匹配,返回体验云员工22038425能访问的文档
      Map<String, List<String>> searchAndSortKeyMap = Maps.newHashMap();
      searchAndSortKeyMap.put(DimensionEnum.WORK_NO.getCode(), Lists.newArrayList( "22038425", ALL));
      searchAndSortKeyMap.put(DimensionEnum.DEPT_NO.getCode(), Lists.newArrayList("tiYanYun", ALL));
      List<MatchRuleResult<String>> ret = ruleEngineService.matchRule(NAMESPACE_ID,
           DOC_READ_RULE_TYPE_CODE, searchAndSortKeyMap, null);
      
      List<String> docIds = ret.stream().map(MatchRuleResult::getResult).collect(toList());
      Assert.isTrue(docIds.contains(docId1), "文档1不能阅读");
      Assert.isTrue(docIds.contains(docId2), "文档2不能阅读");
      Assert.isTrue(!docIds.contains(docId3), "文档3能阅读");
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    支持

    如果您觉得有用,麻烦您按照链接支持下:链接

  • 相关阅读:
    Apache Doris 2.1.2 版本正式发布!
    利用四元数进行蛋白质原子坐标旋转变换
    获取板块分类并展示
    Pod控制器详解-Horizontal Pod Autoscaler(HPA)
    2.如何使用Python官方文档
    图像超分经典网络 SRGAN 解析 ~ 如何把 GAN 运用在其他视觉任务上
    系统篇: linux 下实现 U 盘自动挂载
    Linux·驱动编译相关问题
    [附源码]计算机毕业设计在线项目管理Springboot程序
    【学习笔记】云原生初步
  • 原文地址:https://blog.csdn.net/zhouwenjun0820/article/details/133749598