
# 设置DIS通知策略
#### 功能说明
如果需要将OBS桶中对象变化的事件推送到DIS的事件通道中，可以调用此接口来配置DIS通知策略。接口是幂等的，如果桶上已存在相同策略内容，则返回成功，status code返回值为200；否则status code返回值为201。
融合桶不支持设置DIS通知策略。
#### 接口约束
- 需要使用IAM的角色与策略授权功能，增加Tenant Administrator权限后才能设置、获取、删除DIS通知策略。使用DIS消息通知需要使用IAM的角色与策略授权功能，创建对OBS云服务的委托，委托赋予的权限需为数据接入服务DIS的DIS User权限。
- 一个桶中最多同时配置10条DIS通知规则。
- 对于时延敏感（秒级）的业务，消息通知无法保证时延。
- 新创建的DIS通知将在5分钟之内生效。
- 一个桶的多条DIS通知规则不允许重复，即任意对象在发生任意事件时都不能同时匹配两条以上的DIS通知规则，重复规则会创建失败。
  ![](https://support.huaweicloud.com/sdk-go-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
  针对同一事件，如果配置了一条前后缀都为空的规则，则不允许再配置第二条规则。前后缀都为空表示对所有对象生效。
  例如：针对Put事件，已存在一条规则A，定义的前缀是"abcd"，后缀是".txt"。如果要创建另外一条针对Put事件的规则B，则规则B配置不同前后缀的结果如[表1]所示。
   表1规则B前后缀配置场景及结果 
  | 规则A前后缀配置                                                                                          | 规则B前后缀配置                                                                                            | 规则B创建结果 | 原因            |
  |:---|:---|:---|:---|
  | 前缀：abcd 后缀：.txt | 前缀：abcd 后缀：.txt   | 失败      | 前后缀相同         |
  | 前缀：abcd 后缀：.txt | 前缀：abcd 后缀：空      | 失败      | 前缀相同，后缀B包含A   |
  | 前缀：abcd 后缀：.txt | 前缀：ab 后缀：xt         | 失败      | 前缀B包含A，后缀B包含A |
  | 前缀：abcd 后缀：.txt | 前缀：abef 后缀：.txt | 成功      | 前缀不同，后缀相同     |
  | 前缀：abcd 后缀：.txt | 前缀：abcd 后缀：.mp4    | 成功      | 前缀相同，后缀不同     |
     
  
 
#### 授权信息
您必须是拥有**Tenant Administrator** 权限，才能调用本接口。配置Tenant Administrator权限，需要使用**角色与策略授权** （旧版IAM，即IAM v3接口），授权操作请参考[使用IAM授权](https://support.huaweicloud.com/qs-iam/iam_01_0030.html)。
#### 方法定义
func (obsClient ObsClient) SetDisPolicy(input \*SetDisPolicyInput, extensions ...extensionOptions) (output \*BaseModel, err error)
#### 请求参数说明
表2请求参数说明 
| 参数         | 类型     | 必填 | 说明                                         |
|:---|:---|:---|:---|
| bucketName | string | 是  | **参数解释：** 桶名。 |
   
#### 响应参数说明
表3GetDisPolicyOutput参数说明 
| 字段        | 类型                | 说明                                                                                                                                                                                                         |
|:---|:---|:---|
| BaseModel | BaseModel         | **参数解释：** 基础模型，包含 RequestId 等。                                                                                                                                              |
| Rules     | \[\]DisPolicyRule | DIS 策略规则列表 **约束限制：** 同一个桶下的不同策略前缀不能重复和起始包含，委托建议使用同一个 **取值范围：** 数组大小的取值范围为\[1, 10\] |
   
表4DisPolicyRule参数说明 
| 字段      | 类型         | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
|:---|:---|:---|
| ID      | string     | 规则 ID **取值范围：** \[1, 256\]，满足"\^\[a-zA-Z0-9_-\]{1, 256}$"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Stream  | string     | DIS服务通道名称。 需要先在DIS服务创建此通道                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Project | string     | DIS服务通道所属的项目ID                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Events  | \[\]string | OBS事件列表 有效值：长度\[0, 1023\]，值允许为任意字符，支持如下事件类型： - ObjectCreated:\* （所有上传操作）  - ObjectCreated:Put （上传对象）  - ObjectCreated:Post （使用浏览器上传对象）  - ObjectCreated:Copy （拷贝对象）  - ObjectCreated:CompleteMultipartUpload （合并段）  - ObjectRemoved:\* （所有删除操作）  - ObjectRemoved:Delete （指定对象版本号删除对象）  - ObjectRemoved:DeleteMarkerCreated （不指定对象版本号删除对象）   |
| Prefix  | string     | 对象名前缀，用于指定的对象名关键字，根据定义的前缀，输入需要过滤的对象的关键字信息，字符越长匹配精度越高，最大可支持1024个字符，最小可为空。同时，prefix和suffix加起来长度最大为1024个字符                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Suffix  | string     | 对象名后缀。用于指定的对象名关键字，根据定义的后缀，输入需要过滤的对象的关键字信息，字符越长匹配精度越高，最大可支持1024个字符，最小可为空。同时，prefix和suffix加起来长度最大为1024个字符                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Agency  | string     | IAM委托名，被委托方必须包含OBS服务，赋予的权限必须是DIS服务的DIS Administrator或DIS User                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   
#### 代码示例
**示例1**-为桶examplebucket创建DIS通知策略，将所有对象上传和删除的事件通知到名称为my-dis-stream的DIS通道中（在DIS云服务中可以购买查看）。
```
package main
import (
    "fmt"
    obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
    "log"
    "os"
)
func main() {
    // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    // 您可以登录访问管理控制台获取访问密钥AK/SK。
    ak := os.Getenv("AccessKeyID")
    sk := os.Getenv("SecretAccessKey")
    // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。
    securityToken := os.Getenv("SecurityToken")
    // endpoint填写Bucket对应的Endpoint，这里以华北-北京四为例，其他地区请按实际情况填写。
    endPoint := "https://obs.cn-north-4.myhuaweicloud.com"
    // 创建客户端
    obsClient, err := obs.New(ak, sk, endPoint, obs.WithSecurityToken(securityToken))
    if err != nil {
        fmt.Printf("Create obsClient error, errMsg: %s", err.Error())
    }
    // 设置 DIS 策略
    input := &obs.SetDisPolicyInput{
        Bucket: "examplebucket",
        Rules: []obs.DisPolicyRule{
            {
                ID:      "dis-rule-01",
                Stream:  "my-dis-stream",
                Project: "project-id-12345",
                Events: []string{
                    "ObjectCreated:*",
                    "ObjectRemoved:*",
                },
                Agency: "obs_dis_agency",
            },
        },
    }
    output, err := obsClient.SetDisPolicy(input)
    if err != nil {
        log.Fatalf("Failed to set DIS policy: %v", err)
    }
    fmt.Printf("Request ID: %s\n", output.RequestId)
    fmt.Println("DIS policy set successfully")
}
```
**示例2**-桶examplebucket同时创建多条DIS通知策略，分别是监控桶上前缀为upload/的对象创建事件和后缀为.log的删除事件，事件推送到名称为my-dis-stream的DIS通道中（在DIS云服务中可以购买查看）。
```
package main
import (
    "fmt"
    obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
    "log"
    "os"
)
func main() {
    // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    // 您可以登录访问管理控制台获取访问密钥AK/SK。
    ak := os.Getenv("AccessKeyID")
    sk := os.Getenv("SecretAccessKey")
    // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。
    securityToken := os.Getenv("SecurityToken")
    // endpoint填写Bucket对应的Endpoint，这里以华北-北京四为例，其他地区请按实际情况填写。
    endPoint := "https://obs.cn-north-4.myhuaweicloud.com"
    // 创建客户端
    obsClient, err := obs.New(ak, sk, endPoint, obs.WithSecurityToken(securityToken))
    if err != nil {
        fmt.Printf("Create obsClient error, errMsg: %s", err.Error())
    }
    // 设置多规则 DIS 策略
    input := &obs.SetDisPolicyInput{
        Bucket: "examplebucket",
        Rules: []obs.DisPolicyRule{
            {
                ID:      "create-rule",
                Stream:  "my-dis-stream",
                Project: "project-id-12345",
                Events: []string{
                    "ObjectCreated:*",
                },
                Prefix: "upload/",
                Agency: "obs_dis_agency",
            },
            {
                ID:      "delete-rule",
                Stream:  "my-dis-stream",
                Project: "project-id-12345",
                Events: []string{
                    "ObjectRemoved:*",
                },
                Suffix: ".log",
                Agency: "obs_dis_agency",
            },
        },
    }
    output, err := obsClient.SetDisPolicy(input)
    if err != nil {
        log.Fatalf("Failed to set multi-rule DIS policy: %v", err)
    }
    fmt.Printf("Request ID: %s\n", output.RequestId)
    fmt.Printf("Configured %d rules\n", len(input.Rules))
    fmt.Println("Multi-rule DIS policy set successfully")
}
```
**示例3**-删除桶examplebucket上多条DIS策略中rule id为rule-001的策略。
```
package main
import (
    "fmt"
    obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
    "log"
    "os"
)
func main() {
    // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    // 您可以登录访问管理控制台获取访问密钥AK/SK。
    ak := os.Getenv("AccessKeyID")
    sk := os.Getenv("SecretAccessKey")
    // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。
    securityToken := os.Getenv("SecurityToken")
    // endpoint填写Bucket对应的Endpoint，这里以华北-北京四为例，其他地区请按实际情况填写。
    endPoint := "https://obs.cn-north-4.myhuaweicloud.com"
    // 创建客户端
    obsClient, err := obs.New(ak, sk, endPoint, obs.WithSecurityToken(securityToken))
    if err != nil {
        fmt.Printf("Create obsClient error, errMsg: %s", err.Error())
    }
    bucketName := "examplebucket"
    idsToDelete := []string{"rule-001"}
    // 步骤 1：获取当前策略
    currentPolicy, err := obsClient.GetDisPolicy(bucketName)
    if err != nil {
        log.Fatalf("获取 DIS 策略失败: %v", err)
    }
    fmt.Printf("当前规则数量: %d\n", len(currentPolicy.Rules))
    // 步骤 2：构建要删除的 ID 映射
    idMap := make(map[string]bool)
    for _, id := range idsToDelete {
        idMap[id] = true
    }
    // 步骤 3：从规则列表中移除要删除的规则
    var updatedRules []obs.DisPolicyRule
    for _, rule := range currentPolicy.Rules {
        if !idMap[rule.ID] {
            updatedRules = append(updatedRules, rule)
        }
    }
    // 步骤 4：重新设置策略
    setInput := &obs.SetDisPolicyInput{
        Bucket: bucketName,
        Rules:  updatedRules,
    }
    _, err = obsClient.SetDisPolicy(setInput)
    if err != nil {
        log.Fatalf("设置新策略失败: %v", err)
    }
    fmt.Printf("成功删除 %d 条规则! 剩余规则数量: %d\n", len(idsToDelete), len(updatedRules))
}
```
**示例4**-在桶examplebucket上，已经配置过DIS策略的情况下，再添加一条DIS策略。
```
package main
import (
    "fmt"
    obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
    "log"
    "os"
)
func main() {
    // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    // 您可以登录访问管理控制台获取访问密钥AK/SK。
    ak := os.Getenv("AccessKeyID")
    sk := os.Getenv("SecretAccessKey")
    // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。
    securityToken := os.Getenv("SecurityToken")
    // endpoint填写Bucket对应的Endpoint，这里以华北-北京四为例，其他地区请按实际情况填写。
    endPoint := "https://obs.cn-north-4.myhuaweicloud.com"
    // 创建客户端
    obsClient, err := obs.New(ak, sk, endPoint, obs.WithSecurityToken(securityToken))
    if err != nil {
        fmt.Printf("Create obsClient error, errMsg: %s", err.Error())
    }
    bucket := "examplebucket"
    projectId := "project-id-12345"
    // 1. 先清掉桶上现有 DIS 策略,保证干净起点
    obsClient.DeleteDisPolicy(bucket)
    // 2. 设一条基础规则(带 prefix "base-", 唯一 ID)
    baseInput := &obs.SetDisPolicyInput{
        Bucket: bucket,
        Rules: []obs.DisPolicyRule{{
            ID:      "base-rule-01",
            Stream:  "my-dis-stream",
            Project: projectId,
            Events:  []string{"ObjectCreated:*"},
            Prefix:  "base-",
            Agency:  "dis-agency",
        }},
    }
    if _, err := obsClient.SetDisPolicy(baseInput); err != nil {
        log.Fatalf("set base rule failed: %v", err)
    }
    fmt.Println("base rule set")
    // 3. 获取现有策略
    output, err := obsClient.GetDisPolicy(bucket)
    if err != nil {
        log.Fatalf("get dis policy failed: %v", err)
    }
    fmt.Printf("StatusCode: %d\n", output.StatusCode)
    fmt.Printf("current rules: %d\n", len(output.Rules))
    // 4. 追加一条新规则(不同 prefix "new-", 唯一 ID, 避免冲突)
    newRules := append(output.Rules, obs.DisPolicyRule{
        ID:      "new-rule-02",
        Stream:  "my-dis-stream",
        Project: projectId,
        Events:  []string{"ObjectRemoved:*"},
        Prefix:  "new-",
        Agency:  "dis-agency",
    })
    // 5. 更新策略(原有 + 新追加)
    updateInput := &obs.SetDisPolicyInput{
        Bucket: bucket,
        Rules:  newRules,
    }
    updateOutput, err := obsClient.SetDisPolicy(updateInput)
    if err != nil {
        log.Fatalf("Failed to update DIS policy: %v", err)
    }
    fmt.Printf("update StatusCode: %d\n", updateOutput.StatusCode)
    fmt.Printf("Request ID: %s\n", updateOutput.RequestId)
    fmt.Println("DIS policy updated successfully (appended new rule)")
}
```
#### 相关链接
DIS通知接口返回的错误码含义、问题原因及处理措施可参考[OBS错误码](https://support.huaweicloud.com/api-obs/obs_04_0115.html#section1)。
