更新时间:2024-11-13 GMT+08:00
分享

自定义devspore-horizo插件

Devspore-Horizon是Devspore提供的一个组件,负责在metaBO(及其相关的 RO)操作前进行鉴权和认证,并处理metaBO变动后消息发送与审计等功能。配置horizon后,generator生成的项目的base module中repository中相关操作上会带有。
// 普通增删改查接口@Extension(operation = Operation.CREATE, name = "Project") 

// 用户自定义扩展接口@Extension(operation = Operation.CUSTOM, customMethod = "methodName", name = "Project")
表1 属性说明

参数名称

数据类型

描述

operation

Operation

操作类型。

  • CREATE:新增操作。
  • DELETE:删除操作。
  • UPDATE:更新操作。
  • VIEW:查询操作。
  • BATCH_CREATE:批量新增。
  • BATCH_UPDATE:批量更新。
  • BATCH_VIEW:批量查询。
  • BATCH_DELETE:批量删除。
  • CUSTOM:用户自定义操作。

customMethod

String

扩展API中定义的method对象,仅在operation为CUSTOM时有意义;此值会传递到DataEvent对应字段。

name

String

表示本次操作的metaBO或者RO(关系类型)的名称。

操作示例

  • 新增操作:此示例表示可对名为Order的metaBO新增操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
    * AddOrder Method
    *
    * @param order order
    * @return Order
    */
    @Extension(operation = Operation.CREATE, name = "Order")
    @Override
    public Order addOrder(Order order) {
    return orderRepository.saveSelective(order);
    } 
  • 批量新增操作:此示例表示可对名为Order的metaBO批量新增操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
     * AddOrders Method
     *
     * @param orderList orderList
     * @return List<Order>
     */
    @Extension(operation = Operation.BATCH_CREATE, name = "Order")
    @Override
    public List<Order> addOrders(List<Order> orderList) {
        return orderRepository.saveSelectiveAll(orderList);    
    }
  • 删除操作:此示例表示可对名为Order的metaBO删除操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
     * AddOrders Method
     *
     * @param orderList orderList
     * @return List<Order>
     */
    @Extension(operation = Operation.BATCH_CREATE, name = "Order")
    @Override
    public List<Order> addOrders(List<Order> orderList) {
        return orderRepository.saveSelectiveAll(orderList);
    }
  • 批量删除操作:此示例表示可对名为Order的metaBO批量删除操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
     * DeleteOrderByIds Method
     *
     * @param orderIds orderIds
     * @return Integer
     */
    @Extension(operation = Operation.BATCH_DELETE, name = "Order")
    @Override
    public Integer deleteOrderByIds(List<String> orderIds) {
        return orderRepository.deleteAllById(orderIds);    
    }
  • 更新操作:此示例表示可对名为Order的metaBO更新操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
     * DeleteOrderByIds Method
     *
     * @param orderIds orderIds
     * @return Integer
     */
    @Extension(operation = Operation.BATCH_DELETE, name = "Order")
    @Override
    public Integer deleteOrderByIds(List<String> orderIds) {
        return orderRepository.deleteAllById(orderIds);    
    }
  • 批量更新操作:此示例表示可对名为Order的metaBO批量更新操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
    * UpdateOrderByIds Method
    *
    * @param orderList orderList
    * @return List<Order>
    */
    @Extension(operation = Operation.BATCH_UPDATE, name = "Order")
    @Override
    public List<Order> updateOrderByIds(List<Order> orderList) {
        return orderRepository.updateByIds(orderList);    
    }
  • 查询操作:此示例表示可对名为Order的metaBO查询操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
     * GetOrderById Method
     *
     * @param orderId orderId
     * @return Order
     */
    @Extension(operation = Operation.VIEW, name = "Order")
    @Override
    public Order getOrderById(String orderId) {
        return orderRepository.findOrderById(orderId);    
    }
  • 批量查询操作:此示例表示可对名为Order的metaBO批量查询操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
     * GetOrders Method
     *
     * @param orderQo orderQo
     * @return PageInfo<Order>
     */
    @Extension(operation = Operation.BATCH_VIEW, name = "Order")
    @Override
    public PageInfo<Order> getOrders(OrderQo orderQo) {
        return orderRepository.findOrders(orderQo);    
    }
  • 自定义扩展API操作:此示例表示可对名为Order的metaBO中自定义扩展API“pay”操作做统一的操作前认证、鉴权,操作后消息发送、缓存更新、审计等。
    /**
     * pay
     *
     * @param payment payment
     * @param orderId orderId
     * @return OrderOrderDetailNested
     */
    @Extension(operation = Operation.CUSTOM, customMethod = "pay", name = "Order")
    @Override
    public OrderOrderDetailNested pay(Payment payment, String accountId, String orderId) {
        OrderOrderDetailNested orderOrderDetailNested = orderRepository.findOrderOrderDetailNested(accountId, orderId);
    
        ......
    
        return orderOrderDetailNested;
    }

实现horizon功能

您只要实现了相应接口,填写配置信息即可实现horizon功能。

horizon整体介绍中的架构图描述,horizon开放了两种插件entry插件和exit插件。其中统一认证和统一鉴权需要实现entry插件;而变更通知、更新缓存、统一审计、统一工作流需要实现exit插件。具体实现请参考以下步骤:

  1. 实现接口。

    • 实现entry插件

      devspore-horizon提供了抽象类Processor,用户需要继承这个抽象类,实现抽象方法doProcess(DataEvent event),把认证和鉴权的处理逻辑写到此方法体内。此方法返回值为boolean型。

      如果认证或者鉴权的逻辑失败,则返回false,责任链后续节点不再执行,整个请求返回不再执行;为true,则继续执行。

      Approver代码如下:
      public abstract class Processor {
          protected MetaDocument metaDoc;
      
          private String name;
      
          private Processor next;
      
          public Processor getNext() {
              return next;
          }
      
          public void setNext(Processor next) {
              this.next = next;
          }
      
          public boolean process(DataEvent dataEvent) throws PluginException {
              if (!doProcess(dataEvent)) {
                  return false;
              }
              if (null != next) {
                  return next.process(dataEvent);
              }
              return true;
          }
      
          public abstract boolean doProcess(DataEvent dataEvent) throws PluginException;
      
          public String getName() {
              return name;
          }
      }
      表2 DataEvent参数说明

      参数名称

      数据类型

      描述

      metaDocument

      MetaDocument

      服务的元数据对象。

      operation

      Operation

      资源操作类型,包含增删改查、批量增删改查,自定义等操作。

      customMethod

      String

      扩展API中定义的method对象,仅在operation为CUSTOM时候有意义。

      sourceName

      String

      操作的资源名称。

      argsMap

      Map

      用户自定义参数集合。

      id

      Object

      DataObject id。

      originDo

      Object

      api被调用前do对象(一般从数据库取出)。

      • new : 为null。
      • update(包含自定义状态修改动作CUSTOM): 修改前数据库中的原始对象。
      • delete: 删除前数据库中的原始对象。

      targetDo

      Object

      api想要设置的do对象的克隆对象(对其进行修改不会持久化)。

      • new : 需要创建的对象。
      • update(包含自定义状态修改动作CUSTOM): 需要修改到的对象。
      • delete:为null。

      methodName

      String

      @Extension注解所在原方法名。

      className

      String

      @Extension注解所在的类名。

      contextMap

      Map<String, Object>

      缓存上下文对象,由请求插件设置,并由响应插件读取,通常key是插件名称。

    • 实现exit插件

      devspore-horizon提供了接口Observer,用户需要实现这个接口的observe(DataEvent dataEvent)方法,把变更通知、更新缓存、统一审计、统一工作流的处理逻辑写到此方法体内即可。

      Observer代码如下:
      public interface Observer {
          // receive the BO changes
          void observe(DataEvent dataEvent) throws PluginException;
      }

  2. 完成接口实现之后,还需要填写配置信息。有关horizon的配置信息如下:

    • devspore.horizon.approvers
      实现的entry插件,插件必须注入到spring IOC容器,并提供bean id,赋值给devspore.horizon.processors配置项。devspore.horizon.processors配置项是个数组。horizon会读取数组中每个bean id,执行已实现的鉴权、认证等逻辑。
      devspore:
        horizon:
          processors: bean1,bean2 #多个插件以","分隔,多个插件按配置顺序执行。
    • devspore.horizon.observers
      devspore.horizon.observers配置项也是个数组。horizon会读取数组中每个bean id,执行已实现的消息发送、审计等逻辑。
      devspore:
        horizon:
          observers: bean1,bean2  #多个插件以","分隔,多个插件按配置顺序执行。

实现示例

  • entry插件
    • 继承抽象类Processor,实现doProcess接口,可定义多个插件。
    • 插件均需注册为bean。
      import com.huawei.devspore.horizon.DataEvent;
      import com.huawei.devspore.horizon.exception.PluginException;
      import com.huawei.devspore.horizon.processor.Processor;
      
      import org.springframework.stereotype.Component;
      
      /**
       * custom request plugin
       */
      @Component
      public class CustomRequestPlugin extends Processor {
          @Override
          public boolean doProcess(DataEvent dataEvent) throws PluginException {
              // do your code
              ........
              return true;
          }
      }
    • 多个插件以","分隔,多个插件按配置顺序执行。
      devspore:
        horizon:
          processors: defaultRequestPlugin,customRequestPlugin;
  • exit插件
    • 实现Observer接口中observer接口,可定义多个插件。
    • 插件均需注册为bean。
      import com.huawei.devspore.horizon.DataEvent;
      import com.huawei.devspore.horizon.exception.PluginException;
      import com.huawei.devspore.horizon.subscribe.Observer;
      
      import org.springframework.stereotype.Component;
      
      /**
       * custom response plugin
       */
      @Component
      public class CustomResponsePlugin implements Observer {
          @Override
          public void observe(DataEvent dataEvent) throws PluginException {
              // do your code
              ......
          }
      }
    • 配置文件中多个插件以","分隔,多个插件按配置顺序执行。
      devspore:
        horizon:
          observers: defaultResponsePlugin,customResponsePlugin

相关文档