
# 什么是服务编排管理
服务编排管理是工业数字模型驱动引擎-数据建模引擎（xDM Foundation，简称xDM-F）提供的高代码开发能力，旨在帮助应用开发人员通过编排原子API或脚本快速构建跨实体（表）的组合API。其核心价值在于提升应用开发的速度与质量，同时支持脚本正确性验证，降低开发风险。
#### 为什么需要服务编排管理
在企业应用开发过程中，业务逻辑往往涉及多个数据实体，开发人员需要频繁处理跨表查询与事务一致性保障。传统开发模式下，复杂逻辑的开发周期长、代码重复度高，且容易出现数据不一致问题。
如何在不牺牲质量的前提下快速构建复杂业务API？xDM-F的服务编排管理提供Java和JavaScript两种高代码编排能力，让开发人员能够组合原子服务形成复合API，从而高效实现跨实体业务封装与事务控制。
#### 服务编排管理的优势是什么
- **高代码灵活性**：支持Java、JavaScript两种开发语法，分别适配事务、复杂查询两类差异化业务。
- **跨实体组合能力**：支持将多个原子API或脚本编排为跨表组合API，简化多源数据关联开发流程。
- **脚本验证机制**：支持验证脚本的正确性或是否符合预期，确保业务逻辑准确执行 。
- **精细化权限控制**：支持通过"权限管理"自定义授权，实现精细化权限控制，满足业务安全需求 。
 
#### 服务编排管理的使用场景
- **场景一：跨对象复杂查询**
  应用开发人员在构建工业应用时，面临跨多个数据实体的复杂查询需求，需要整合分散在不同表中的业务数据。服务编排管理提供JavaScript编排能力，支持动态SQL构建与跨对象查询，以实现灵活的数据整合与快速开发。
  
- **场景二：事务一致性保障**
  开发团队在处理订单、库存等需要强事务一致性的核心业务时，需要确保多步骤操作的原子性。Java服务编排内置事务控制能力，支持编排涉及多表更新的业务逻辑，以保障数据一致性和业务可靠性。
  
- **场景三：精细化权限管控**
  企业运维人员在多租户环境中管理API开发权限时，需要对服务编排功能进行精细化授权。通过权限管理的自定义授权能力，管理员可控制特定团队访问服务编排功能，以实现安全的访问控制与合规管理。
  
 
#### 服务编排管理的分类
服务编排管理作为xDM-F的核心能力，通常可按脚本语言分为**Java类型** 和**JavaScript类型**两类。
- [Java服务编排](https://support.huaweicloud.com/usermanual-idme/idme_clientog_0123.html)：主要支持事务一致性处理和持久化操作，内置对xDM-F模型、Java集合类、包装类、正则表达式、时间类、JSON类、Lombok及GeneralCrudService的支持，适用于需要强事务保障的业务场景。
- [JavaScript服务编排](https://support.huaweicloud.com/usermanual-idme/idme_clientog_0124.html)：主要支持跨对象复杂查询和动态SQL构建，提供灵活的入参传递方式与特定字符转义规则，更适用于数据整合、条件筛选等灵活查询场景。
 
#### 与服务编排管理相关的操作和特性
- **开启服务编排配置** ：使用服务编排管理前，需在应用设计态的"应用中心 \> 应用配置"中开启"xdm.runtime.custom.enable"配置项。具体操作请参见[应用配置](https://support.huaweicloud.com/usermanual-idme/idme_usermanual_0134.html)。
- **基础操作（Java）** ：使用Java语言编排原子API与脚本，支持事务一致性处理及xDM-F模型操作。具体操作请参见[创建Java服务编排](https://support.huaweicloud.com/usermanual-idme/idme_clientog_0123.html)。
- **基础操作（JavaScript）** ：使用JavaScript语言编写动态SQL，支持跨对象复杂查询与多种入参传递方式。具体操作请参见[创建JavaScript服务编排](https://support.huaweicloud.com/usermanual-idme/idme_clientog_0124.html)。
- **自定义权限控制** ：默认情况下，所有用户均具有使用服务编排管理的权限。如果您希望只有授权的团队成员或部门成员才能访问和使用服务编排管理功能，您可以通过"权限管理 \> 授权 \> 服务编排"自定义授权，实现精细化权限控制以满足业务需求。更多权限相关信息请参见[权限管理](https://support.huaweicloud.com/usermanual-idme/idme_clientog_0262.html)。
 
#### 约束与限制
- 服务编排管理功能仅支持在唯一编码为"-1"的默认租户"basicTenant"下使用。
- "数据服务管理 \> 全量数据服务 \> 系统管理API \> 服务编排"的create、get、history、list_page、revise、saveas和update接口的"gray"参数已废弃，使用相关接口时无需配置此参数。
- Java服务编排不支持包含union all (with table_name as(select *的SQL语法。如需使用此语法，请使用JavaScript服务编排。
 
#### 编排内容限制
表1服务编排内容限制 
| 编排类型         | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
|:---|:---|
| Java类型       | 支持编排如下内容： - xDM-F的内置模型  - 用户自定义的数据模型  - Java集合类，例如Collection接口和Map接口  - Java包装类，例如Integer类、Byte类、Float类和Double类  - 正则表达式，例如Pattern类和Matcher类  - 时间相关类，例如java.util包下的java.util.Date和java.util.Calendar类  - JSON相关类，例如Jackson类库  - Lombok项目  - 持久化功能相关类，例如GeneralCrudService   |
| JavaScript类型 | - 不可转义：\`、'、;和"。  - 不可转义，但可在SQL中转换：{。 例如，有一条如下所示的SQL语句： ``` select 1 from tablename where name='{}' ``` 可在SQL中进行如下转换： ``` select 1 from tablename where name=chr(123)||'}' ```   - 可转义：(、)和\|。 例如，(转义成\\\\(，)转义成\\\\)，\|转义成\\\\\|。                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   
#### 入参定义差异
- **Java类型服务编排**
  Java类型的服务编排入参在服务开发中由用户自行定义。
  
- **JavaScript类型服务编排**
  JavaScript服务编排入参有两种方式：
  - 通过var request="";
    JavaScript服务编排要求在JavaScript脚本里面加var request="";，否则运行时会报错。服务编排内容如下：
    ```
    var request="";
    // 数值类型
    var tenantId=request.tenantId;
    //字符串类型
    var targetType=request.targetType;
    //数值类型
    var statusArray=request.statusArray;
    //JSON类型
    var userInfo=request.userInfo;
    var sql="select * from xdm_task where 1=1";
    // 数值类型的使用
    if( tenantId!=undefined && tenantId !=null ){
      sql += " and _tenantId="+tenantId;
    }
    // 字符串类型的使用
    if( targetType!=undefined && targetType !=null ){
      sql += " and targetType='"+targetType+"'";
    }
    // 数组类型的使用
    if( statusArray!=undefined && statusArray !=null ){
      sql +=" and status in (";
      for(var i=0;i<statusArray.length;i++){
        if(i !=statusArray.length-1){
          sql+="'"+statusArray[i]+"',";
        }else{
          sql+="'"+statusArray[i]+"')";
        }
      }
    }
    // JSON类型的使用
    if( userInfo!=undefined && userInfo !=null ){
      var creator=userInfo.creator;
      var modifier=userInfo.modifier;
      if( creator!=undefined && creator !=null ){
        sql += " and creator='"+creator+"'";
      }
      if( modifier!=undefined && modifier !=null ){
        sql += " and modifier='"+modifier+"'";
      }
    }
    ```
    1. 执行接口入参：
       ```
       {"params":{"tenantId":-1,"targetType":"UNITTYPE","statusArray":["SUCCESS","FAIL"],"userInfo":{"creator":"mary","modifier":"jack"}}}
       ```
       
    
    2. 获取SQL：
       ```
       select * from xdm_task where 1=1 and _tenantId=-1 and targetType='UNITTYPE' and status in('SUCCESS','FAIL') and creator='mary' and modifier='jack'
       ```
       
     
  
  - 通过
    如在JavaScript服务编排中写入了，在执行接口入参的JSON中会有对应的key，在运行JavaScript服务编排时，会将服务编排中的替换成入参中对应的key值。在入参中一定要有对应的key，否则服务编排中的不会被替换。
    
   
- **字符串类型服务编排**
  服务编排内容如下：
  ```
  var request="";var creator="";var sql="select * from xdm_task where creator='"+creator+"'";
  ```
  1. 执行接口入参：
     ```
     {"params":{}}
     ```
     ```
     {"params":{"creator":null}}
     ```
     
  
  2. 获取SQL：
     ```
     select * from xdm_task where creator=''
     ```
     ```
     select * from xdm_task where creator='null'
     ```
     
   
- **数值类型服务编排**
  服务编排内容如下：
  ```
  var request="";var tenantId=;var sql="select * from xdm_task where _tenantId="+tenantId;
  ```
  1. 执行接口入参：
     ```
     {"params":{"tenantId":-1}} 或者 {"params":{"tenantId":"-1"}}
     ```
     
  
  2. 获取SQL：
     ```
     select * from xdm_task where _tenantId=-1
     ```
     
   
- **数组类型服务编排**
  服务编排内容如下：
  ```
  var request="";
  var statusArray=;
  var sql="select * from xdm_task where 1=1";
  if( statusArray!=undefined && statusArray !=null ){
    sql +=" and status in (";
    for(var i=0;i<statusArray.length;i++){
      if(i !=statusArray.length-1){
        sql+="'"+statusArray[i]+"',";
      }else{
        sql+="'"+statusArray[i]+"')";
      }
    }
  }
  ```
  1. 执行接口入参：
     ```
     {"params":{"statusArray":"[\"SUCCESS\",\"FAIL\"]"}}  //入参类型：String类型
     {"params":{"statusArray":["SUCCESS","FAIL"]}}    //入参类型：数值类型
     ```
     
  
  2. 获取SQL：
     ```
     select * from xdm_task where 1=1 and status in ('SUCCESS','FAIL')
     ```
     
   
- **JSON类型服务编排**
  服务编排内容如下：
  ```
  var request="";
  var userInfo=;
  var sql="select * from xdm_task where 1=1"
  if( userInfo!=undefined && userInfo !=null ){
    var creator=userInfo.creator;
    var modifier=userInfo.modifier;
    if( creator!=undefined && creator !=null ){
      sql += " and creator='"+creator+"'";
    }
    if( modifier!=undefined && modifier !=null ){
      sql += " and modifier='"+modifier+"'";
    }
  }
  ```
  1. 执行接口入参：
     ```
     {"params":{"userInfo":{"creator":"mary","modifier":"jack"}}}  //入参类型：String类型
     {"params":{"userInfo":{"creator":"mary","modifier":"jack"}}}  //入参类型：JSON类型
     ```
     
  
  2. 获取SQL：
     ```
     select * from xdm_task where 1=1 and creator='mary' and modifier='jack'
     ```
     
   
 
