diff --git a/CHANGELOG.md b/CHANGELOG.md index df020d2cb..0bd4cc753 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,37 +1,46 @@ # Changelog -## 7.16.0(2024-09-12) + +## 7.16.0 (2024-09-12) + * 支持闲时任务 * 移除已下线区域相关域名 -## 7.15.1(2024-05-29) +## 7.15.1 (2024-05-29) + * 处理在构造 Download URL 时 Key 前缀为 / 的情况 -## 7.15.0(2023-12-25) +## 7.15.0 (2023-12-25) + * 区域缓存支持磁盘缓存 * 提供快速生成公有云的区域实例的方法 * batch 操作接口增强 * 支持归档直读 -## 7.14.0(2023-07-18) +## 7.14.0 (2023-07-18) + * Region 移除亚太首尔区域 * BucketManager 的部分 Bucket 级别接口支持主备重试 -## 7.13.1(2023-05-25) +## 7.13.1 (2023-05-25) + * 优化 BucketManager 的 getBucketQuota 方法 * 废弃 pu.qbox.me 域名 * 废弃 BucketManager 的 listFilesV2 方法 * PlayExpire -## 7.13.0(2023-03-30) +## 7.13.0 (2023-03-30) + * Client 开放 head 请求方法 * BatchOperations 增加 size() 方法 * BucketManager 支持获取源站域名 -## 7.12.1(2022-12-07) +## 7.12.1 (2022-12-07) + * uc query 增加全局缓存 * 处理分片 v2 块大小设置无效问题 -## 7.12.0(2022-10-25) +## 7.12.0 (2022-10-25) + * 增加亚太-首尔区域固定 Region * 移除雾存储区域:华东一区 * 升级 gson 版本至 2.8.9 @@ -39,61 +48,78 @@ * 优化私有云使用姿势,不再单独配置 rs api uc域名 * 优化分片上传 ctx 超时检测 -## 7.11.0(2022-06-08) -* 对象存储,管理类 API 发送请求时增加 [X-Qiniu-Date](https://developer.qiniu.com/kodo/3924/common-request-headers) (生成请求的时间) header +## 7.11.0 (2022-06-08) + +* 对象存储,管理类 API 发送请求时增加 [X-Qiniu-Date](https://developer.qiniu.com/kodo/3924/common-request-headers) + (生成请求的时间) header ## 7.10.4 (2022-05-27) + * 添加查询单个短信模板接口 ## 7.10.3 (2022-05-19) + * 支持非 UTF-8 环境变量 -* QVS修复中文前缀列举问题 +* QVS修复中文前缀列举问题 ## 7.10.2 (2022-04-28) + * RTC模块提供V4版本合流接口 ## 7.10.1 (2022-04-25) + * 对象存储,补充 stat api 可查看对象元数据信息 -## 7.10.0 (2022-04-15) -* 对象存储,新增支持 [深度归档存储类型](https://developer.qiniu.com/kodo/3956/kodo-category#deep_archive) +## 7.10.0 (2022-04-15) +* 对象存储,新增支持 [深度归档存储类型](https://developer.qiniu.com/kodo/3956/kodo-category#deep_archive) ## 7.9.5 (2022-03-28) ## 修复 + ### QRTC + * 服务端支持全量覆盖,合流支持z参数, strechMode使用枚举 ## 7.9.4 (2022-03-15) ## 修复 + ### 对象存储 + * 修复大于 2G 的文件上传失败问题 * 实现了 Qiniu 签名,并替换所有管理 API 的签名方式为 [Qiniu 签名](https://developer.qiniu.com/kodo/1201/access-token) ## 7.9.3 (2022-01-27) ### 对象存储 + * 增加内置华东-浙江2 区域域名信息 ## 7.9.2 (2021-12-30) ## 修复 + ### QRTC + * qvs修复创建设备的Bug ## 7.9.1 (2021-12-20) ## 增加 + ### QRTC相关 -* 新增语音对讲 + +* 新增语音对讲 * 新增平台设备类型 ## 7.9.0 (2021-12-10) ## 增加 + ### QRTC相关 + * 添加APP级别管理接口 * 添加ROOM级别管理接口 * 添加QRTC回调设定接口 @@ -103,31 +129,35 @@ ## 7.8.0 (2021-06-22) ## 增加 + * 支持批量解冻归档 ## 7.7.0 (2021-05-28) ## 增加 + * 支持跨区域双活上传,提供区域级别上传故障情况下上传可用性保障,跨区域双活功能需要工单申请开通 ## 7.6.0 (2021-04-29) ## 增加 + * 上传每个服务端 API 对应基础上传数据 API 支持流式数据 InputStream * 提供更友好的构建 DownloadUrl 能力 - ## 7.5.0 (2021-04-15) ## 增加 + * 新增上传服务基础 api * 新增分片上传 v2 功能 - ## 7.4.0 (2020-11-25) ## 增加 + [QVS相关](https://developer.qiniu.io/qvs/api/6706/summary-of-the-api) + * 新增录制管理相关api * 新增数据统计管理相关api * 流管理api增加按需截图,删除截图 @@ -137,15 +167,16 @@ * 增加相关单元测试并测试通过 * 新增PTZ云台控制相关接口和单测 - -## 7.3.0(2020-09-11) +## 7.3.0 (2020-09-11) ## 新增 + * 新增流管理停止流的功能 * 新增设备管理模块的功能 * 增加空间管理的部分参数 ## 修改 + * 修复部分已知问题 * 去除查询推流历史记录接口 start 和 end 的非法检查,由服务端判断 @@ -158,89 +189,122 @@ ## 修改 -* 修复 Client 的 duration +* 修复 Client 的 duration ## 7.2.28 (2019-12-09) ## 增加 + * Client 增加 setAppName 方法,ua 包含设置的名称 + ## 修改 + * 修复 listFilesV2 空指针问题 * 修改 cdn 刷新、预取数量限制,和文档一致 ## 7.2.27 (2019-10-22) + ## 增加 + * SMS 功能增加三个接口 ## 7.2.25 (2019-08-23) + ## 修改 + * 修正 7.2.24 引入的问题: java.net.UnknownHostException: https ## 7.2.24 (2019-08-21) + ## 增加 + * 支持 Region + ## 修改 + * okhttp3 改为 3.14.2, 其要求 java 要求 1.8; * 若 java 必须为 1.7, 可指定依赖 3.12.3 - ## 7.2.23 (2019-07-01) + ## 增加 + * SMS 功能支持 ## 7.2.18 (2018-12-17) + ## 修正 + * 分片上传重试添加 crc32 校验 * pili stream 管理,参数 json 格式 ## 7.2.15 (2018-09-10) + ## 移除内部鉴权打印 ## 7.2.12 (2018-05-09) + ## 增加 + * 增加连麦Rtc功能 ## 7.2.11 (2018-03-01) + ## 增加 + * 增加新加坡机房的支持,新机房上线 ## 7.2.10 (2018-01-30) + ## 增加 + * 增加changeHeaders方法用来支持资源相应头部修改 * 移除travis里面jdk7的配置,因为现在travis不再支持jdk7 ## 7.2.9 (2017-12-29) + ### 修正 + * 部分类、方法的可访问权限 * okhttp 从 3.3.1 升级到 3.9.1 * gson 从 2.6.2 升级到 2.8.2 ## 7.2.8 (2017-10-18) + ### 增加 + * 开放空间和域名列表域名的设置接口,以适应私有云定制 * 为Response增加close的方法 * 增加ChangeType方法用来设置资源存储类型 * 默认开启表单上传的CRC32校验功能避免网络内容劫持 ### 修正 + * 修复获取流历史记录的参数错误 * 移除查询处理进度的域名前缀 ## 7.2.7 (2017-07-10) + ### 增加 + * PutPolicy里面增加 isPrefixalScope 参数 ### 修正 + * 修复put方法遇到InputStream为0的时候进入死循环的问题 * 修复put方法遇到IputStream的时候,出现的block's crc32 is not correct的问题 ## 7.2.6 (2017-03-23) + ### 修正 + * 删除v1版本的access token签名中对application/json的body的签名 * 更新qetag中关闭File对象生成的InputStream对象 ## 7.2.5 (2017-02-20) + ### 增加 + * 批量修改mimeType的操作 * 批量操作的结果内容丰富 * 开放Zone.Builder用于私有环境自定义域名 @@ -250,122 +314,156 @@ * 添加deleteAfterDays接口用来设置文件生存时间 ### 修正 + * 代码的格式化风格 ## 7.2.4 (2017-02-07) + ### 增加 + * 北美机房的上传,转码测试用例 * 持久化处理的结果查询方法 ### 修正 + * 默认不设置autoZone的情况下,自动判断zone * zone和autoZone的代码结构优化 ## 7.2.3 (2017-01-11) + ### 增加 + * CDN url 预取 * 获取带宽、流量数据 * 获取日志列表 * 时间戳防盗链签名 ### 修正 + * ETag 大文件块计算整数溢出问题 * autoZone 不支持rs、rsf等问题 * 不能设置使用 https 的问题 ## 7.2.2 (2016-11-04) + ### 增加 + * stream 方式上传 ## 7.2.1 (2016-11-03) + ### 修正 + * streaming publish url 过期时间单位问题 ## 7.2.0 (2016-11-02) + ### 增加 + * 为多存储区 增加 autozone, zone2 * 整合 cdn 刷新 * 整合 streaming 服务端SDK ## 7.1.3 (2016-09-02) + ### 增加 + * 下载方法 * 支持x:foo变量 * batch 增加force * host first ## 7.1.2 (2016-07-14) + ### 增加 + * 内部dns 解析支持 * proxy 支持 -* add String[] commonPrefixes in FileListing +* add String[] commonPrefixes in FileListing ## 7.1.1 (2016-06-27) + ### 修正 + * 断点上传,skip 已上传部分 ## 7.1.0 (2016-04-27) + ### 增加 + * 升级到okhttp3, 升级次版本号。 ## 7.0.9 (2016-04-22) + ### 增加 + * 强制copy或者move ## 7.0.8 (2016-01-05) ### 修正 + * 添加写超时时间,避免okhttp 2.7 上传大文件失败 ## 7.0.7 (2015-11-13) ### 修正 + * invalid multipart format: multipart: message too large ## 7.0.6 (2015-10-30) ### 修正 + * 断点续上传 读取本地持久化记录偏移问题 * form 及 断点上传 fname 改为 本地文件名 ## 7.0.5 (2015-10-08) ### 修正 + * 调大连接池,提高并发性能 * 超时单位设置 ### 增加 + * 增加data的异步上传 ## 7.0.4.2 (2015-09-22) ### 修正 + * 跟据reqid 判断服务器是否为七牛的 ## 7.0.4.1 (2015-08-27) ### 修正 + * okhttp 2.4 兼容问题 ## 7.0.4 (2015-06-25) ### 变更 + * 多zone 支持 ## 7.0.3 (2015-05-04) ### 修正 + * post在无body情况下变成了get。 ## 7.0.2 (2015-04-15) ### 增加 + * fetch 返回key * 增加上传断点记录持久化 ## 7.0.0 (2015-02-03) ### 增加 + * 简化上传接口 * 自动选择断点续上传还是直传 * 重构代码,接口和内部结构更清晰 diff --git a/README.md b/README.md index ef768fbda..50c93a442 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Qiniu Resource Storage SDK for Java + [![@qiniu on weibo](http://img.shields.io/badge/weibo-%40qiniutek-blue.svg)](http://weibo.com/qiniutek) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) [![Build Status](https://travis-ci.org/qiniu/java-sdk.svg)](https://travis-ci.org/qiniu/java-sdk) @@ -6,9 +7,11 @@ [![Docs](https://img.shields.io/github/v/tag/qiniu/java-sdk.svg?label=docs&color=yellow)](https://qiniu.github.io/java-sdk/) [![Coverage Status](https://codecov.io/gh/qiniu/java-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/qiniu/java-sdk) [![Latest Stable Version](https://img.shields.io/maven-central/v/com.qiniu/qiniu-java-sdk.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.qiniu%22%20AND%20a%3A%22qiniu-java-sdk%22) + ## 安装 下载 [the latest JAR][1] 或者 通过 Maven: + ```xml com.qiniu @@ -16,7 +19,9 @@ [7.16.0, 7.16.99] ``` + 或者 Gradle: + ```groovy implementation 'com.qiniu:qiniu-java-sdk:7.16.+' ``` @@ -28,6 +33,7 @@ JDK 7 及以上 ## 使用方法 ### 上传 + ```Java // 分片上传 v1 import com.qiniu.storage.UploadManager; @@ -73,6 +79,7 @@ $ ./gradlew build ``` ## 生成Eclipse工程文件 + ``` bash $ ./gradlew gen_eclipse ``` @@ -105,6 +112,9 @@ $ ./gradlew gen_eclipse The MIT License (MIT).详情见 [License文件](https://github.com/qiniu/java-sdk/blob/master/LICENSE). [1]: https://search.maven.org/remote_content?g=com.qiniu&a=qiniu-java-sdk&v=LATEST + [2]: https://github.com/Nextpeer/okhttp + [3]: https://raw.githubusercontent.com/qiniu/java-sdk/master/libs/okhttp-2.3.0-SNAPSHOT.jar + [4]: https://raw.githubusercontent.com/qiniu/java-sdk/master/libs/okio-1.3.0-SNAPSHOT.jar diff --git a/build.gradle b/build.gradle index 69c0e00ed..049ffe1f4 100755 --- a/build.gradle +++ b/build.gradle @@ -51,14 +51,14 @@ task getHomeDir { apply plugin: 'checkstyle' task apiJavadocs(type: Javadoc) { - source = sourceSets.main.allJava - classpath = sourceSets.main.runtimeClasspath - title = "七牛 Java SDK API 文档" - options { - memberLevel = JavadocMemberLevel.PUBLIC - setEncoding 'UTF-8' - setWindowTitle "七牛 Java SDK API 文档" - } + source = sourceSets.main.allJava + classpath = sourceSets.main.runtimeClasspath + title = "七牛 Java SDK API 文档" + options { + memberLevel = JavadocMemberLevel.PUBLIC + setEncoding 'UTF-8' + setWindowTitle "七牛 Java SDK API 文档" + } } def versionName() { diff --git a/code-gen/go.mod b/code-gen/go.mod new file mode 100644 index 000000000..dfd876cca --- /dev/null +++ b/code-gen/go.mod @@ -0,0 +1,19 @@ +module github.com/YangSen-qn/code-gen + +require ( + github.com/getkin/kin-openapi v0.124.0 + github.com/iancoleman/strcase v0.3.0 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/swag v0.22.8 // indirect + github.com/invopop/yaml v0.2.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect +) + +go 1.21.8 diff --git a/code-gen/src/api_desc.go b/code-gen/src/api_desc.go new file mode 100644 index 000000000..06ab7d0f9 --- /dev/null +++ b/code-gen/src/api_desc.go @@ -0,0 +1 @@ +package main diff --git a/code-gen/src/apidesc/api.go b/code-gen/src/apidesc/api.go new file mode 100644 index 000000000..10e119188 --- /dev/null +++ b/code-gen/src/apidesc/api.go @@ -0,0 +1,16 @@ +package apidesc + +type ApiDetailedDescription struct { + Documentation string `yaml:"documentation,omitempty"` // API 文档 + PackageName string `yaml:"package_name,omitempty"` // 包名,文件路径中提取 + Name string `yaml:"name,omitempty"` // API 名称,文件名 + CamelCaseName string `yaml:"camel_case_name,omitempty"` // 驼峰命名 + SnakeCaseName string `yaml:"snake_case_name,omitempty"` // 蛇形命名:特指下划线命名 + Method MethodName `yaml:"method,omitempty"` // HTTP 方法 + ServiceNames []ServiceName `yaml:"service_names,omitempty"` // 七牛服务名称 + Command string `yaml:"command,omitempty"` // URL 查询命令 + BasePath string `yaml:"base_path,omitempty"` // URL 基础路径 + PathSuffix string `yaml:"path_suffix,omitempty"` // URL 路径后缀 + Request ApiRequestDescription `yaml:"request,omitempty"` // 请求参数 + Response ApiResponseDescription `yaml:"response,omitempty"` // 响应参数 +} diff --git a/code-gen/src/apidesc/body_json.go b/code-gen/src/apidesc/body_json.go new file mode 100644 index 000000000..c68d04456 --- /dev/null +++ b/code-gen/src/apidesc/body_json.go @@ -0,0 +1,82 @@ +package apidesc + +import ( + "fmt" + + "gopkg.in/yaml.v3" +) + +type ( + JsonType struct { + String bool `yaml:"string,omitempty"` // 字符串 + Integer bool `yaml:"integer,omitempty"` // 整型数字 + Float bool `yaml:"float,omitempty"` // 浮点型数字 + Boolean bool `yaml:"boolean,omitempty"` // 布尔值 + Array *JsonArray `yaml:"array,omitempty"` // 数组 + Struct *JsonStruct `yaml:"struct,omitempty"` // 结构体 + Any bool `yaml:"any,omitempty"` // 任意数据结构 + StringMap bool `yaml:"string_map,omitempty"` // 任意字符串映射结构 + } + + JsonArray struct { + Documentation string `yaml:"documentation,omitempty"` // JSON 数组参数文档 + Name string `yaml:"name,omitempty"` // JSON 数组名称 + CamelCaseName string `yaml:"camel_case_name,omitempty"` // JSON 数组驼峰命名 + SnakeCaseName string `yaml:"snake_case_name,omitempty"` // JSON 数组下划线命名 + Type *JsonType `yaml:"type,omitempty"` // JSON 数组类型 + } + + JsonStruct struct { + Documentation string `yaml:"documentation,omitempty"` // JSON 结构体参数文档 + Name string `yaml:"name,omitempty"` // JSON 结构体名称 + CamelCaseName string `yaml:"camel_case_name,omitempty"` // JSON 结构体驼峰命名 + SnakeCaseName string `yaml:"snake_case_name,omitempty"` // JSON 结构体下划线命名 + Fields []JsonField `yaml:"fields,omitempty"` // JSON 字段列表 + } + + JsonField struct { + Documentation string `yaml:"documentation,omitempty"` // JSON 字段参数文档 + Key string `yaml:"key,omitempty"` // JSON 字段参数名称 + FieldName string `yaml:"field_name,omitempty"` // JSON 字段名称 + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // JSON 字段驼峰命名 + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // JSON 字段下划线命名 + Type JsonType `yaml:"type,omitempty"` // JSON 字段类型 + Optional *OptionalType `yaml:"optional,omitempty"` // JSON 字段是否可选,如果为空,则表示必填 + ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // JSON 字段是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式 + ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // JSON 字段是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式 + } +) + +func (jsonType *JsonType) UnmarshalYAML(value *yaml.Node) error { + switch value.ShortTag() { + case "!!str": + switch value.Value { + case "string": + jsonType.String = true + case "integer": + jsonType.Integer = true + case "float": + jsonType.Float = true + case "boolean": + jsonType.Boolean = true + case "any": + jsonType.Any = true + case "string_map": + jsonType.StringMap = true + default: + return fmt.Errorf("unknown json type: %s", value.Value) + } + return nil + case "!!map": + switch value.Content[0].Value { + case "array": + return value.Content[1].Decode(&jsonType.Array) + case "struct": + return value.Content[1].Decode(&jsonType.Struct) + default: + return fmt.Errorf("unknown json type: %s", value.Content[0].Value) + } + default: + return fmt.Errorf("unknown json type: %s", value.ShortTag()) + } +} diff --git a/code-gen/src/apidesc/consts.go b/code-gen/src/apidesc/consts.go new file mode 100644 index 000000000..102f30907 --- /dev/null +++ b/code-gen/src/apidesc/consts.go @@ -0,0 +1,95 @@ +package apidesc + +import ( + "net/http" +) + +type MethodName string + +const ( + MethodNameGET MethodName = http.MethodGet + MethodNamePOST MethodName = http.MethodPost + MethodNamePUT MethodName = http.MethodPut + MethodNameDELETE MethodName = http.MethodDelete +) + +type ServiceName string + +const ( + ServiceNameUp ServiceName = "up" + ServiceNameIo ServiceName = "io" + ServiceNameRs ServiceName = "rs" + ServiceNameRsf ServiceName = "rsf" + ServiceNameApi ServiceName = "api" + ServiceNameBucket ServiceName = "uc" +) + +// StringLikeType 类字符串参数类型 +type StringLikeType = string + +const ( + StringLikeTypeString StringLikeType = "string" // 字符串 + StringLikeTypeInteger StringLikeType = "integer" // 整型数字 + StringLikeTypeFloat StringLikeType = "float" // 浮点型数字 + StringLikeTypeBoolean StringLikeType = "boolean" // 布尔值 +) + +type MultipartFormDataType = string + +const ( + MultipartFormDataTypeString MultipartFormDataType = "string" // 字符串 + MultipartFormDataTypeInteger MultipartFormDataType = "integer" + MultipartFormDataTypeUploadToken MultipartFormDataType = "upload_token" + MultipartFormDataTypeBinaryData MultipartFormDataType = "binary_data" +) + +type OptionalType string + +const ( + OptionalTypeRequired OptionalType = "" // 用户必须传值 + OptionalTypeOmitEmpty OptionalType = "omitempty" // 如果用户不传值,则该字段省略 + OptionalTypeKeepEmpty OptionalType = "keepempty" // 即使用户不传值,也会发送空值 + OptionalTypeNullable OptionalType = "nullable" // 如果用户不传值,则该字段省略,但如果用户传值,即使是空值也会发送 +) + +type Authorization string + +const ( + AuthorizationNone Authorization = "" + AuthorizationQbox Authorization = "Qbox" + AuthorizationQiniu Authorization = "qiniu" + AuthorizationUpToken Authorization = "UploadToken" +) + +type Idempotent string + +const ( + IdempotentDefault Idempotent = "default" // 默认幂等性(根据 HTTP 方法判定) + IdempotentAlways Idempotent = "always" // 总是幂等 + IdempotentNever Idempotent = "never" // 总是不幂等 +) + +type EncodeType string + +const ( + EncodeTypeNone EncodeType = "none" + EncodeTypeUrlSafeBase64 EncodeType = "url_safe_base64" // 需要进行编码 + EncodeTypeUrlSafeBase64OrNone EncodeType = "url_safe_base64_or_none" // 不仅需要编码,即使路径参数的值是 None 也要编码。该选项暗示了 nullable +) + +type ServiceBucketType string + +const ( + ServiceBucketTypeNone ServiceBucketType = "" // + ServiceBucketTypePlainText ServiceBucketType = "plain_text" // 该值为存储空间名称 + ServiceBucketTypeEntry ServiceBucketType = "entry" // 该值格式为 UrlSafeBase64("$bucket:$key") + ServiceBucketTypeUploadToken ServiceBucketType = "upload_token" // 该值为上传凭证,内部包含存储空间信息 +) + +type ServiceObjectType string + +const ( + ServiceObjectTypeNone ServiceObjectType = "" // + ServiceObjectTypePlainText ServiceObjectType = "plain_text" // 该值为对象名称 + ServiceObjectTypeEntry ServiceObjectType = "entry" // 该值格式为 UrlSafeBase64("$bucket:$key") +) diff --git a/code-gen/src/apidesc/header.go b/code-gen/src/apidesc/header.go new file mode 100644 index 000000000..3e4a81fda --- /dev/null +++ b/code-gen/src/apidesc/header.go @@ -0,0 +1,12 @@ +package apidesc + +type HeaderName struct { + HeaderName string `yaml:"header_name,omitempty"` // HTTP 头名称 + Documentation string `yaml:"documentation,omitempty"` // HTTP 头参数文档 + FieldName string `yaml:"field_name,omitempty"` // HTTP 头参数名称 + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // HTTP 头参数驼峰命名 + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // HTTP 头参数下划线命名 + Optional *OptionalType `yaml:"optional,omitempty"` // HTTP 头参数是否可选,如果为空,则表示必填 +} + +type HeaderNames []HeaderName diff --git a/code-gen/src/apidesc/request.go b/code-gen/src/apidesc/request.go new file mode 100644 index 000000000..e53f06203 --- /dev/null +++ b/code-gen/src/apidesc/request.go @@ -0,0 +1,77 @@ +package apidesc + +import ( + "fmt" + + "gopkg.in/yaml.v3" +) + +type NamedPathParam struct { + Documentation string `yaml:"documentation,omitempty"` // URL 路径参数文档 + PathSegment string `yaml:"path_segment,omitempty"` // URL 路径段落,如果为空,则表示参数直接追加在 URL 路径末尾 + FieldName string `yaml:"field_name,omitempty"` // URL 路径参数名称 + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 路径参数驼峰命名 + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 路径参数下划线命名 + Type *StringLikeType `yaml:"type,omitempty"` // URL 路径参数类型 + Encode *EncodeType `yaml:"encode,omitempty"` // URL 路径参数编码方式,如果为空,表示直接转码成字符串 + ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // URL 路径参数是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式 + ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // URL 路径参数是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式 + Optional *OptionalType `yaml:"optional,omitempty"` // URL 路径参数是否可选,如果为空,则表示必填 +} + +type FreePathParams struct { + FieldName string `yaml:"field_name,omitempty"` // URL 路径参数名称 + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 路径参数驼峰命名 + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 路径参数下划线命名 + Documentation string `yaml:"documentation,omitempty"` // URL 路径参数文档 + EncodeParamKey *EncodeType `yaml:"encode_param_key"` // URL 路径参数键编码方式,如果为空,表示直接转码成字符串 + EncodeParamValue *EncodeType `yaml:"encode_param_value"` // URL 路径参数值编码方式,如果为空,表示直接转码成字符串 +} + +type PathParams struct { + Named []NamedPathParam `yaml:"named,omitempty"` // URL 路径有名参数列表 + Free *FreePathParams `yaml:"free,omitempty"` // URL 路径自由参数列表 +} + +type RequestBody struct { + Json *JsonType `yaml:"json,omitempty"` // JSON 类型 + FormUrlencoded *FormUrlencodedRequestStruct `yaml:"form_urlencoded,omitempty"` // URL 编码表单调用(无法上传二进制数据) + MultipartFormData *MultipartFormFields `yaml:"multipart_form_data,omitempty"` // 复合表单调用(可以上传二进制数据) + BinaryData bool `yaml:"binary_data,omitempty"` // 二进制数据 +} + +func (body *RequestBody) UnmarshalYAML(value *yaml.Node) error { + switch value.ShortTag() { + case "!!str": + switch value.Value { + case "binary_data": + body.BinaryData = true + default: + return fmt.Errorf("unknown request body type: %s", value.Value) + } + return nil + case "!!map": + switch value.Content[0].Value { + case "json": + return value.Content[1].Decode(&body.Json) + case "form_urlencoded": + return value.Content[1].Decode(&body.FormUrlencoded) + case "multipart_form_data": + return value.Content[1].Decode(&body.MultipartFormData) + default: + return fmt.Errorf("unknown request body type: %s", value.Content[0].Value) + } + default: + return fmt.Errorf("unknown request body type: %s", value.ShortTag()) + } +} + +type ApiRequestDescription struct { + PathParams *PathParams `yaml:"path_params,omitempty"` // URL 路径参数列表 + HeaderNames HeaderNames `yaml:"header_names,omitempty"` // HTTP 头参数列表 + QueryNames QueryNames `yaml:"query_names,omitempty"` // URL 查询参数列表 + Body *RequestBody `yaml:"body,omitempty"` // 请求体 + Authorization *Authorization `yaml:"authorization,omitempty"` // 鉴权参数 + Idempotent *Idempotent `yaml:"idempotent,omitempty"` // 幂等性 + responseTypeRequired bool `yaml:"response_type_required"` // +} diff --git a/code-gen/src/apidesc/request_body_form.go b/code-gen/src/apidesc/request_body_form.go new file mode 100644 index 000000000..328554917 --- /dev/null +++ b/code-gen/src/apidesc/request_body_form.go @@ -0,0 +1,18 @@ +package apidesc + +type FormUrlencodedRequestStruct struct { + Fields []FormUrlencodedRequestField `yaml:"fields,omitempty"` // URL 编码表单字段列表 +} + +type FormUrlencodedRequestField struct { + FieldName string `yaml:"field_name,omitempty"` // URL 编码表单字段名称 + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 编码表单字段驼峰命名 + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 编码表单字段下划线命名 + Key string `yaml:"key,omitempty"` // URL 编码表单参数名称 + Documentation string `yaml:"documentation,omitempty"` // URL 编码表单参数文档 + Type *StringLikeType `yaml:"type,omitempty"` // URL 编码表单参数类型 + Multiple bool `yaml:"multiple,omitempty"` // URL 编码表单参数是否可以有多个值 + Optional *OptionalType `yaml:"optional,omitempty"` // URL 编码表单参数是否可选,如果为空,则表示必填 + ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // URL 编码表单参数是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式 + ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // URL 编码表单参数是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式 +} diff --git a/code-gen/src/apidesc/request_body_multipart.go b/code-gen/src/apidesc/request_body_multipart.go new file mode 100644 index 000000000..9fbf5cc89 --- /dev/null +++ b/code-gen/src/apidesc/request_body_multipart.go @@ -0,0 +1,25 @@ +package apidesc + +type MultipartFormFields struct { + Named []NamedMultipartFormField `yaml:"named_fields,omitempty"` + Free *FreeMultipartFormFields `yaml:"free_fields,omitempty"` +} + +type NamedMultipartFormField struct { + FieldName string `yaml:"field_name,omitempty"` + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` + Key string `yaml:"key,omitempty"` + Type *MultipartFormDataType `yaml:"type,omitempty"` + Documentation string `yaml:"documentation,omitempty"` + ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` + ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` + Optional *OptionalType `yaml:"optional,omitempty"` +} + +type FreeMultipartFormFields struct { + FieldName string `yaml:"field_name,omitempty"` + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` + Documentation string `yaml:"documentation,omitempty"` +} diff --git a/code-gen/src/apidesc/request_query.go b/code-gen/src/apidesc/request_query.go new file mode 100644 index 000000000..ad2ef8610 --- /dev/null +++ b/code-gen/src/apidesc/request_query.go @@ -0,0 +1,16 @@ +package apidesc + +type QueryName struct { + FieldName string `yaml:"field_name,omitempty"` // 参数名称 + FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 路径参数驼峰命名 + FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 路径参数下划线命名 + QueryName string `yaml:"query_name,omitempty"` // URL 查询参数名称 + Documentation string `yaml:"documentation,omitempty"` // URL 查询参数文档 + Multiple bool `yaml:"multiple,omitempty"` // URL 查询参数是否可以有多个值 + QueryType *StringLikeType `yaml:"query_type,omitempty"` // URL 查询参数类型 + ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // URL 查询参数是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式 + ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // URL 查询参数是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式 + Optional *OptionalType `yaml:"optional,omitempty"` // URL 查询参数是否可选,如果为空,则表示必填 +} + +type QueryNames []QueryName diff --git a/code-gen/src/apidesc/response.go b/code-gen/src/apidesc/response.go new file mode 100644 index 000000000..35b1097e4 --- /dev/null +++ b/code-gen/src/apidesc/response.go @@ -0,0 +1,6 @@ +package apidesc + +type ApiResponseDescription struct { + HeaderNames HeaderNames `yaml:"header_names,omitempty"` // HTTP 头参数列表 + Body *ResponseBody `yaml:"body,omitempty"` // 响应体 +} diff --git a/code-gen/src/apidesc/response_body.go b/code-gen/src/apidesc/response_body.go new file mode 100644 index 000000000..87970615b --- /dev/null +++ b/code-gen/src/apidesc/response_body.go @@ -0,0 +1,34 @@ +package apidesc + +import ( + "fmt" + + "gopkg.in/yaml.v3" +) + +type ResponseBody struct { + Json *JsonType `yaml:"json,omitempty"` // JSON 类型 + BinaryDataStream bool `yaml:"binaryDataStream,omitempty"` // 二进制数据 +} + +func (body *ResponseBody) UnmarshalYAML(value *yaml.Node) error { + switch value.ShortTag() { + case "!!str": + switch value.Value { + case "binary_data_stream": + body.BinaryDataStream = true + return nil + default: + return fmt.Errorf("unknown response body type: %s", value.Value) + } + case "!!map": + switch value.Content[0].Value { + case "json": + return value.Content[1].Decode(&body.Json) + default: + return fmt.Errorf("unknown response body type: %s", value.Content[0].Value) + } + default: + return fmt.Errorf("unknown response body type: %s", value.ShortTag()) + } +} diff --git a/code-gen/src/generator/config.go b/code-gen/src/generator/config.go new file mode 100644 index 000000000..abca19d64 --- /dev/null +++ b/code-gen/src/generator/config.go @@ -0,0 +1,62 @@ +package generator + +import ( + "path/filepath" + + "github.com/YangSen-qn/code-gen/src/generator/lang" +) + +type Config struct { + Language lang.Language // + TemplateDir string // 模版路径 + OutputDir string // 输出路径 + PackagePrefix string // 包名前缀 +} + +func (c Config) apiTemplatePath() string { + return c.templatePath(TemplateFileNameApi) +} + +func (c Config) apiClassTemplatePath() []string { + templateNames := []string{ + TemplateFileNameCreateClass, + } + paths := make([]string, 0) + for _, name := range templateNames { + paths = append(paths, c.templatePath(name)) + } + return paths +} + +func (c Config) apiRequestTemplatePath() []string { + templateNames := []string{ + TemplateFileNameRequest, + TemplateFileNameCreateClass, + } + paths := make([]string, 0) + for _, name := range templateNames { + paths = append(paths, c.templatePath(name)) + } + return paths +} + +func (c Config) apiResponseTemplatePath() []string { + templateNames := []string{ + TemplateFileNameResponse, + } + paths := make([]string, 0) + for _, name := range templateNames { + paths = append(paths, c.templatePath(name)) + } + return paths +} + +func (c Config) templatePath(name string) string { + path := name + + if len(c.TemplateDir) > 0 { + path = filepath.Join(c.TemplateDir, path) + } + + return path +} diff --git a/code-gen/src/generator/consts.go b/code-gen/src/generator/consts.go new file mode 100644 index 000000000..4f4e796ba --- /dev/null +++ b/code-gen/src/generator/consts.go @@ -0,0 +1,8 @@ +package generator + +const ( + TemplateFileNameApi = "api.java" + TemplateFileNameCreateClass = "api_create_class.java" + TemplateFileNameRequest = "api_request.java" + TemplateFileNameResponse = "api_response.java" +) diff --git a/code-gen/src/generator/generator.go b/code-gen/src/generator/generator.go new file mode 100644 index 000000000..5a0d2e61e --- /dev/null +++ b/code-gen/src/generator/generator.go @@ -0,0 +1,158 @@ +package generator + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "strings" + "text/template" + + "github.com/YangSen-qn/code-gen/src/apidesc" + "github.com/YangSen-qn/code-gen/src/generator/internal/data" + "github.com/YangSen-qn/code-gen/src/utils" +) + +type Generator interface { + Generate(desc *apidesc.ApiDetailedDescription) error +} + +func New(cfg Config) Generator { + return &generator{ + Config: cfg, + } +} + +type generator struct { + Config + + api data.Api + funcMap template.FuncMap +} + +func (g *generator) Generate(desc *apidesc.ApiDetailedDescription) error { + pkgName := g.Language.PackageName(desc.PackageName) + apiFileName := g.Language.ApiFileName(desc.Name) + outputPath := filepath.Join(g.OutputDir, pkgName, "apis", apiFileName) + outputDir := filepath.Dir(outputPath) + pkgName = pkgName + ".apis" + if exist, err := utils.ExistDir(outputDir); err != nil { + return err + } else if !exist { + if e := os.MkdirAll(outputDir, 0755); e != nil { + return e + } + } + + g.api = data.Api{ + PackageName: g.PackagePrefix + pkgName, + Document: g.Language.Annotation(desc.Documentation), + ClassName: g.Language.ClassName(desc.Name, false), + Language: g.Language, + } + + g.funcMap = template.FuncMap{ + "addIndentation": g.api.AddIndentation, + "generateClassCode": g.generateClassCode, + } + + requestData := &data.Request{ + PackageName: g.PackagePrefix + pkgName, + Document: g.Language.Annotation(desc.Documentation), + ClassName: g.Language.ClassName(desc.Name, false), + Method: strings.ToUpper(string(desc.Method)), + BasicPath: strings.TrimPrefix(desc.BasePath, "/"), // 去除首部的 / + PathSuffix: strings.TrimPrefix(desc.PathSuffix, "/"), // 去除首部的 / + Desc: desc.Request, + Language: g.Language, + } + requestData.Setup() + requestCode := g.generateRequestCode(requestData) + + responseData := &data.Response{ + PackageName: g.PackagePrefix + pkgName, + Document: g.Language.Annotation(desc.Documentation), + ClassName: g.Language.ClassName(desc.Name, false), + Desc: desc.Response, + Language: g.Language, + } + responseData.Setup() + responseCode := g.generateResponseCode(responseData) + + apiCode := g.generateApiCode(&data.Api{ + PackageName: g.PackagePrefix + pkgName, + Document: g.Language.Annotation(desc.Documentation), + ClassName: g.Language.ClassName(desc.Name, false), + RequestCode: requestCode, + ResponseCode: responseCode, + Language: g.Language, + UseEncode: requestData.HasEncodeFields, + Request: requestData, + Response: responseData, + }) + + f, err := os.Create(outputPath) + if err != nil { + return err + } + defer f.Close() + + _, err = f.WriteString(apiCode) + return err +} + +func (g *generator) generateRequestCode(info any) string { + code, err := g.generateCode(info, g.apiRequestTemplatePath()...) + if err != nil { + panic(fmt.Sprintf("generateRequestCode error:%v ", err)) + } + return code +} + +func (g *generator) generateResponseCode(info any) string { + code, err := g.generateCode(info, g.apiResponseTemplatePath()...) + if err != nil { + panic(fmt.Sprintf("generateResponseCode error:%v ", err)) + } + return code +} + +func (g *generator) generateClassCode(info any) string { + code, err := g.generateCode(info, g.apiClassTemplatePath()...) + if err != nil { + panic(fmt.Sprintf("generateClass error:%v ", err)) + } + return code +} + +func (g *generator) generateApiCode(info any) string { + code, err := g.generateCode(info, g.apiTemplatePath()) + if err != nil { + panic(fmt.Sprintf("generateApiCode error:%v ", err)) + } + return code +} + +func (g *generator) generateCode(data any, templatePaths ...string) (string, error) { + if len(templatePaths) == 0 { + return "", fmt.Errorf("no template path") + } + + allFuncs := utils.TemplateFunctions() + for name, fn := range g.funcMap { + allFuncs[name] = fn + } + + name := filepath.Base(templatePaths[0]) + t, err := template.New(name).Funcs(allFuncs).ParseFiles(templatePaths...) + if err != nil { + return "", err + } + + w := bytes.NewBuffer([]byte{}) + if err = t.Execute(w, data); err != nil { + return "", err + } + + return w.String(), nil +} diff --git a/code-gen/src/generator/internal/data/api.go b/code-gen/src/generator/internal/data/api.go new file mode 100644 index 000000000..88abb1aeb --- /dev/null +++ b/code-gen/src/generator/internal/data/api.go @@ -0,0 +1,77 @@ +package data + +import ( + "github.com/YangSen-qn/code-gen/src/generator/lang" + "github.com/YangSen-qn/code-gen/src/utils" +) + +type Api struct { + PackageName string + Document string + ClassName string + RequestCode string + ResponseCode string + UseEncode bool + Request *Request + Response *Response + Language lang.Language +} + +func (a *Api) HasOtherClasses() bool { + return len(a.Request.Classes) > 0 || len(a.Response.Classes) > 0 +} + +func (a *Api) HasMapFields() bool { + for _, f := range a.Request.RequireFields { + if f.IsMap() { + return true + } + } + + for _, f := range a.Request.OptionsFields { + if f.IsMap() { + return true + } + } + + for _, class := range a.Request.Classes { + for _, field := range class.Fields { + if field.IsMap() { + return true + } + + } + } + + for _, class := range a.Response.Classes { + for _, field := range class.Fields { + if field.IsMap() { + return true + } + } + } + + return false +} + +func (a *Api) IsFromRequestBody() bool { + return a.Request.IsBodyForm || a.Request.IsBodyMultiPartFrom +} + +func (a *Api) IsJsonRequestBody() bool { + return a.Request.IsBodyJson +} + +func (a *Api) IsJsonResponseBody() bool { + return a.Response.IsBodyJson +} + +func (a *Api) AddIndentation(info string) string { + if newInfo, err := utils.TextLineMapper(info, func(line string, lineNumber int, totalLine int) (t string, stop bool) { + return a.Language.Indentation() + line, false + }); err != nil { + return info + } else { + return newInfo + } +} diff --git a/code-gen/src/generator/internal/data/field.go b/code-gen/src/generator/internal/data/field.go new file mode 100644 index 000000000..7ac369749 --- /dev/null +++ b/code-gen/src/generator/internal/data/field.go @@ -0,0 +1,163 @@ +package data + +import ( + "fmt" + + "github.com/YangSen-qn/code-gen/src/apidesc" + "github.com/YangSen-qn/code-gen/src/generator/lang" +) + +const ( + defaultFieldName = "data" +) + +type Field struct { + Document string `json:"document"` + Name string `json:"name"` + Type string `json:"type"` // 参考:parseJsonTypeToField + PublicGetFunc bool `json:"public_get_func"` + GetFuncName string `json:"get_func_name"` + PublicSetFunc bool `json:"public_set_func"` + SetFuncName string `json:"set_func_name"` + Key string `json:"key"` + KeyOptional bool `json:"key_optional"` // true: value 无值,则 Key 和 Value 忽略,如果为 false, Key 必传,Value 看实际情况 + ValueOptional bool `json:"value_optional"` // Key 为 false 时生效,如果为 true, Value 可忽略 + Default string `json:"default"` + Encode string `json:"encode"` + EncodeDefault string `json:"encode_default"` // Encode 模式,Value 为空,如果此值不为空,则使用此值作为编码后的值 + KeyEncode string `json:"key_encode"` + KeyEncodeDefault string `json:"key_encode_default"` // KeyEncode Encode 模式,Value 为空,如果此值不为空,则使用此值作为编码后的值 + Deprecated bool `json:"deprecated"` + + typeInfo lang.FieldType // +} + +func (f *Field) IsMap() bool { + return f.typeInfo.FieldType == FieldTypeMap +} + +func (f *Field) ContentValueType() string { + return f.typeInfo.ContentValueType +} + +type Class struct { + Document string `json:"document"` + ClassName string `json:"class_name"` + IsInner bool `json:"is_inner"` + Fields []*Field `json:"fields"` +} + +func parseJsonTypeToField(l lang.Language, t *apidesc.JsonType) (f Field, classes []Class) { + f = Field{ + Document: "数据信息", + Name: defaultFieldName, + PublicGetFunc: false, + GetFuncName: "", + PublicSetFunc: false, + SetFuncName: "", + Key: "", + Type: "", + KeyOptional: false, + ValueOptional: false, + Default: "null", + Encode: "", + Deprecated: false, + } + if t.String { + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeString, + } + f.Type = l.FieldTypeDesc(f.typeInfo) + return + } else if t.Integer { + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeInt, + } + f.Type = l.FieldTypeDesc(f.typeInfo) + return + } else if t.Float { + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeFloat, + } + f.Type = l.FieldTypeDesc(f.typeInfo) + return + } else if t.Boolean { + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeBool, + } + f.Type = l.FieldTypeDesc(f.typeInfo) + return + } else if t.Array != nil { + ff, cc := parseJsonTypeToField(l, t.Array.Type) + if len(cc) > 0 { + classes = append(classes, cc...) + } + f.Name = l.FieldName(t.Array.Name, false) + f.Document = t.Array.Documentation + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeArray, + ContentValueType: ff.Type, + } + f.Type = l.FieldTypeDesc(f.typeInfo) + return + } else if t.Struct != nil { + f.Name = defaultFieldName + f.Document = t.Struct.Documentation + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeClass, + ClassName: t.Struct.Name, + } + f.Type = l.FieldTypeDesc(f.typeInfo) + t.Struct.Name = f.Type + + // 解析 Field + classFields := make([]*Field, 0) + for _, field := range t.Struct.Fields { + ff, cc := parseJsonTypeToField(l, &field.Type) + if len(cc) > 0 { + classes = append(classes, cc...) + } + ff.Document = field.Documentation + // TODO: 字段是否私有,一般是公开的,但需要确认 + ff.Name = l.FieldName(field.FieldName, false) + ff.Key = field.Key + ff.KeyOptional, ff.ValueOptional = parseOptional(nil, field.Optional) + ff.GetFuncName = l.FieldGetFunctionName(field.FieldName, false) + ff.SetFuncName = l.FieldSetFunctionName(field.FieldName, false) + // TODO: 默认值 + ff.Default = "null" + classFields = append(classFields, &ff) + } + + classes = append(classes, Class{ + Document: t.Struct.Documentation, + ClassName: t.Struct.Name, + IsInner: true, + Fields: classFields, + }) + + return + } else if t.Any { + f.Key = defaultFieldName + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeAny, + } + f.Type = l.FieldTypeDesc(f.typeInfo) + return + } else if t.StringMap { + f.Key = defaultFieldName + f.typeInfo = lang.FieldType{ + FieldType: FieldTypeMap, + ContentKeyType: l.FieldTypeDesc(lang.FieldType{ + FieldType: FieldTypeString, + }), + ContentValueType: l.FieldTypeDesc(lang.FieldType{ + FieldType: FieldTypeAny, + }), + } + f.Type = l.FieldTypeDesc(f.typeInfo) + return + } + + panic(fmt.Sprintf("json type not found:%+v", t)) +} diff --git a/code-gen/src/generator/internal/data/request.go b/code-gen/src/generator/internal/data/request.go new file mode 100644 index 000000000..6f68064aa --- /dev/null +++ b/code-gen/src/generator/internal/data/request.go @@ -0,0 +1,440 @@ +package data + +import ( + "fmt" + + "github.com/YangSen-qn/code-gen/src/apidesc" + "github.com/YangSen-qn/code-gen/src/generator/lang" +) + +const ( + FieldInPath = "path" + FieldInQuery = "query" + FieldInHead = "head" + FieldInBody = "body" +) + +const ( + FieldTypeInt = "int" + FieldTypeInteger = "integer" + FieldTypeLong = "long" + FieldTypeFloat = "float" + FieldTypeBool = "bool" + FieldTypeString = "string" + FieldTypeArray = "array" + FieldTypeMap = "map" + FieldTypeAny = "any" + FieldTypeClass = "class" + FieldTypeBinaryData = "binary" +) + +var fieldTypeMapper = map[string]string{ + apidesc.StringLikeTypeInteger: FieldTypeInt, + apidesc.StringLikeTypeBoolean: FieldTypeBool, + apidesc.StringLikeTypeFloat: FieldTypeFloat, + apidesc.StringLikeTypeString: FieldTypeString, + apidesc.MultipartFormDataTypeUploadToken: FieldTypeString, + apidesc.MultipartFormDataTypeBinaryData: FieldTypeBinaryData, +} + +func transformFileType(fieldName string, t *apidesc.StringLikeType) lang.FieldType { + if t == nil { + panic(fmt.Sprintf("field %s type is nil", fieldName)) + } + + fieldType, ok := fieldTypeMapper[*t] + if !ok { + panic(fmt.Sprintf("field %s type is not support", *t)) + } + + newFieldType := lang.FieldType{ + FieldType: fieldType, + ContentKeyType: "", + ContentValueType: "", + } + + // 大小转换成 long,其他是 int + if fieldType == FieldTypeInt && fieldName == "fsize" { + newFieldType.FieldType = FieldTypeLong + } + + return newFieldType +} + +type Body struct { + Type string + IsBinary bool +} + +type Request struct { + Document string `json:"document"` + PackageName string `json:"package_name"` + ClassName string `json:"class_name"` + Method string `json:"method"` + Desc apidesc.ApiRequestDescription `json:"desc"` + Language lang.Language `json:"-"` + BasicPath string `json:"-"` + PathSuffix string `json:"-"` + Authorization string `json:"-"` + RequireFields []Field `json:"-"` + OptionsFields []Field `json:"-"` + PathFields []Field `json:"-"` + QueryFields []Field `json:"-"` + HeadFields []Field `json:"-"` + BodyFields []Field `json:"-"` // json 或 表单 + Classes []Class `json:"-"` + IsBodyBinary bool `json:"-"` + IsBodyJson bool `json:"-"` + IsBodyForm bool `json:"-"` + IsBodyMultiPartFrom bool `json:"-"` + HasEncodeFields bool `json:"-"` +} + +func (r *Request) JsonBodyField() *Field { + if !r.IsBodyJson || len(r.BodyFields) == 0 { + return nil + } + + return &r.BodyFields[0] +} + +func (r *Request) Setup() *Request { + r.getFieldsFromPath() + r.getFieldsFromQuery() + r.getFieldsFromHeader() + r.getFieldsFromBody() + + for _, class := range r.Classes { + for _, field := range class.Fields { + field.PublicSetFunc = true + } + } + + if authorization := r.Desc.Authorization; authorization != nil { + r.Authorization = string(*authorization) + } + + return r +} + +func (r *Request) getFieldsFromPath() { + hasEncodeFields := false + + if path := r.Desc.PathParams; path != nil { + for _, f := range path.Named { + kOptional, vOptional := parseOptional(f.Encode, f.Optional) + fieldType := transformFileType(f.FieldName, f.Type) + encode, defaultEncode := parseEncode(f.Encode) + field := Field{Document: f.Documentation, + Name: r.Language.FieldName(f.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(f.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(f.FieldName, !vOptional), + Key: f.PathSegment, + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + KeyOptional: kOptional, + ValueOptional: vOptional, + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + Encode: encode, + EncodeDefault: defaultEncode, + Deprecated: false, + } + + if len(field.Encode) > 0 { + hasEncodeFields = true + } + + r.PathFields = append(r.PathFields, field) + + if vOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + } + + if f := path.Free; f != nil { + fieldType := lang.FieldType{ + FieldType: FieldTypeMap, + ContentKeyType: r.Language.FieldTypeDesc(lang.FieldType{ + FieldType: FieldTypeString, + }), + ContentValueType: r.Language.FieldTypeDesc(lang.FieldType{ + FieldType: FieldTypeString, + }), + } + + field := Field{ + Document: f.Documentation, + Name: r.Language.FieldName(f.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(f.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(f.FieldName, true), + Key: "", + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + ValueOptional: true, + Default: r.Language.FieldDefaultValue(fieldType, false), + Encode: "", + Deprecated: false, + } + field.KeyEncode, field.KeyEncodeDefault = parseEncode(f.EncodeParamKey) + field.Encode, field.EncodeDefault = parseEncode(f.EncodeParamValue) + + r.PathFields = append(r.PathFields, field) + r.OptionsFields = append(r.OptionsFields, field) + } + } + + r.HasEncodeFields = r.HasEncodeFields || hasEncodeFields +} + +func (r *Request) getFieldsFromQuery() { + if queryItems := r.Desc.QueryNames; queryItems != nil { + for _, f := range queryItems { + fieldType := transformFileType(f.FieldName, f.QueryType) + kOptional, vOptional := parseOptional(nil, f.Optional) + field := Field{ + Document: f.Documentation, + Name: r.Language.FieldName(f.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(f.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(f.FieldName, !vOptional), + Key: f.QueryName, + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + KeyOptional: kOptional, + ValueOptional: vOptional, + Deprecated: false, + } + + r.QueryFields = append(r.QueryFields, field) + + if vOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + } + } +} + +func (r *Request) getFieldsFromHeader() { + if headers := r.Desc.HeaderNames; headers != nil { + for _, f := range headers { + fieldType := lang.FieldType{ + FieldType: FieldTypeString, + } + kOptional, vOptional := parseOptional(nil, f.Optional) + field := Field{ + Document: f.Documentation, + Name: r.Language.FieldName(f.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(f.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(f.FieldName, !vOptional), + Key: f.HeaderName, + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + KeyOptional: kOptional, + ValueOptional: vOptional, + Deprecated: false, + } + + r.HeadFields = append(r.HeadFields, field) + + if vOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + } + } +} + +func (r *Request) getFieldsFromBody() { + body := r.Desc.Body + if body == nil { + return + } + + if body.BinaryData { + r.IsBodyBinary = true + kOptional, vOptional := false, false + fieldType := lang.FieldType{ + FieldType: FieldTypeBinaryData, + } + fieldName := "data" + field := Field{ + Document: "请求数据", + Name: r.Language.FieldName(fieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(fieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(fieldName, !vOptional), + Key: fieldName, + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + KeyOptional: kOptional, + ValueOptional: vOptional, + Deprecated: false, + } + + r.BodyFields = append(r.BodyFields, field) + + if vOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + return + } + + if data := body.FormUrlencoded; data != nil { + if len(data.Fields) == 0 { + return + } + + for _, f := range data.Fields { + kOptional, vOptional := parseOptional(nil, f.Optional) + fieldType := transformFileType(f.FieldName, f.Type) + field := Field{ + Document: f.Documentation, + Name: r.Language.FieldName(f.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(f.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(f.FieldName, !vOptional), + Key: f.Key, + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + KeyOptional: kOptional, + ValueOptional: vOptional, + Deprecated: false, + } + + r.BodyFields = append(r.BodyFields, field) + + if vOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + } + + r.IsBodyForm = true + return + } + + if data := body.MultipartFormData; data != nil { + if nData := data.Named; nData != nil { + for _, f := range nData { + kOptional, vOptional := parseOptional(nil, f.Optional) + fieldType := transformFileType(f.FieldName, f.Type) + field := Field{ + Document: f.Documentation, + Name: r.Language.FieldName(f.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(f.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(f.FieldName, !vOptional), + Key: f.Key, + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + KeyOptional: kOptional, + ValueOptional: vOptional, + Deprecated: false, + } + + r.BodyFields = append(r.BodyFields, field) + + if vOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + } + } + + if fData := data.Free; fData != nil { + fieldType := lang.FieldType{ + FieldType: FieldTypeMap, + ContentKeyType: FieldTypeString, + ContentValueType: FieldTypeString, + } + vOptional := false + field := Field{ + Document: fData.Documentation, + Name: r.Language.FieldName(fData.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(fData.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(fData.FieldName, !vOptional), + Key: fData.FieldName, + Type: r.Language.FieldTypeDesc(fieldType), + typeInfo: fieldType, + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + KeyOptional: false, + ValueOptional: vOptional, + Deprecated: false, + } + + r.BodyFields = append(r.BodyFields, field) + + if vOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + } + + r.IsBodyMultiPartFrom = true + return + } + + if data := body.Json; data != nil { + field, classes := parseJsonTypeToField(r.Language, data) + r.BodyFields = append(r.BodyFields, field) + + if field.ValueOptional { + r.OptionsFields = append(r.OptionsFields, field) + } else { + r.RequireFields = append(r.RequireFields, field) + } + + r.Classes = classes + r.IsBodyJson = true + return + } +} + +func parseEncode(encode *apidesc.EncodeType) (string, string) { + if encode == nil || *encode == apidesc.EncodeTypeNone { + return "", "" + } + + if *encode == apidesc.EncodeTypeUrlSafeBase64 { + return string(*encode), "" + } else if *encode == apidesc.EncodeTypeUrlSafeBase64OrNone { + return string(*encode), "~" + } + + panic(fmt.Errorf("unknown encode type: %s", *encode)) +} + +func parseOptional(encode *apidesc.EncodeType, optional *apidesc.OptionalType) (keyOptional, valueOptional bool) { + encodeType, encodeDefault := parseEncode(encode) + if optional == nil || len(*optional) == 0 { + keyOptional = false + valueOptional = len(encodeType) > 0 && len(encodeDefault) > 0 // encode 有默认值,此 value 可以不传 + } else if *optional == apidesc.OptionalTypeOmitEmpty { + // 如果用户不传值,则该字段省略 + keyOptional = true + valueOptional = true + } else if *optional == apidesc.OptionalTypeNullable { + // 如果用户不传值,则该字段省略,但如果用户传值,即使是空值也会发送 + keyOptional = true + valueOptional = true + } else if *optional == apidesc.OptionalTypeKeepEmpty { + // 即使用户不传值,也会发送空值 + keyOptional = false + valueOptional = true + } else { + keyOptional = false + valueOptional = len(encodeType) > 0 && len(encodeDefault) > 0 // encode 有默认值,此 value 可以不传 + } + return +} diff --git a/code-gen/src/generator/internal/data/response.go b/code-gen/src/generator/internal/data/response.go new file mode 100644 index 000000000..4dd6e1f84 --- /dev/null +++ b/code-gen/src/generator/internal/data/response.go @@ -0,0 +1,83 @@ +package data + +import ( + "github.com/YangSen-qn/code-gen/src/apidesc" + "github.com/YangSen-qn/code-gen/src/generator/lang" +) + +type Response struct { + Document string `json:"document"` + PackageName string `json:"package_name"` + ClassName string `json:"class_name"` + Desc apidesc.ApiResponseDescription `json:"desc"` + Language lang.Language `json:"-"` + HeadFields []Field `json:"-"` + BodyField Field `json:"-"` + IsStreamBody bool `json:"-"` + IsBodyJson bool `json:"-"` + Classes []Class `json:"-"` +} + +func (r *Response) Setup() *Response { + r.getFieldsFromHeader() + r.getFieldsFromBody() + + for _, class := range r.Classes { + if class.ClassName == "" { + class.ClassName = "ResponseData" + } + + for _, field := range class.Fields { + field.PublicGetFunc = true + } + } + return r +} + +func (r *Response) getFieldsFromHeader() { + if headers := r.Desc.HeaderNames; headers != nil { + for _, f := range headers { + fieldType := lang.FieldType{ + FieldType: FieldTypeString, + } + kOptional, vOptional := parseOptional(nil, f.Optional) + field := Field{ + Document: f.Documentation, + Name: r.Language.FieldName(f.FieldName, true), + GetFuncName: r.Language.FieldGetFunctionName(f.FieldName, true), + SetFuncName: r.Language.FieldSetFunctionName(f.FieldName, !vOptional), + Key: f.HeaderName, + Type: r.Language.FieldTypeDesc(fieldType), + Default: r.Language.FieldDefaultValue(fieldType, vOptional), + KeyOptional: kOptional, + ValueOptional: vOptional, + Deprecated: false, + } + + r.HeadFields = append(r.HeadFields, field) + } + } +} + +func (r *Response) getFieldsFromBody() { + body := r.Desc.Body + if body == nil { + return + } + + if body.BinaryDataStream { + r.IsStreamBody = true + return + } + + if data := body.Json; data != nil { + field, classes := parseJsonTypeToField(r.Language, data) + r.BodyField = field + r.BodyField.PublicGetFunc = true + r.BodyField.GetFuncName = r.Language.FieldGetFunctionName(field.Name, false) + + r.Classes = classes + r.IsBodyJson = true + return + } +} diff --git a/code-gen/src/generator/lang/java/java.go b/code-gen/src/generator/lang/java/java.go new file mode 100644 index 000000000..d00335db7 --- /dev/null +++ b/code-gen/src/generator/lang/java/java.go @@ -0,0 +1,155 @@ +package java + +import ( + "fmt" + + "github.com/iancoleman/strcase" + + "github.com/YangSen-qn/code-gen/src/generator/internal/data" + "github.com/YangSen-qn/code-gen/src/generator/lang" + "github.com/YangSen-qn/code-gen/src/utils" +) + +func Java() lang.Language { + return &java{} +} + +type java struct { +} + +func (j *java) PackageName(name string) string { + return strcase.ToLowerCamel(name) +} + +func (j *java) Indentation() string { + return " " +} + +func (j *java) Annotation(info string) string { + if newInfo, err := utils.TextLineMapper(info, func(line string, lineNumber int, totalLine int) (t string, stop bool) { + return " * " + line, false + }); err != nil { + return info + } else { + return fmt.Sprintf(` +/** + %s + */`, newInfo) + } + +} + +func (j *java) ApiFileName(name string) string { + return "Api" + strcase.ToCamel(name) + ".java" +} + +func (j *java) ClassName(name string, isPrivate bool) string { + return "Api" + strcase.ToCamel(name) +} + +func (j *java) FunctionName(name string, isPrivate bool) string { + return strcase.ToLowerCamel(name) +} + +func (j *java) FieldName(name string, isPrivate bool) string { + if name == "private" { + name = "isPrivate" + } + return strcase.ToLowerCamel(name) +} + +func (j *java) FieldDefaultValue(fieldType lang.FieldType, isOptional bool) string { + switch fieldType.FieldType { + case data.FieldTypeInt: + if isOptional { + return "null" + } else { + return "0" + } + case data.FieldTypeLong: + if isOptional { + return "null" + } else { + return "0l" + } + case data.FieldTypeFloat: + if isOptional { + return "null" + } else { + return "0" + } + case data.FieldTypeBool: + if isOptional { + return "null" + } else { + return "false" + } + case data.FieldTypeString: + if isOptional { + return "null" + } else { + return "\"\"" + } + case data.FieldTypeArray: + if isOptional { + return "null" + } else { + return fmt.Sprintf("new %s[]()", strcase.ToCamel(fieldType.ContentValueType)) + } + case data.FieldTypeMap: + if isOptional { + return "null" + } else { + return fmt.Sprintf("new HashMap<%s,%s>()", strcase.ToCamel(fieldType.ContentKeyType), strcase.ToCamel(fieldType.ContentValueType)) + } + case data.FieldTypeClass: + if isOptional { + return "null" + } else { + return fmt.Sprintf("new %s()", strcase.ToCamel(fieldType.ContentKeyType)) + } + case data.FieldTypeBinaryData: + if isOptional { + return "" + } else { + return "new byte[]()" + } + } + + panic(fmt.Sprintf("unknown field type: %+v", fieldType)) +} + +func (j *java) FieldGetFunctionName(name string, isPrivate bool) string { + return "get" + strcase.ToCamel(name) +} + +func (j *java) FieldSetFunctionName(name string, isPrivate bool) string { + return "set" + strcase.ToCamel(name) +} + +func (j *java) FieldTypeDesc(fieldType lang.FieldType) string { + switch fieldType.FieldType { + case data.FieldTypeInt: + return "Integer" + case data.FieldTypeLong: + return "Long" + case data.FieldTypeFloat: + return "Float" + case data.FieldTypeBool: + return "Boolean" + case data.FieldTypeString: + return "String" + case data.FieldTypeArray: + return fmt.Sprintf("%s[]", strcase.ToCamel(fieldType.ContentValueType)) + case data.FieldTypeMap: + return fmt.Sprintf("Map<%s,%s>", strcase.ToCamel(fieldType.ContentKeyType), strcase.ToCamel(fieldType.ContentValueType)) + case data.FieldTypeClass: + return strcase.ToCamel(fieldType.ClassName) + case data.FieldTypeAny: + return "Object" + case data.FieldTypeBinaryData: + return "byte[]" + } + + panic(fmt.Sprintf("unknown field type: %+v", fieldType)) +} diff --git a/code-gen/src/generator/lang/java/java_test.go b/code-gen/src/generator/lang/java/java_test.go new file mode 100644 index 000000000..e77f925f8 --- /dev/null +++ b/code-gen/src/generator/lang/java/java_test.go @@ -0,0 +1,14 @@ +package java + +import ( + "testing" +) + +func TestFunctionName(t *testing.T) { + + j := java{} + name := j.FieldName("Domain", false) + if name != "domain" { + t.Errorf("Expected domain, got %s", name) + } +} diff --git a/code-gen/src/generator/lang/lang.go b/code-gen/src/generator/lang/lang.go new file mode 100644 index 000000000..199fdb72f --- /dev/null +++ b/code-gen/src/generator/lang/lang.go @@ -0,0 +1,22 @@ +package lang + +type FieldType struct { + FieldType string + ClassName string // for class + ContentKeyType string // for map,转化后的 + ContentValueType string // for map and array,转化后的 +} + +type Language interface { + PackageName(name string) string + Indentation() string + Annotation(info string) string + ApiFileName(name string) string + ClassName(name string, isPrivate bool) string + FieldName(name string, isPrivate bool) string + FieldTypeDesc(fieldType FieldType) string + FieldDefaultValue(fieldType FieldType, isOptional bool) string + FieldGetFunctionName(name string, isPrivate bool) string + FieldSetFunctionName(name string, isPrivate bool) string + FunctionName(name string, isPrivate bool) string +} diff --git a/code-gen/src/main.go b/code-gen/src/main.go new file mode 100644 index 000000000..bfa48d726 --- /dev/null +++ b/code-gen/src/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + + "github.com/YangSen-qn/code-gen/src/apidesc" + "github.com/YangSen-qn/code-gen/src/generator" + "github.com/YangSen-qn/code-gen/src/generator/lang/java" + "github.com/YangSen-qn/code-gen/src/parser" +) + +func main() { + + apiDescDir := "api-specs" + + gen := generator.New(generator.Config{ + Language: java.Java(), + TemplateDir: "temp/java", + OutputDir: "../src/main/java/com/qiniu", + PackagePrefix: "com.qiniu.", + }) + + if e := parser.Parser(apiDescDir, func(desc *apidesc.ApiDetailedDescription) error { + fmt.Println(desc) + return gen.Generate(desc) + }); e != nil { + fmt.Printf("error: %s", e) + } +} diff --git a/code-gen/src/parser/parser.go b/code-gen/src/parser/parser.go new file mode 100644 index 000000000..a6849722c --- /dev/null +++ b/code-gen/src/parser/parser.go @@ -0,0 +1,67 @@ +package parser + +import ( + "fmt" + "io/fs" + "os" + "path/filepath" + "strings" + + "gopkg.in/yaml.v3" + + "github.com/YangSen-qn/code-gen/src/apidesc" + "github.com/YangSen-qn/code-gen/src/utils" +) + +func isApiSpecFile(path string) bool { + return strings.HasSuffix(path, ".yml") +} + +type ApiDescHandler func(desc *apidesc.ApiDetailedDescription) error + +func Parser(apiDir string, handler ApiDescHandler) error { + if handler == nil { + return nil + } + + return filepath.WalkDir(apiDir, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + // 检查 + apiPath := path + if exist, e := utils.ExistFile(apiPath); e != nil { + return e + } else if !exist { + return nil + } + + if !isApiSpecFile(apiPath) { + return nil + } + + descFile, err := os.Open(apiPath) + if err != nil { + return err + } + defer descFile.Close() + + pkgName := strings.TrimPrefix(path, apiDir) + pkgName = strings.TrimPrefix(pkgName, "/") + pkgName = strings.TrimSuffix(pkgName, d.Name()) + pkgName = strings.TrimSuffix(pkgName, "/") + + desc := apidesc.ApiDetailedDescription{ + PackageName: pkgName, + Name: strings.TrimSuffix(d.Name(), ".yml"), + } + decoder := yaml.NewDecoder(descFile) + decoder.KnownFields(true) + if err = decoder.Decode(&desc); err != nil { + return fmt.Errorf("parse api:%s error:%s", apiPath, err) + } + + return handler(&desc) + }) +} diff --git a/code-gen/src/utils/file.go b/code-gen/src/utils/file.go new file mode 100644 index 000000000..e14fb0725 --- /dev/null +++ b/code-gen/src/utils/file.go @@ -0,0 +1,29 @@ +package utils + +import ( + "os" +) + +func ExistDir(dir string) (bool, error) { + stat, err := os.Stat(dir) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + + return false, err + } + return stat.IsDir(), nil +} + +func ExistFile(dir string) (bool, error) { + stat, err := os.Stat(dir) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + + return false, err + } + return !stat.IsDir(), nil +} diff --git a/code-gen/src/utils/math.go b/code-gen/src/utils/math.go new file mode 100644 index 000000000..66ae735d5 --- /dev/null +++ b/code-gen/src/utils/math.go @@ -0,0 +1,20 @@ +package utils + +func Add(a, b int) int { + return a + b +} + +func Sub(a, b int) int { + return a - b +} + +func Mul(a, b int) int { + return a * b +} + +func Div(a, b int) int { + if b == 0 { + return 0 + } + return a / b +} diff --git a/code-gen/src/utils/string.go b/code-gen/src/utils/string.go new file mode 100644 index 000000000..cf21df65d --- /dev/null +++ b/code-gen/src/utils/string.go @@ -0,0 +1,54 @@ +package utils + +import ( + "bufio" + "bytes" + "strings" +) + +func TextLineMapper(text string, mapper func(line string, lineNumber int, totalLine int) (t string, stop bool)) (string, error) { + if mapper == nil { + return text, nil + } + + totalLine := CountLines(text) + + stop := false + line := "" + index := 0 + newText := strings.Builder{} + s := bufio.NewScanner(bytes.NewReader([]byte(text))) + for s.Scan() { + line, stop = mapper(s.Text(), index, totalLine) + if index > 0 { + line = "\n" + line + } + + if _, err := newText.WriteString(line); err != nil { + return "", err + } + + if stop { + break + } + + index++ + } + + return newText.String(), nil +} + +func CountLines(text string) int { + lines := 0 + for _, char := range text { + if char == '\n' { + lines++ + } + } + + // 如果字符串不以换行符结尾,则需要额外加一 + if lines > 0 && text[len(text)-1] != '\n' { + lines++ + } + return lines +} diff --git a/code-gen/src/utils/temp.go b/code-gen/src/utils/temp.go new file mode 100644 index 000000000..163c818bb --- /dev/null +++ b/code-gen/src/utils/temp.go @@ -0,0 +1,14 @@ +package utils + +import ( + "text/template" +) + +func TemplateFunctions() template.FuncMap { + return template.FuncMap{ + "add": Add, + "sub": Sub, + "mul": Mul, + "div": Div, + } +} diff --git a/code-gen/templates/java/api.java b/code-gen/templates/java/api.java new file mode 100644 index 000000000..9f162b917 --- /dev/null +++ b/code-gen/templates/java/api.java @@ -0,0 +1,61 @@ +package {{ .PackageName }}; +{{ if .HasOtherClasses}} +import com.google.gson.annotations.SerializedName; +{{- end}} +{{- if .IsJsonRequestBody }} +import com.qiniu.common.Constants; +{{- end}} +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +{{- if .UseEncode}} +import com.qiniu.util.UrlSafeBase64; +{{- end}} +import com.qiniu.storage.Api; +{{- if or .IsJsonRequestBody .IsJsonResponseBody }} +import com.qiniu.util.Json; +{{- end}} +{{- if .IsFromRequestBody }} +import com.qiniu.util.StringMap; +{{- end}} +{{ if .HasMapFields }} +import java.util.HashMap; +import java.util.Map; +{{- end}} +{{ .Document }} +public class {{ .ClassName }} extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public {{ .ClassName }}(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public {{ .ClassName }}(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + +{{ .AddIndentation .RequestCode }} + +{{ .AddIndentation .ResponseCode }} +} diff --git a/code-gen/templates/java/api_create_class.java b/code-gen/templates/java/api_create_class.java new file mode 100644 index 000000000..4d4928d9d --- /dev/null +++ b/code-gen/templates/java/api_create_class.java @@ -0,0 +1,46 @@ +{{- $classInfo := .}} +/** + * {{.Document}} + */ +public{{if .IsInner}} static{{end}} final class {{ .ClassName }} { + {{- $fieldList := .Fields}}{{if $fieldList}} + {{- range $i, $field := $fieldList}} + + /** + * {{$field.Document}} + */ + @SerializedName("{{$field.Key}}") + private {{$field.Type}} {{$field.Name}}; + {{- end}} + {{- end}} + + {{- $fieldList := .Fields}}{{if $fieldList}} + {{- range $i, $field := $fieldList}} + {{- if $field.PublicGetFunc}} + + /** + * 获取变量值 + * {{$field.Document}} + * + * @return {{$field.Name}} + */ + public {{$field.Type}} {{$field.GetFuncName}}() { + return this.{{$field.Name}}; + } + {{- end}} + {{- if $field.PublicSetFunc}} + + /** + * 设置变量值 + * + * @param {{$field.Name}} {{$field.Document}} + * @return Request + */ + public {{ $classInfo.ClassName }} {{$field.SetFuncName}}({{$field.Type}} {{$field.Name}}) { + this.{{$field.Name}} = {{$field.Name}}; + return this; + } + {{- end}} + {{- end}} + {{- end}} +} \ No newline at end of file diff --git a/code-gen/templates/java/api_request.java b/code-gen/templates/java/api_request.java new file mode 100644 index 000000000..b1a2f3950 --- /dev/null +++ b/code-gen/templates/java/api_request.java @@ -0,0 +1,265 @@ +/** + * 请求信息 + */ +public static class Request extends Api.Request { + {{- /* 必选属性 */}} + {{- $fields := .RequireFields}}{{range $i, $field := $fields}} + + /** + * {{$field.Document}} + */ + private {{$field.Type}} {{$field.Name}}; + {{- end}} + + {{- /* 可选属性 */}} + {{- $fields := .OptionsFields}}{{range $i, $field := $fields}} + + /** + * {{$field.Document}} + */ + private {{$field.Type}} {{$field.Name}} = {{$field.Default}}; + {{- end}} + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + {{- $fields := .RequireFields}}{{range $i, $field := $fields}} + * @param {{$field.Name}} {{$field.Document}} 【必须】 + {{- end}} + */ + public Request(String urlPrefix{{$fields := .RequireFields}}{{range $i, $field := $fields}}, {{$field.Type}} {{$field.Name}}{{- end}}) { + super(urlPrefix); + this.setMethod(MethodType.{{.Method}}); + + {{- /* 鉴权方式 */}} + {{- if eq .Authorization "qiniu"}} + this.setAuthType(AuthTypeQiniu); + {{- else if eq .Authorization ""}} + {{- end}} + + {{- $fields := .RequireFields}}{{range $i, $field := $fields}} + this.{{$field.Name}} = {{$field.Name}}; + {{- end}} + } + + {{- /* 可选属性配置函数 */}} + {{- $fields := .OptionsFields}}{{range $i, $field := $fields}} + + /** + * 设置参数【可选】 + * + * @param {{$field.Name}} {{$field.Document}} + * @return Request + */ + public Request {{$field.SetFuncName}}({{$field.Type}} {{$field.Name}}) { + this.{{$field.Name}} = {{$field.Name}}; + return this; + } + {{- end}} + + @Override + protected void prepareToRequest() throws QiniuException { + {{- $fields := .RequireFields}}{{if $fields}}{{range $i, $field := $fields}} + if (this.{{$field.Name}} == null) { + throw new QiniuException(new NullPointerException("{{$field.Name}} can't empty")); + } + {{- end}} + {{- end}} + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + {{- /* 原始路径 */}} + {{- if len .BasicPath }} + addPathSegment("{{.BasicPath}}"); + {{- end }} + + {{- $fields := .PathFields}}{{if $fields}} + {{- range $i, $field := $fields}} + {{- if not $field.IsMap}} + + {{- if $field.KeyOptional}} + {{- /* Key 可选,如果 Key 对应的 Value 不存在,则此部分省略 */}} + if (this.{{$field.Name}} != null) { + {{- if len $field.Key}} + addPathSegment("{{$field.Key}}"); + {{- end}} + addPathSegment({{ if $field.Encode }}UrlSafeBase64.encodeToString(this.{{$field.Name}}){{ else }}this.{{$field.Name}}{{end}}); + } + {{- else}} + + {{- /* Key 有值情况必选,Value 根据实际处理 */}} + {{- if len $field.Key}} + addPathSegment("{{$field.Key}}"); + {{- end}} + + {{- /* 看 Value 是否可选 */}} + {{- if $field.ValueOptional }} + {{- /* Value 可选,如果 Value 无值则使用默认值,如果默认值也没有,则使用 EncodeDefault*/}} + {{$field.Type}} value = this.{{$field.Name}}; + {{- if and ($field.Default) (ne $field.Default "null")}} + if (value == null) { + value = {{$field.Default}}; + } + {{- end}} + {{- if $field.Encode }} + if (value != null) { + value = UrlSafeBase64.encodeToString(value); + }{{- if len $field.EncodeDefault }} else { + {{- /* 如果有默认值 EncodeDefault 就使用 */}} + value = "{{$field.EncodeDefault}}"; + }{{- end}} + {{- end}} + if (value != null) { + addPathSegment(value); + } + {{- else}} + {{- /* Value 必选,值会提前检测,一定会有值 */}} + addPathSegment({{ if $field.Encode }}UrlSafeBase64.encodeToString(this.{{$field.Name}}){{ else }}this.{{$field.Name}}{{end}}); + {{- end}} + {{- end}} + + {{- else}} + + for (String key : this.{{$field.Name}}.keySet()) { + {{- if $field.KeyOptional}} + + {{- /* Key 可选,如果 Key 对应的 Value 不存在,则此部分省略 */}} + if (this.{{$field.Name}} != null) { + {{- if len $field.Key}} + addPathSegment("{{$field.Key}}"); + {{- end}} + addPathSegment({{ if $field.Encode }}UrlSafeBase64.encodeToString(this.{{$field.Name}}){{ else }}this.{{$field.Name}}{{end}}); + } + + {{- else}} + + {{- /* Key 有值情况必选,Value 根据实际处理 */}} + addPathSegment({{ if $field.KeyEncode }}UrlSafeBase64.encodeToString(key){{ else }}key{{end}}); + + {{- /* 看 Value 是否可选 */}} + {{- if $field.ValueOptional }} + {{- /* Value 可选,如果 Value 无值则使用默认值,如果默认值也没有,则使用 EncodeDefault*/}} + {{$field.ContentValueType}} valueP = this.{{$field.Name}}.get(key); + {{- if $field.Encode }} + if (valueP != null) { + valueP = UrlSafeBase64.encodeToString(valueP); + }{{- if len $field.EncodeDefault }} else { + {{- /* 如果有默认值 EncodeDefault 就使用 */}} + valueP = "{{$field.EncodeDefault}}"; + }{{- end}} + {{- end}} + if (valueP != null) { + addPathSegment(valueP); + } + {{- else}} + {{- /* Value 必选,值会提前检测,一定会有值 */}} + addPathSegment({{ if $field.Encode }}UrlSafeBase64.encodeToString(this.{{$field.Name}}){{ else }}this.{{$field.Name}}{{end}}); + {{- end}} + {{- end}} + } + + {{- end}} + {{- end}} + {{- end}} + + {{- if len .PathSuffix }} + addPathSegment("{{.PathSuffix}}"); + {{- end}} + + {{- /* super */}} + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + {{- $fields := .QueryFields}}{{if $fields}} + {{range $i, $field := $fields}} + {{- if $field.KeyOptional}} + if (this.{{$field.Name}} != null) { + addQueryPair("{{$field.Key}}", this.{{$field.Name}}); + } + {{- else}} + addQueryPair("{{$field.Key}}", this.{{$field.Name}}); + {{- end}} + {{- end}} + {{- end}} + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + {{- $fields := .HeadFields}}{{if $fields}} + {{range $i, $field := $fields}} + {{- if $field.KeyOptional}} + if (this.{{$field.Name}} != null) { + addHeaderField("{{$field.Key}}", this.{{$field.Name}}); + } + {{- else}} + addHeaderField("{{$field.Key}}", this.{{$field.Name}}); + {{- end}} + {{- end}} + {{- end}} + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + {{- /* 构建 Binary */}} + {{- if .IsBodyBinary}} + this.setBody(data, 0, data.length, null); + + {{- /* 构建表单 */}} + {{- else if .IsBodyForm }} + StringMap fields = new StringMap(); + {{- $fields := .BodyFields}}{{if $fields}} + {{- range $i, $field := $fields}} + {{- if $field.KeyOptional}} + if (this.{{$field.Name}} != null) { + fields.put("{{$field.Key}}", this.{{$field.Name}}); + } + {{- else}} + fields.put("{{$field.Key}}", this.{{$field.Name}}); + {{- end}} + {{- end}} + {{- end}} + this.setFormBody(fields); + + {{- /* TODO: 构建 MultiPartFrom */}} + {{- else if .IsBodyMultiPartFrom }} + StringMap fields = new StringMap(); + {{- $fields := .BodyFields}}{{if $fields}} + {{- range $i, $field := $fields}} + {{- if $field.KeyOptional}} + if (this.{{$field.Name}} != null) { + fields.put("{{$field.Key}}", this.{{$field.Name}}); + } + {{- else}} + fields.put("{{$field.Key}}", this.{{$field.Name}}); + {{- end}} + {{- end}} + {{- end}} + this.setMultipartBody("", "", fields, (byte[])null, null); + + {{- /* 构建 Json */}} + {{- else if .IsBodyJson }} + {{- $jsonBodyField := .JsonBodyField }} + byte[] body = Json.encode(this.{{$jsonBodyField.Name}}).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + {{- end}} + + super.buildBodyInfo(); + } + {{/* 创建 class */}} + {{- $classList := .Classes}}{{if $classList}} + {{- range $i, $classInfo := $classList}} + {{- $classCode := generateClassCode $classInfo }}{{ addIndentation $classCode }} + {{- end}} + {{- end}} +} \ No newline at end of file diff --git a/code-gen/templates/java/api_response.java b/code-gen/templates/java/api_response.java new file mode 100644 index 000000000..1c5c8ac29 --- /dev/null +++ b/code-gen/templates/java/api_response.java @@ -0,0 +1,39 @@ +/** + * 响应信息 + */ +public static class Response extends Api.Response { + {{- if .IsBodyJson}} + + /** + * {{.BodyField.Document}} + */ + private {{.BodyField.Type}} {{.BodyField.Name}}; + {{- end}} + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + {{- if .IsBodyJson}} + + this.{{.BodyField.Name}} = Json.decode(response.bodyString(), {{.BodyField.Type}}.class); + {{- end}} + } + + {{- if .IsBodyJson}} + + /** + * 响应信息 + * + * @return {{.BodyField.Type}} + */ + public {{.BodyField.Type}} {{.BodyField.GetFuncName}}() { + return this.{{.BodyField.Name}}; + } + {{- end}} + {{/* 创建 class */}} + {{- $classList := .Classes}}{{if $classList}} + {{- range $i, $classInfo := $classList}} + {{- $classCode := generateClassCode $classInfo }}{{ addIndentation $classCode }} + {{- end}} + {{- end}} +} \ No newline at end of file diff --git a/codecov.yml b/codecov.yml index fee0452aa..df604d3e9 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,7 +3,7 @@ codecov: - prow.qiniu.io # prow 里面运行需添加,其他 CI 不要 require_ci_to_pass: no # 改为 no,否则 codecov 会等待其他 GitHub 上所有 CI 通过才会留言。 -github_checks: #关闭github checks +github_checks: #关闭github checks annotations: false comment: @@ -12,13 +12,13 @@ comment: require_changes: false # if true: only post the comment if coverage changes require_base: no # [yes :: must have a base report to post] require_head: yes # [yes :: must have a head report to post] - branches: # branch names that can post comment + branches: # branch names that can post comment - "master" coverage: - status: # 评判 pr 通过的标准 + status: # 评判 pr 通过的标准 patch: off - project: # project 统计所有代码x + project: # project 统计所有代码x default: # basic target: 60% # 总体通过标准 diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 8351d9206..da888f7ae 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -28,14 +28,14 @@ - + - + diff --git a/examples/CdnRefreshDirsDemo.java b/examples/CdnRefreshDirsDemo.java index 2d8351b6c..7e7f31739 100644 --- a/examples/CdnRefreshDirsDemo.java +++ b/examples/CdnRefreshDirsDemo.java @@ -8,25 +8,25 @@ //https://developer.qiniu.com/kodo/sdk/java#fusion-refresh-urls public class CdnRefreshDirsDemo { - public static void main(String args[]) { - String accessKey = "your access key"; - String secretKey = "your secret key"; - Auth auth = Auth.create(accessKey, secretKey); - CdnManager c = new CdnManager(auth); - //待刷新的目录列表,目录必须以 / 结尾 - String[] dirs = new String[]{ - "http://javasdk.qiniudn.com/gopher1/", - "http://javasdk.qiniudn.com/gopher2/", - //.... - }; - try { - //单次方法调用刷新的目录不可以超过10个,另外刷新目录权限需要联系技术支持开通 - CdnResult.RefreshResult result = c.refreshDirs(dirs); - System.out.println(result.code); - //获取其他的回复内容 - } catch (QiniuException e) { - System.err.println(e.response.toString()); - } - } + public static void main(String args[]) { + String accessKey = "your access key"; + String secretKey = "your secret key"; + Auth auth = Auth.create(accessKey, secretKey); + CdnManager c = new CdnManager(auth); + //待刷新的目录列表,目录必须以 / 结尾 + String[] dirs = new String[]{ + "http://javasdk.qiniudn.com/gopher1/", + "http://javasdk.qiniudn.com/gopher2/", + //.... + }; + try { + //单次方法调用刷新的目录不可以超过10个,另外刷新目录权限需要联系技术支持开通 + CdnResult.RefreshResult result = c.refreshDirs(dirs); + System.out.println(result.code); + //获取其他的回复内容 + } catch (QiniuException e) { + System.err.println(e.response.toString()); + } + } } diff --git a/examples/DomainListDemo.java b/examples/DomainListDemo.java index 2c1257ce2..ad2aa81b6 100644 --- a/examples/DomainListDemo.java +++ b/examples/DomainListDemo.java @@ -1,4 +1,3 @@ - import com.qiniu.common.QiniuException; import com.qiniu.common.Zone; import com.qiniu.http.Response; @@ -22,8 +21,8 @@ public static void main(String args[]) { try { String[] domainLists = bucketManager.domainList(bucket); - for(String domain : domainLists) - System.out.print(domain); + for (String domain : domainLists) + System.out.print(domain); } catch (QiniuException e) { diff --git a/examples/GetBucketInfo.java b/examples/GetBucketInfo.java index 5ef65988d..a2582cfb4 100644 --- a/examples/GetBucketInfo.java +++ b/examples/GetBucketInfo.java @@ -5,26 +5,26 @@ import com.qiniu.storage.model.BucketInfo; public class GetBucketInfo { - + //设置需要操作的账号的AK和SK String ACCESS_KEY = "Access_Key"; String SECRET_KEY = "Secret_Key"; Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY); - + //指定区域,可以用 Zone.autoZone() 自动获取 Zone z = Zone.zone0(); Configuration c = new Configuration(z); - + //实例化一个BucketManager对象 BucketManager bucketManager = new BucketManager(auth, c); - + // 空间名 String bucket = "BUCKET"; - + public static void main(String[] args) { new GetBucketInfo().getBucketInfo(); } - + public void getBucketInfo() { try { BucketInfo bucketInfo = bucketManager.getBucketInfo(bucket); @@ -32,9 +32,9 @@ public void getBucketInfo() { System.out.println(bucketInfo.getPrivate()); // 输出空间所述区域 System.out.println(bucketInfo.getZone()); - - // 其他参数详见 https://github.com/qiniu/java-sdk/blob/master/src/main/java/com/qiniu/storage/model/BucketInfo.java - + + // 其他参数详见 https://github.com/qiniu/java-sdk/blob/master/src/main/java/com/qiniu/storage/model/BucketInfo.java + } catch (Exception e) { // } diff --git a/examples/LinkingDemo.java b/examples/LinkingDemo.java index 1aea0da88..2806e68f2 100644 --- a/examples/LinkingDemo.java +++ b/examples/LinkingDemo.java @@ -16,114 +16,113 @@ public class LinkingDemo { final static String testHost = "http://linking.qiniuapi.com"; final static String testDeviceName1 = "test1"; final static String testDeviceName2 = "test2"; + public static void main(String[] args) { - Auth auth = Auth.create(testAk,testSk); - LinkingDeviceManager deviceManager = new LinkingDeviceManager(auth,testHost); - try{ + Auth auth = Auth.create(testAk, testSk); + LinkingDeviceManager deviceManager = new LinkingDeviceManager(auth, testHost); + try { //创建设备 - deviceManager.createDevice(testAppid,testDeviceName1); - } catch (QiniuException e){ + deviceManager.createDevice(testAppid, testDeviceName1); + } catch (QiniuException e) { System.out.println(e.error()); } - try{ + try { //添加dak - DeviceKey[] keys = deviceManager.addDeviceKey(testAppid,testDeviceName1); + DeviceKey[] keys = deviceManager.addDeviceKey(testAppid, testDeviceName1); System.out.println(keys[0].getAccessKey()); System.out.println(keys[0].getSecretKey()); - }catch (QiniuException e){ + } catch (QiniuException e) { System.out.println(e.error()); } - try{ + try { //查询设备 - DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid,testDeviceName1); - if (keys.length==1){ - throw new QiniuException(new Exception(),"expect one length"); + DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid, testDeviceName1); + if (keys.length == 1) { + throw new QiniuException(new Exception(), "expect one length"); } //删除设备 - deviceManager.deleteDeviceKey(testAppid,testDeviceName1,keys[0].getAccessKey()); - keys = deviceManager.queryDeviceKey(testAppid,testDeviceName1); - if (keys.length==0){ - throw new QiniuException(new Exception(),"expect zero length"); + deviceManager.deleteDeviceKey(testAppid, testDeviceName1, keys[0].getAccessKey()); + keys = deviceManager.queryDeviceKey(testAppid, testDeviceName1); + if (keys.length == 0) { + throw new QiniuException(new Exception(), "expect zero length"); } - }catch (QiniuException e){ + } catch (QiniuException e) { System.out.println(e.error()); } - try{ + try { //列出设备 - DeviceListing deviceslist = deviceManager.listDevice(testAppid,"","", 1,false); + DeviceListing deviceslist = deviceManager.listDevice(testAppid, "", "", 1, false); System.out.println(deviceslist.items.length); - }catch (QiniuException e){ + } catch (QiniuException e) { System.out.println(e.error()); } - - try{ + try { //修改设备字段 - PatchOperation[] operations={new PatchOperation("replace","segmentExpireDays",9)}; - Device device= deviceManager.updateDevice(testAppid,testDeviceName1,operations); + PatchOperation[] operations = {new PatchOperation("replace", "segmentExpireDays", 9)}; + Device device = deviceManager.updateDevice(testAppid, testDeviceName1, operations); System.out.println(device.getSegmentExpireDays()); - }catch (QiniuException e){ + } catch (QiniuException e) { System.out.println(e.error()); } - try{ + try { //查询设备在线历史记录 - DeviceHistoryListing history= deviceManager.listDeviceHistory(testAppid,testDeviceName1, - 0,(new Date().getTime())/1000,"",0); - }catch (QiniuException e){ + DeviceHistoryListing history = deviceManager.listDeviceHistory(testAppid, testDeviceName1, + 0, (new Date().getTime()) / 1000, "", 0); + } catch (QiniuException e) { System.out.println(e.error()); } - - try{ + try { //删除设备信息 - deviceManager.deleteDevice(testAppid,testDeviceName1); - } catch (QiniuException e){ + deviceManager.deleteDevice(testAppid, testDeviceName1); + } catch (QiniuException e) { System.out.println(e.error()); } - try{ - deviceManager.createDevice(testAppid,testDeviceName1); - deviceManager.createDevice(testAppid,testDeviceName2); + try { + deviceManager.createDevice(testAppid, testDeviceName1); + deviceManager.createDevice(testAppid, testDeviceName2); //添加dak - deviceManager.addDeviceKey(testAppid,testDeviceName1); - DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid,testDeviceName1); + deviceManager.addDeviceKey(testAppid, testDeviceName1); + DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid, testDeviceName1); String dak = keys[0].getAccessKey(); //移动dak - deviceManager.cloneDeviceKey(testAppid,testDeviceName1,testDeviceName2,true, false,dak); + deviceManager.cloneDeviceKey(testAppid, testDeviceName1, testDeviceName2, true, false, dak); Device device = deviceManager.getDeviceByAccessKey(dak); device.getDeviceName(); - deviceManager.deleteDeviceKey(testAppid,testDeviceName2,dak); + deviceManager.deleteDeviceKey(testAppid, testDeviceName2, dak); String token; //生成具有所有功能的token - String[] actions = new String[]{Auth.DTOKEN_ACTION_STATUS,Auth.DTOKEN_ACTION_VOD,Auth.DTOKEN_ACTION_TUTK}; - token = auth.generateLinkingDeviceTokenWithExpires(testAppid,testDeviceName1,1000,actions); + String[] actions = new String[]{Auth.DTOKEN_ACTION_STATUS, Auth.DTOKEN_ACTION_VOD, Auth.DTOKEN_ACTION_TUTK}; + token = auth.generateLinkingDeviceTokenWithExpires(testAppid, testDeviceName1, 1000, actions); //生成视频相关功能的token - token = auth.generateLinkingDeviceVodTokenWithExpires(testAppid,testDeviceName1,1000,actions); + token = auth.generateLinkingDeviceVodTokenWithExpires(testAppid, testDeviceName1, 1000, actions); //生成获取设备状态的token - token = auth.generateLinkingDeviceStatusTokenWithExpires(testAppid,testDeviceName1,1000,actions); + token = auth.generateLinkingDeviceStatusTokenWithExpires(testAppid, testDeviceName1, 1000, actions); - }catch (QiniuException e){ + } catch (QiniuException e) { System.out.println(e.error()); - }finally { - try{ - deviceManager.deleteDevice(testAppid,testDeviceName1); - }catch (Exception ignored){ + } finally { + try { + deviceManager.deleteDevice(testAppid, testDeviceName1); + } catch (Exception ignored) { } - try{ - deviceManager.deleteDevice(testAppid,testDeviceName2); - }catch (Exception ignored){ + try { + deviceManager.deleteDevice(testAppid, testDeviceName2); + } catch (Exception ignored) { } } diff --git a/examples/QNMetaDemo.java b/examples/QNMetaDemo.java index 5173bd486..533a988e8 100644 --- a/examples/QNMetaDemo.java +++ b/examples/QNMetaDemo.java @@ -11,18 +11,17 @@ /** * 自定义文件元信息demo(x-qn-meta-*) - * + *

* 接口 * POST /setmeta/[//][/cond/Encoded(condKey1=condVal1&condKey2=condVal2)] * Host: rs-.qiniu.com * Content-Type: application/x-www-form-urlencoded * Authorization: Qbox 鉴权 - * + *

* 注意: * meta-key,key不能设置为中文,不允许为空; * 新的metas会完全替换掉以前的metas,注意, 是完全覆盖; * 如果请求url中没有 [/],则表示要删除所有metas; - * */ public class QNMetaDemo { //设置好账号的ACCESS_KEY和SECRET_KEY @@ -49,7 +48,7 @@ public static void main(String[] args) throws Exception { metaKeyVal.put("eng1", "qiniu"); metaKeyVal.put("eng2", "七牛"); boolean result = qnMetaDemo.setMeta(qnMetaDemo.bucketName, key, metaKeyVal); - if(result){ + if (result) { System.out.println("done"); } } @@ -66,9 +65,9 @@ public boolean setMeta(String bucket, String key, Map headers) t String path = String.format("/setmeta/%s", resource); String k; String encodedMetaValue; - for(Iterator var6 = headers.keySet().iterator(); var6.hasNext(); path = String.format("%s/x-qn-meta-%s/%s", path, k, encodedMetaValue)) { - k = (String)var6.next(); - encodedMetaValue = UrlSafeBase64.encodeToString((String)headers.get(k)); + for (Iterator var6 = headers.keySet().iterator(); var6.hasNext(); path = String.format("%s/x-qn-meta-%s/%s", path, k, encodedMetaValue)) { + k = (String) var6.next(); + encodedMetaValue = UrlSafeBase64.encodeToString((String) headers.get(k)); } //接口请求地址 String url = String.format("https://%s%s", rsHost, path); diff --git a/examples/ResourcesCensor.java b/examples/ResourcesCensor.java index 4ad9f5780..e01ffe482 100644 --- a/examples/ResourcesCensor.java +++ b/examples/ResourcesCensor.java @@ -10,10 +10,10 @@ import java.util.Map; /** - * 内容安全审核 demo - * ImageCensor 图片内容安全审核,同步处理,不需要查询处理结果 - * VideoCensor 视频内容安全审核,异步处理,需要查询处理结果,返回处理任务ID - * getVideoCensorResultByJobID 根据视频内容审核任务ID,查询审核结果 + * 内容安全审核 demo + * ImageCensor 图片内容安全审核,同步处理,不需要查询处理结果 + * VideoCensor 视频内容安全审核,异步处理,需要查询处理结果,返回处理任务ID + * getVideoCensorResultByJobID 根据视频内容审核任务ID,查询审核结果 */ public class ResourcesCensor { //设置好账号的ACCESS_KEY和SECRET_KEY @@ -105,17 +105,17 @@ public String VideoCensor() throws QiniuException { * 查询视频审核内容结果 * 参考 * https://developer.qiniu.com/censor/api/5620/video-censor#4 - * @param ID : 视频审核返回的 job ID * + * @param ID : 视频审核返回的 job ID */ - public String getVideoCensorResultByJobID(String ID){ + public String getVideoCensorResultByJobID(String ID) { String url = "http://ai.qiniuapi.com/v3/jobs/video/".concat(ID); String accessToken = (String) auth.authorizationV2(url).get("Authorization"); StringMap headers = new StringMap(); headers.put("Authorization", accessToken); try { - com.qiniu.http.Response resp = client.get(url,headers); + com.qiniu.http.Response resp = client.get(url, headers); return resp.bodyString(); } catch (Exception e) { e.printStackTrace(); diff --git a/examples/SendMessageDemo.java b/examples/SendMessageDemo.java index 42320f78c..fd304f67c 100644 --- a/examples/SendMessageDemo.java +++ b/examples/SendMessageDemo.java @@ -7,18 +7,18 @@ import com.qiniu.util.Auth; public class SendMessageDemo { - public static void main(String args[]) { - // 设置需要操作的账号的AK和SK - String ACCESS_KEY = ""; - String SECRET_KEY = ""; - Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY); - - // 实例化一个SmsManager对象 - SmsManager smsManager = new SmsManager(auth); - - try { - Map map = new HashMap(); - Response resp = smsManager.sendMessage("templateId", new String[] { "10086" }, map); + public static void main(String args[]) { + // 设置需要操作的账号的AK和SK + String ACCESS_KEY = ""; + String SECRET_KEY = ""; + Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY); + + // 实例化一个SmsManager对象 + SmsManager smsManager = new SmsManager(auth); + + try { + Map map = new HashMap(); + Response resp = smsManager.sendMessage("templateId", new String[]{"10086"}, map); // Response resp = smsManager.describeSignature("passed", 0, 0); // Response resp = smsManager.createSignature("signature", "app", // new String[] { "data:image/gif;base64,xxxxxxxxxx" }); @@ -28,7 +28,7 @@ public static void main(String args[]) { // Response resp = smsManager.modifySignature("SignatureId", "signature"); // Response resp = smsManager.deleteSignature("signatureId"); // Response resp = smsManager.deleteTemplate("templateId"); - System.out.println(resp.bodyString()); + System.out.println(resp.bodyString()); // SignatureInfo sinfo = smsManager.describeSignatureItems("", 0, 0); // System.out.println(sinfo.getItems().get(0).getAuditStatus()); @@ -36,9 +36,9 @@ public static void main(String args[]) { // System.out.println(tinfo.getItems().get(0).getAuditStatus()); - } catch (QiniuException e) { - System.out.println(e); - } + } catch (QiniuException e) { + System.out.println(e); + } - } + } } diff --git a/examples/UploadBySelfDefiningParam.java b/examples/UploadBySelfDefiningParam.java index a504703b2..f92779d53 100644 --- a/examples/UploadBySelfDefiningParam.java +++ b/examples/UploadBySelfDefiningParam.java @@ -8,13 +8,13 @@ /** * 设置自定义变量上传并接收自定义变量 demo - * + *

* 自定义变量需要以 x: 开头, 携带自定义变量上传参考文档 * https://developer.qiniu.com/kodo/manual/1235/vars#2 - * + *

* 接收自定义变量参考上传策略文档 -- returnBody * https://developer.qiniu.com/kodo/manual/1206/put-policy - * + *

* 服务端具体用法实例参考 UploadBySelfDefiningParam.upload() */ public class UploadBySelfDefiningParam { @@ -57,11 +57,11 @@ public void upload() throws QiniuException { //上传自定义参数,自定义参数名称需要以 x:开头 StringMap params = new StringMap(); - params.put("x:fname","123.jpg"); - params.put("x:age",20); + params.put("x:fname", "123.jpg"); + params.put("x:age", 20); String localFilePath = "/Users/mini/Downloads/qiniu_test.jpg"; - Response response = uploadManager.put(localFilePath, key, upToken,params,null,false); + Response response = uploadManager.put(localFilePath, key, upToken, params, null, false); //输出返回结果 System.out.println(response.bodyString()); } diff --git a/examples/upload_ recorder.java b/examples/upload_ recorder.java index b2560f359..243ced59e 100644 --- a/examples/upload_ recorder.java +++ b/examples/upload_ recorder.java @@ -41,6 +41,10 @@ public class UploadDemo { //创建上传对象 UploadManager uploadManager = new UploadManager(c); + public static void main(String args[]) throws IOException { + new UploadDemo().upload(); + } + // 覆盖上传 public String getUpToken() { return auth.uploadToken(bucketname); @@ -72,8 +76,4 @@ public void upload() throws IOException { } } - public static void main(String args[]) throws IOException { - new UploadDemo().upload(); - } - } \ No newline at end of file diff --git a/examples/upload_callback.java b/examples/upload_callback.java index 380634cde..9dc5f976c 100644 --- a/examples/upload_callback.java +++ b/examples/upload_callback.java @@ -43,6 +43,10 @@ public class UploadDemo { //创建上传对象 UploadManager uploadManager = new UploadManager(c); + public static void main(String args[]) throws IOException { + new UploadDemo().upload(); + } + //设置callbackUrl以及callbackBody,七牛将文件名和文件大小回调给业务服务器 public String getUpToken() { return auth.uploadToken(bucketname, null, 3600, new StringMap() @@ -69,8 +73,4 @@ public void upload() throws IOException { } } - public static void main(String args[]) throws IOException { - new UploadDemo().upload(); - } - } \ No newline at end of file diff --git a/examples/upload_pfops.java b/examples/upload_pfops.java index f088248e1..f4ad7ee59 100644 --- a/examples/upload_pfops.java +++ b/examples/upload_pfops.java @@ -6,6 +6,7 @@ import com.qiniu.util.UrlSafeBase64; import java.io.IOException; + import com.qiniu.common.QiniuException; import com.qiniu.http.Response; import com.qiniu.storage.UploadManager; diff --git a/examples/upload_v1_api.java b/examples/upload_v1_api.java index 853b87540..7a1bff663 100644 --- a/examples/upload_v1_api.java +++ b/examples/upload_v1_api.java @@ -38,15 +38,15 @@ public class UploadDemo { //密钥配置 Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY); + public static void main(String args[]) throws IOException { + new UploadDemo().upload(); + } + //简单上传,使用默认策略,只需要设置上传的空间名就可以了 public String getUpToken() { return auth.uploadToken(bucketName); } - public static void main(String args[]) throws IOException { - new UploadDemo().upload(); - } - public void upload() throws IOException { long fileSize = 1024 * 7 + 2341; // 单位: k diff --git a/examples/upload_v2_api.java b/examples/upload_v2_api.java index 749a3e9b9..dac2dd2dd 100644 --- a/examples/upload_v2_api.java +++ b/examples/upload_v2_api.java @@ -34,15 +34,15 @@ public class UploadDemo { //密钥配置 Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY); + public static void main(String args[]) throws IOException { + new UploadDemo().upload(); + } + //简单上传,使用默认策略,只需要设置上传的空间名就可以了 public String getUpToken() { return auth.uploadToken(bucketName); } - public static void main(String args[]) throws IOException { - new UploadDemo().upload(); - } - public void testUpload() { String fileName = "java_api_v2_test.zip"; diff --git "a/examples/\345\205\263\344\272\216\345\233\236\350\260\203\346\265\201\347\250\213.md" "b/examples/\345\205\263\344\272\216\345\233\236\350\260\203\346\265\201\347\250\213.md" index 72116cd29..01f0c16af 100644 --- "a/examples/\345\205\263\344\272\216\345\233\236\350\260\203\346\265\201\347\250\213.md" +++ "b/examples/\345\205\263\344\272\216\345\233\236\350\260\203\346\265\201\347\250\213.md" @@ -1,16 +1,19 @@ 一般的上传流程是用户获得上传凭证之后直接将资源上传到七牛空间,然后七牛回返回一个上传成功或者失败的信息,用户业务服务器是不清楚这些信息的,可以参考下面的流程图: ![不设置回调](http://7xkn2v.dl1.z0.glb.clouddn.com/QQ20151019-0@2x.png) -另外一种方式是用户在上传的时候设置回调,则七牛会在用户上传成功后将上传资源的元信息以json格式POST到用户设置的callbackurl,用户业务服务器收到这些信息时可以将其进行保存(比如保存到数据库里面方面查询),但是到这一步并没有结束,用户业务服务器还需要对七牛服务器这次回调做出响应,同样是响应一个json格式的数据给七牛服务器,七牛会将回调的信息返回给上传客户端,流程参考如下: +另外一种方式是用户在上传的时候设置回调,则七牛会在用户上传成功后将上传资源的元信息以json格式POST到用户设置的callbackurl,用户业务服务器收到这些信息时可以将其进行保存( +比如保存到数据库里面方面查询),但是到这一步并没有结束,用户业务服务器还需要对七牛服务器这次回调做出响应,同样是响应一个json格式的数据给七牛服务器,七牛会将回调的信息返回给上传客户端,流程参考如下: ![设置回调](http://7xkn2v.dl1.z0.glb.clouddn.com/QQ20151019-1@2x.png) 以下是具体回调过程: + 1. 上传策略里面设置好callbackurl以及callbackbody,callbackHost和callbackBodyType这两个字段都是可以默认不设置的,关于这两个参数的规则可以参考七牛的上传策略文档: -http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html -这个例子设置的callbackbody是: -`"hash=$(etag)&key=$(key)&fsize=$(fsize)&mimeType=$(mimeType)"` + http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html + 这个例子设置的callbackbody是: + `"hash=$(etag)&key=$(key)&fsize=$(fsize)&mimeType=$(mimeType)"` 2.业务服务器设置接收该回调以及返回json的程序代码,可以参考: + ``` public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -36,6 +39,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) out.close(); } ``` + 3.业务服务器可以接收到该回调信息如下: ![业务服务器收到的回调信息](http://7xkn2v.dl1.z0.glb.clouddn.com/QQ20151019-5@2x.png) diff --git "a/examples/\345\205\263\344\272\216\350\256\276\347\275\256notifyURL\346\262\241\346\234\211\346\224\266\345\210\260\345\233\236\350\260\203.md" "b/examples/\345\205\263\344\272\216\350\256\276\347\275\256notifyURL\346\262\241\346\234\211\346\224\266\345\210\260\345\233\236\350\260\203.md" index 78f0eb120..d614b5248 100644 --- "a/examples/\345\205\263\344\272\216\350\256\276\347\275\256notifyURL\346\262\241\346\234\211\346\224\266\345\210\260\345\233\236\350\260\203.md" +++ "b/examples/\345\205\263\344\272\216\350\256\276\347\275\256notifyURL\346\262\241\346\234\211\346\224\266\345\210\260\345\233\236\350\260\203.md" @@ -1,15 +1,17 @@ ##七牛设置notifyURL没有收到回调 -在使用七牛进行数据处理时用户可以使用来主动查询持久化处理的执行状态,具体查询方法是发送一个Get请求:http://api.qiniu.com/status/get/prefop?id= +在使用七牛进行数据处理时用户可以使用 +来主动查询持久化处理的执行状态,具体查询方法是发送一个Get请求:http://api.qiniu.com/status/get/prefop?id= 可以参考: -http://developer.qiniu.com/docs/v6/api/reference/fop/pfop/prefop.html +http://developer.qiniu.com/docs/v6/api/reference/fop/pfop/prefop.html 但是调用查询的成本比较高,还得起脚本实时去遍历查询,如果能回调,就可以省掉这个工作了。 正好七牛这边针对上传预转持续化和触发持续化分别提供persistentNotifyUrl和notifyUrl讲处理结果POST到用户业务服务器,用户那边设置解析打印出处理结果就可以了。 那么问题来了,有的用户在使用过程中出现接受不到处理的结果,这种情况一般都是用户那边自己的问题,那应该怎样处理呢? -1.检查下用户设置的persistentNotifyUrl以及notifyUrl,必须是公网上可以正常进行POST请求并能响应HTTP/1.1 200 OK的有效URL,可以使用curl访问下看是否满足这个条件。 +1.检查下用户设置的persistentNotifyUrl以及notifyUrl,必须是公网上可以正常进行POST请求并能响应HTTP/1.1 200 +OK的有效URL,可以使用curl访问下看是否满足这个条件。 另外,七牛这边发送body格式为Content-Type为"application/json"的POST请求,用户回调服务器需要按照读取流的形式读取请求的body才能获取。 2.如果第一个条件满足的情况,我们可以检测下用户后端设定的接收回调处理的程序是否是正常的,对此,我们可以主动POST一个数据给用户的回调服务器: @@ -17,10 +19,12 @@ eg:curl -vX POST "URL" -d "name=123.jpg" 用户那边如果能够正常打印出该内容,说明用户的接收程序是没有问题的。 3.如果以上条件都没有问题的情况下,应该是用户持续化处理本身的代码是有问题的,应该是用户设置的persistentNotifyUrl或者notifyurl没有设置成功,这个时候我们可以让用户在程序里面调试打印下这个URL的值,或者提供下返回的persistentID我们可以请求下获得ReqID然后在日志机上查询下是否是正确的,比如,之前查到的一个结果如下: -url.Values{"notifyURL":[]string{""}, "force":[]string{""} +url.Values{"notifyURL":[]string{""}, "force":[]string{""}} 这就明显看出用户设置的notifyURL是没有传进去的。 -这时,我们可以让用户提供下代码,检查下用户代码参数设置是否是有问题的,因为,**不同的语言对于notifyURL参数的写法是有问题的,比如java里面写法是notifyURL,而PHP里面该字段是notifyUrl**,经排查果然,用户用的是PHP语言,但是里面设置notifyURL字段应该是: +这时,我们可以让用户提供下代码,检查下用户代码参数设置是否是有问题的,因为,* +*不同的语言对于notifyURL参数的写法是有问题的,比如java里面写法是notifyURL,而PHP里面该字段是notifyUrl** +,经排查果然,用户用的是PHP语言,但是里面设置notifyURL字段应该是: $notifyUrl = 'http://notify.fake.com'; 但用户设置的是$notifyURL,参数设置是有问题的 diff --git a/mvn_push.gradle b/mvn_push.gradle index cd8dc8a8d..498af0602 100644 --- a/mvn_push.gradle +++ b/mvn_push.gradle @@ -54,8 +54,8 @@ task docJar(type: Jar, dependsOn: javadocs) { } publishing { - publications{ - mavenJava(MavenPublication){ + publications { + mavenJava(MavenPublication) { groupId = GROUP artifactId = POM_ARTIFACT_ID @@ -90,9 +90,9 @@ publishing { } } scm { - connection= POM_SCM_CONNECTION - developerConnection=POM_SCM_DEV_CONNECTION - url=POM_SCM_URL + connection = POM_SCM_CONNECTION + developerConnection = POM_SCM_DEV_CONNECTION + url = POM_SCM_URL } } } diff --git a/src/main/java/com/qiniu/audit/apis/ApiQueryLog.java b/src/main/java/com/qiniu/audit/apis/ApiQueryLog.java new file mode 100644 index 000000000..b4fcdf716 --- /dev/null +++ b/src/main/java/com/qiniu/audit/apis/ApiQueryLog.java @@ -0,0 +1,643 @@ +package com.qiniu.audit.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 审计日志查询 + */ +public class ApiQueryLog extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiQueryLog(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiQueryLog(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 检索日志的开始时间,日期格式按照 ISO8601 标准,并使用 UTC 时间 + */ + private String startTime; + + /** + * 检索日志的结束时间,日期格式按照 ISO8601 标准,并使用 UTC 时间 + */ + private String endTime; + + /** + * 服务名称,参考 https://developer.qiniu.com/af/12434/audit-log-events + */ + private String serviceName = null; + + /** + * 事件名称集合,参考 https://developer.qiniu.com/af/12434/audit-log-events + */ + private String eventNames = null; + + /** + * 请求者的 ID,参考 https://developer.qiniu.com/af/manual/12433/audit-log-object + */ + private String principalId = null; + + /** + * 请求身份所属的 AccessKey ID + */ + private String accessKeyId = null; + + /** + * 允许返回的最大结果数目,取值范围:1~50,不传值默认为:20 + */ + private Integer limit = null; + + /** + * 用于请求下一页检索的结果 + */ + private String nextMark = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param startTime 检索日志的开始时间,日期格式按照 ISO8601 标准,并使用 UTC 时间 【必须】 + * @param endTime 检索日志的结束时间,日期格式按照 ISO8601 标准,并使用 UTC 时间 【必须】 + */ + public Request(String urlPrefix, String startTime, String endTime) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.startTime = startTime; + this.endTime = endTime; + } + + /** + * 设置参数【可选】 + * + * @param serviceName 服务名称,参考 https://developer.qiniu.com/af/12434/audit-log-events + * @return Request + */ + public Request setServiceName(String serviceName) { + this.serviceName = serviceName; + return this; + } + + /** + * 设置参数【可选】 + * + * @param eventNames 事件名称集合,参考 https://developer.qiniu.com/af/12434/audit-log-events + * @return Request + */ + public Request setEventNames(String eventNames) { + this.eventNames = eventNames; + return this; + } + + /** + * 设置参数【可选】 + * + * @param principalId 请求者的 ID,参考 https://developer.qiniu.com/af/manual/12433/audit-log-object + * @return Request + */ + public Request setPrincipalId(String principalId) { + this.principalId = principalId; + return this; + } + + /** + * 设置参数【可选】 + * + * @param accessKeyId 请求身份所属的 AccessKey ID + * @return Request + */ + public Request setAccessKeyId(String accessKeyId) { + this.accessKeyId = accessKeyId; + return this; + } + + /** + * 设置参数【可选】 + * + * @param limit 允许返回的最大结果数目,取值范围:1~50,不传值默认为:20 + * @return Request + */ + public Request setLimit(Integer limit) { + this.limit = limit; + return this; + } + + /** + * 设置参数【可选】 + * + * @param nextMark 用于请求下一页检索的结果 + * @return Request + */ + public Request setNextMark(String nextMark) { + this.nextMark = nextMark; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.startTime == null) { + throw new QiniuException(new NullPointerException("startTime can't empty")); + } + if (this.endTime == null) { + throw new QiniuException(new NullPointerException("endTime can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("audit/log-query"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + addQueryPair("start_time", this.startTime); + addQueryPair("end_time", this.endTime); + if (this.serviceName != null) { + addQueryPair("service_name", this.serviceName); + } + if (this.eventNames != null) { + addQueryPair("event_names", this.eventNames); + } + if (this.principalId != null) { + addQueryPair("principal_id", this.principalId); + } + if (this.accessKeyId != null) { + addQueryPair("access_key_id", this.accessKeyId); + } + if (this.limit != null) { + addQueryPair("limit", this.limit); + } + if (this.nextMark != null) { + addQueryPair("next_mark", this.nextMark); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * + */ + private QueryLogResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), QueryLogResp.class); + } + + /** + * 响应信息 + * + * @return QueryLogResp + */ + public QueryLogResp getData() { + return this.data; + } + + /** + * 返回的请求者的身份信息 + */ + public static final class UserIdentify { + + /** + * 当前请求所属的七牛云账号 ID + */ + @SerializedName("account_id") + private String accountId; + + /** + * 当前请求者的 ID,需结合 principal_type 来确认请求者身份 + */ + @SerializedName("principal_id") + private String principalId; + + /** + * 请求者身份类型,仅支持 UNKNOWN 表示未知,ROOT_USER 表示七牛云账户 ID,IAM_USER 表示 IAM 子账户 ID,QINIU_ACCOUNT 表示当七牛云账号跨账号操作时,记录七牛云账号 ID + */ + @SerializedName("principal_type") + private String principalType; + + /** + * 当前请求身份所属的 AccessKey ID + */ + @SerializedName("access_key_id") + private String accessKeyId; + + /** + * 获取变量值 + * 当前请求所属的七牛云账号 ID + * + * @return accountId + */ + public String getAccountId() { + return this.accountId; + } + + /** + * 获取变量值 + * 当前请求者的 ID,需结合 principal_type 来确认请求者身份 + * + * @return principalId + */ + public String getPrincipalId() { + return this.principalId; + } + + /** + * 获取变量值 + * 请求者身份类型,仅支持 UNKNOWN 表示未知,ROOT_USER 表示七牛云账户 ID,IAM_USER 表示 IAM 子账户 ID,QINIU_ACCOUNT 表示当七牛云账号跨账号操作时,记录七牛云账号 ID + * + * @return principalType + */ + public String getPrincipalType() { + return this.principalType; + } + + /** + * 获取变量值 + * 当前请求身份所属的 AccessKey ID + * + * @return accessKeyId + */ + public String getAccessKeyId() { + return this.accessKeyId; + } + } + + /** + * 返回的审计日志 + */ + public static final class LogInfo { + + /** + * 日志 ID + */ + @SerializedName("event_id") + private String eventId; + + /** + * 事件类型,仅支持 UNKNOWN 表示未知,CONSOLE 表示控制台事件,API 表示 API 事件 + */ + @SerializedName("event_type") + private String eventType; + + /** + * 事件发生时间(UTC 格式) + */ + @SerializedName("event_time") + private String eventTime; + + /** + * 请求者的身份信息 + */ + @SerializedName("user_identity") + private UserIdentify userIdentity; + + /** + * 读写类型,仅支持 UNKNOWN 表示未知,READ 表示读,WRITE 表示写 + */ + @SerializedName("event_rw") + private String eventRw; + + /** + * 服务名称 + */ + @SerializedName("service_name") + private String serviceName; + + /** + * 事件名称 + */ + @SerializedName("event_name") + private String eventName; + + /** + * 源 IP 地址 + */ + @SerializedName("source_ip") + private String sourceIp; + + /** + * 客户端代理 + */ + @SerializedName("user_agent") + private String userAgent; + + /** + * 操作的资源名称列表 + */ + @SerializedName("resource_names") + private String[] resourceNames; + + /** + * 请求 ID + */ + @SerializedName("request_id") + private String requestId; + + /** + * 请求 URL + */ + @SerializedName("request_url") + private String requestUrl; + + /** + * 请求的输入参数 + */ + @SerializedName("request_params") + private String requestParams; + + /** + * 请求的返回数据 + */ + @SerializedName("response_data") + private String responseData; + + /** + * 请求的返回码 + */ + @SerializedName("response_code") + private Integer responseCode; + + /** + * 请求的返回信息 + */ + @SerializedName("response_message") + private String responseMessage; + + /** + * 额外备注信息 + */ + @SerializedName("additional_event_data") + private String additionalEventData; + + /** + * 获取变量值 + * 日志 ID + * + * @return eventId + */ + public String getEventId() { + return this.eventId; + } + + /** + * 获取变量值 + * 事件类型,仅支持 UNKNOWN 表示未知,CONSOLE 表示控制台事件,API 表示 API 事件 + * + * @return eventType + */ + public String getEventType() { + return this.eventType; + } + + /** + * 获取变量值 + * 事件发生时间(UTC 格式) + * + * @return eventTime + */ + public String getEventTime() { + return this.eventTime; + } + + /** + * 获取变量值 + * 请求者的身份信息 + * + * @return userIdentity + */ + public UserIdentify getUserIdentity() { + return this.userIdentity; + } + + /** + * 获取变量值 + * 读写类型,仅支持 UNKNOWN 表示未知,READ 表示读,WRITE 表示写 + * + * @return eventRw + */ + public String getEventRw() { + return this.eventRw; + } + + /** + * 获取变量值 + * 服务名称 + * + * @return serviceName + */ + public String getServiceName() { + return this.serviceName; + } + + /** + * 获取变量值 + * 事件名称 + * + * @return eventName + */ + public String getEventName() { + return this.eventName; + } + + /** + * 获取变量值 + * 源 IP 地址 + * + * @return sourceIp + */ + public String getSourceIp() { + return this.sourceIp; + } + + /** + * 获取变量值 + * 客户端代理 + * + * @return userAgent + */ + public String getUserAgent() { + return this.userAgent; + } + + /** + * 获取变量值 + * 操作的资源名称列表 + * + * @return resourceNames + */ + public String[] getResourceNames() { + return this.resourceNames; + } + + /** + * 获取变量值 + * 请求 ID + * + * @return requestId + */ + public String getRequestId() { + return this.requestId; + } + + /** + * 获取变量值 + * 请求 URL + * + * @return requestUrl + */ + public String getRequestUrl() { + return this.requestUrl; + } + + /** + * 获取变量值 + * 请求的输入参数 + * + * @return requestParams + */ + public String getRequestParams() { + return this.requestParams; + } + + /** + * 获取变量值 + * 请求的返回数据 + * + * @return responseData + */ + public String getResponseData() { + return this.responseData; + } + + /** + * 获取变量值 + * 请求的返回码 + * + * @return responseCode + */ + public Integer getResponseCode() { + return this.responseCode; + } + + /** + * 获取变量值 + * 请求的返回信息 + * + * @return responseMessage + */ + public String getResponseMessage() { + return this.responseMessage; + } + + /** + * 获取变量值 + * 额外备注信息 + * + * @return additionalEventData + */ + public String getAdditionalEventData() { + return this.additionalEventData; + } + } + + /** + * + */ + public static final class QueryLogResp { + + /** + * 用于请求下一页检索的结果 + */ + @SerializedName("next_mark") + private String nextMark; + + /** + * 日志集合 + */ + @SerializedName("audit_log_infos") + private LogInfo[] auditLogInfos; + + /** + * 获取变量值 + * 用于请求下一页检索的结果 + * + * @return nextMark + */ + public String getNextMark() { + return this.nextMark; + } + + /** + * 获取变量值 + * 日志集合 + * + * @return auditLogInfos + */ + public LogInfo[] getAuditLogInfos() { + return this.auditLogInfos; + } + } + } +} diff --git a/src/main/java/com/qiniu/common/QiniuException.java b/src/main/java/com/qiniu/common/QiniuException.java index bad0bef31..9b52258a0 100644 --- a/src/main/java/com/qiniu/common/QiniuException.java +++ b/src/main/java/com/qiniu/common/QiniuException.java @@ -23,6 +23,16 @@ public QiniuException(Response response) { } } + public QiniuException(Exception e) { + this(e, null); + } + + public QiniuException(Exception e, String msg) { + super(msg != null ? msg : (e != null ? e.getMessage() : null), e); + this.response = null; + this.error = msg; + } + public static QiniuException unrecoverable(Exception e) { QiniuException exception = new QiniuException(e); exception.isUnrecoverable = true; @@ -35,16 +45,6 @@ public static QiniuException unrecoverable(String msg) { return exception; } - public QiniuException(Exception e) { - this(e, null); - } - - public QiniuException(Exception e, String msg) { - super(msg != null ? msg : (e != null ? e.getMessage() : null), e); - this.response = null; - this.error = msg; - } - public String url() { return response != null ? response.url() : ""; } diff --git a/src/main/java/com/qiniu/common/Zone.java b/src/main/java/com/qiniu/common/Zone.java index 5927a30bf..ccf0d42bf 100644 --- a/src/main/java/com/qiniu/common/Zone.java +++ b/src/main/java/com/qiniu/common/Zone.java @@ -35,6 +35,7 @@ public class Zone { /** * 华东机房相关域名 + * * @return 域名信息 */ public static Zone zone0() { @@ -50,6 +51,7 @@ public static Zone zone0() { /** * 华东机房相关域名 + * * @return 域名信息 */ public static Zone huadong() { @@ -58,6 +60,7 @@ public static Zone huadong() { /** * 华东机房内网上传相关域名 + * * @return 域名信息 */ public static Zone qvmZone0() { @@ -73,6 +76,7 @@ public static Zone qvmZone0() { /** * 华东机房内网上传相关域名 + * * @return 域名信息 */ public static Zone qvmHuadong() { @@ -81,6 +85,7 @@ public static Zone qvmHuadong() { /** * 华北机房相关域名 + * * @return 域名信息 */ public static Zone zone1() { @@ -96,6 +101,7 @@ public static Zone zone1() { /** * 华北机房相关域名 + * * @return 域名信息 */ public static Zone huabei() { @@ -104,6 +110,7 @@ public static Zone huabei() { /** * 华北机房内网上传相关域名 + * * @return 域名信息 */ public static Zone qvmZone1() { @@ -119,6 +126,7 @@ public static Zone qvmZone1() { /** * 华北机房内网上传相关域名 + * * @return 域名信息 */ public static Zone qvmHuabei() { @@ -127,6 +135,7 @@ public static Zone qvmHuabei() { /** * 华南机房相关域名 + * * @return 域名信息 */ public static Zone zone2() { @@ -142,6 +151,7 @@ public static Zone zone2() { /** * 华南机房相关域名 + * * @return 域名信息 */ public static Zone huanan() { @@ -150,6 +160,7 @@ public static Zone huanan() { /** * 北美机房相关域名 + * * @return 域名信息 */ public static Zone zoneNa0() { @@ -165,6 +176,7 @@ public static Zone zoneNa0() { /** * 北美机房相关域名 + * * @return 域名信息 */ public static Zone beimei() { @@ -173,6 +185,7 @@ public static Zone beimei() { /** * 新加坡相关域名 + * * @return 域名信息 */ public static Zone zoneAs0() { @@ -188,6 +201,7 @@ public static Zone zoneAs0() { /** * 新加坡机房相关域名 + * * @return 域名信息 */ public static Zone xinjiapo() { @@ -217,7 +231,7 @@ public String getRegion(ZoneReqInfo zoneReqInfo) { /** * 获取上传 HTTP URL * - * @param zoneReqInfo token 信息 + * @param zoneReqInfo token 信息 * @return URL */ public String getUpHttp(ZoneReqInfo zoneReqInfo) { @@ -227,7 +241,7 @@ public String getUpHttp(ZoneReqInfo zoneReqInfo) { /** * 获取上传 HTTPS URL * - * @param zoneReqInfo token 信息 + * @param zoneReqInfo token 信息 * @return URL */ public String getUpHttps(ZoneReqInfo zoneReqInfo) { @@ -237,7 +251,7 @@ public String getUpHttps(ZoneReqInfo zoneReqInfo) { /** * 获取备用上传 HTTP URL * - * @param zoneReqInfo token 信息 + * @param zoneReqInfo token 信息 * @return URL */ public String getUpBackupHttp(ZoneReqInfo zoneReqInfo) { @@ -247,7 +261,7 @@ public String getUpBackupHttp(ZoneReqInfo zoneReqInfo) { /** * 获取备用上传 HTTPS URL * - * @param zoneReqInfo token 信息 + * @param zoneReqInfo token 信息 * @return URL */ public String getUpBackupHttps(ZoneReqInfo zoneReqInfo) { diff --git a/src/main/java/com/qiniu/http/Client.java b/src/main/java/com/qiniu/http/Client.java index b46df80e5..224a4199b 100755 --- a/src/main/java/com/qiniu/http/Client.java +++ b/src/main/java/com/qiniu/http/Client.java @@ -425,7 +425,8 @@ public void accept(String key, Object value) { double duration = (System.currentTimeMillis() - start) / 1000.0; r = Response.create(res, tag.ip, duration); - if (r.statusCode >= 300) { + // 如果读取 body 失败也抛出异常 + if (r.statusCode >= 300 || !StringUtils.isNullOrEmpty(r.error)) { throw new QiniuException(r); } diff --git a/src/main/java/com/qiniu/http/MethodType.java b/src/main/java/com/qiniu/http/MethodType.java index df2a78e0a..aa9b5b396 100644 --- a/src/main/java/com/qiniu/http/MethodType.java +++ b/src/main/java/com/qiniu/http/MethodType.java @@ -4,7 +4,8 @@ public enum MethodType { GET(false), PUT(true), POST(true), - DELETE(false), + PATCH(true), + DELETE(true), HEAD(false), OPTIONS(false); @@ -28,12 +29,18 @@ public String toString() { case POST: m = "POST"; break; + case PATCH: + m = "PATCH"; + break; case HEAD: m = "HEAD"; break; case DELETE: m = "DELETE"; break; + case OPTIONS: + m = "OPTIONS"; + break; default: m = "GET"; } diff --git a/src/main/java/com/qiniu/http/RequestStreamBody.java b/src/main/java/com/qiniu/http/RequestStreamBody.java index 137e5bebf..35d7240d8 100644 --- a/src/main/java/com/qiniu/http/RequestStreamBody.java +++ b/src/main/java/com/qiniu/http/RequestStreamBody.java @@ -12,10 +12,10 @@ public class RequestStreamBody extends RequestBody { - private long limitSize = -1; - private long sinkSize = 1024 * 100; private final MediaType type; private final InputStream stream; + private long limitSize = -1; + private long sinkSize = 1024 * 100; /** * 构造函数 diff --git a/src/main/java/com/qiniu/http/Response.java b/src/main/java/com/qiniu/http/Response.java index e09ee5ed8..40d4b7d0e 100644 --- a/src/main/java/com/qiniu/http/Response.java +++ b/src/main/java/com/qiniu/http/Response.java @@ -71,20 +71,19 @@ private Response(okhttp3.Response response, int statusCode, String reqId, String this.method = getMethod(response); } - private String getMethod(okhttp3.Response response) { - String method = null; - if (response != null) { - Request req = response.request(); - if (req != null) { - method = req.method(); - } - } - if (method == null) { - method = ""; - } - return method; - } - + /*** + * 构造请求方法,此处可能会尝试读取 body,如果 body 读取失败会保留原始的 + * 状态码,因此判断请求是否成功使用 Response.isOK() + *

+ * SDK 内部处理: + * 同步请求,请求失败会抛异常 + * 异步请求,判断请求是否成功使用 Response.isOK() + * + * @param response okhttp3 请求 response + * @param address 请求 address + * @param duration 请求耗时 + * @return com.qiniu.http.Response 七牛 Response + **/ public static Response create(okhttp3.Response response, String address, double duration) { String error = null; int code = response.code(); @@ -148,16 +147,11 @@ public static Response createError(okhttp3.Response response, String address, do address, duration, error, body); } - public okhttp3.Response getResponse() { - return response; - } - public static Response createSuccessResponse() { return new Response(null, 200, "inter:reqId", null, "inter:via", null, 0, null, new byte[0]); } - private static String via(okhttp3.Response response) { String via; if (!(via = response.header("X-Via", "")).equals("")) { @@ -182,6 +176,24 @@ private static String ctype(okhttp3.Response response) { return mediaType.type() + "/" + mediaType.subtype(); } + private String getMethod(okhttp3.Response response) { + String method = null; + if (response != null) { + Request req = response.request(); + if (req != null) { + method = req.method(); + } + } + if (method == null) { + method = ""; + } + return method; + } + + public okhttp3.Response getResponse() { + return response; + } + public boolean isOK() { return statusCode == 200 && error == null && reqId != null && reqId.length() > 0; } diff --git a/src/main/java/com/qiniu/iam/apis/ApiCreateGroup.java b/src/main/java/com/qiniu/iam/apis/ApiCreateGroup.java new file mode 100644 index 000000000..3f308381b --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiCreateGroup.java @@ -0,0 +1,312 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 新建用户分组 + */ +public class ApiCreateGroup extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiCreateGroup(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiCreateGroup(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 创建用户分组参数 + */ + private CreateGroupParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param data 创建用户分组参数 【必须】 + */ + public Request(String urlPrefix, CreateGroupParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 创建用户分组参数 + */ + public static final class CreateGroupParam { + + /** + * 用户分组别名,由 `A-Za-z0-9` 组成 + */ + @SerializedName("alias") + private String alias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 设置变量值 + * + * @param alias 用户分组别名,由 `A-Za-z0-9` 组成 + * @return Request + */ + public CreateGroupParam setAlias(String alias) { + this.alias = alias; + return this; + } + + /** + * 设置变量值 + * + * @param description 用户分组描述 + * @return Request + */ + public CreateGroupParam setDescription(String description) { + this.description = description; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的用户分组响应 + */ + private CreatedGroupResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), CreatedGroupResp.class); + } + + /** + * 响应信息 + * + * @return CreatedGroupResp + */ + public CreatedGroupResp getData() { + return this.data; + } + + /** + * 返回的用户分组信息 + */ + public static final class CreatedGroupData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 用户分组别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 用户分组是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 用户分组创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 用户分组上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 用户分组别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 用户分组描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 用户分组是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 用户分组创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 用户分组上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + } + + /** + * 返回的用户分组响应 + */ + public static final class CreatedGroupResp { + + /** + * 用户分组信息 + */ + @SerializedName("data") + private CreatedGroupData data; + + /** + * 获取变量值 + * 用户分组信息 + * + * @return data + */ + public CreatedGroupData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiCreatePolicy.java b/src/main/java/com/qiniu/iam/apis/ApiCreatePolicy.java new file mode 100644 index 000000000..c8e8018a0 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiCreatePolicy.java @@ -0,0 +1,473 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 新建授权策略 + */ +public class ApiCreatePolicy extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiCreatePolicy(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiCreatePolicy(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 创建授权策略参数 + */ + private CreatePolicyParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param data 创建授权策略参数 【必须】 + */ + public Request(String urlPrefix, CreatePolicyParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 授权策略规则 + */ + public static final class CreateStatement { + + /** + * 授权策略规则的操作集合,action 查询参考 action 接口,格式为 service/action_alias + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合,格式为 qrn:product:region:uid:[resource-type/]resource-id ;可以简写为 qrn:product:::resource-id + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 设置变量值 + * + * @param actions 授权策略规则的操作集合,action 查询参考 action 接口,格式为 service/action_alias + * @return Request + */ + public CreateStatement setActions(String[] actions) { + this.actions = actions; + return this; + } + + /** + * 设置变量值 + * + * @param resources 授权策略规则的资源集合,格式为 qrn:product:region:uid:[resource-type/]resource-id ;可以简写为 qrn:product:::resource-id + * @return Request + */ + public CreateStatement setResources(String[] resources) { + this.resources = resources; + return this; + } + + /** + * 设置变量值 + * + * @param effect 授权策略规则的生效类型,允许访问或拒绝访问 + * @return Request + */ + public CreateStatement setEffect(String effect) { + this.effect = effect; + return this; + } + } + + /** + * 创建授权策略参数 + */ + public static final class CreatePolicyParam { + + /** + * 授权策略别名,由 `A-Za-z0-9` 组成 + */ + @SerializedName("alias") + private String alias; + + /** + * 1:是通过自定义 JSON 编辑的策略 2:是通过 UI 编辑的策略 + */ + @SerializedName("edit_type") + private Integer editType; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private CreateStatement[] statement; + + /** + * 设置变量值 + * + * @param alias 授权策略别名,由 `A-Za-z0-9` 组成 + * @return Request + */ + public CreatePolicyParam setAlias(String alias) { + this.alias = alias; + return this; + } + + /** + * 设置变量值 + * + * @param editType 1:是通过自定义 JSON 编辑的策略 2:是通过 UI 编辑的策略 + * @return Request + */ + public CreatePolicyParam setEditType(Integer editType) { + this.editType = editType; + return this; + } + + /** + * 设置变量值 + * + * @param description 授权策略描述 + * @return Request + */ + public CreatePolicyParam setDescription(String description) { + this.description = description; + return this; + } + + /** + * 设置变量值 + * + * @param statement 授权策略规则集合 + * @return Request + */ + public CreatePolicyParam setStatement(CreateStatement[] statement) { + this.statement = statement; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的授权策略响应 + */ + private CreatedPolicyResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), CreatedPolicyResp.class); + } + + /** + * 响应信息 + * + * @return CreatedPolicyResp + */ + public CreatedPolicyResp getData() { + return this.data; + } + + /** + * 授权策略规则 + */ + public static final class CreatedStatement { + + /** + * 授权策略规则的操作集合 + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合 + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 获取变量值 + * 授权策略规则的操作集合 + * + * @return actions + */ + public String[] getActions() { + return this.actions; + } + + /** + * 获取变量值 + * 授权策略规则的资源集合 + * + * @return resources + */ + public String[] getResources() { + return this.resources; + } + + /** + * 获取变量值 + * 授权策略规则的生效类型,允许访问或拒绝访问 + * + * @return effect + */ + public String getEffect() { + return this.effect; + } + } + + /** + * 返回的授权策略信息 + */ + public static final class CreatedPolicyData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 授权策略别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 授权策略创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 授权策略上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private CreatedStatement[] statement; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 授权策略别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 授权策略描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 授权策略是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 授权策略创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 授权策略上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 授权策略规则集合 + * + * @return statement + */ + public CreatedStatement[] getStatement() { + return this.statement; + } + } + + /** + * 返回的授权策略响应 + */ + public static final class CreatedPolicyResp { + + /** + * 授权策略信息 + */ + @SerializedName("data") + private CreatedPolicyData data; + + /** + * 获取变量值 + * 授权策略信息 + * + * @return data + */ + public CreatedPolicyData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiCreateUser.java b/src/main/java/com/qiniu/iam/apis/ApiCreateUser.java new file mode 100644 index 000000000..025a4f93e --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiCreateUser.java @@ -0,0 +1,328 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 创建 IAM 子账号 + */ +public class ApiCreateUser extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiCreateUser(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiCreateUser(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 创建 IAM 子账号参数 + */ + private CreateIamUserParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param data 创建 IAM 子账号参数 【必须】 + */ + public Request(String urlPrefix, CreateIamUserParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 创建 IAM 子账号参数 + */ + public static final class CreateIamUserParam { + + /** + * 子账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 子账号密码 + */ + @SerializedName("password") + private String password; + + /** + * 设置变量值 + * + * @param alias 子账号别名 + * @return Request + */ + public CreateIamUserParam setAlias(String alias) { + this.alias = alias; + return this; + } + + /** + * 设置变量值 + * + * @param password 子账号密码 + * @return Request + */ + public CreateIamUserParam setPassword(String password) { + this.password = password; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号响应 + */ + private CreatedIamUserResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), CreatedIamUserResp.class); + } + + /** + * 响应信息 + * + * @return CreatedIamUserResp + */ + public CreatedIamUserResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号信息 + */ + public static final class CreatedIamUserData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 子账号 uid + */ + @SerializedName("iuid") + private Integer iuid; + + /** + * 子账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 子账号创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("last_login_time") + private String lastLoginTime; + + /** + * 子账号是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 子账号 uid + * + * @return iuid + */ + public Integer getIuid() { + return this.iuid; + } + + /** + * 获取变量值 + * 子账号别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 子账号创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return lastLoginTime + */ + public String getLastLoginTime() { + return this.lastLoginTime; + } + + /** + * 获取变量值 + * 子账号是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的 IAM 子账号响应 + */ + public static final class CreatedIamUserResp { + + /** + * IAM 子账号信息 + */ + @SerializedName("data") + private CreatedIamUserData data; + + /** + * 获取变量值 + * IAM 子账号信息 + * + * @return data + */ + public CreatedIamUserData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiCreateUserKeypairs.java b/src/main/java/com/qiniu/iam/apis/ApiCreateUserKeypairs.java new file mode 100644 index 000000000..eed8e7e6a --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiCreateUserKeypairs.java @@ -0,0 +1,256 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 创建 IAM 子账号密钥 + */ +public class ApiCreateUserKeypairs extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiCreateUserKeypairs(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiCreateUserKeypairs(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("keypairs"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号密钥响应 + */ + private CreatedIamUserKeyPairResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), CreatedIamUserKeyPairResp.class); + } + + /** + * 响应信息 + * + * @return CreatedIamUserKeyPairResp + */ + public CreatedIamUserKeyPairResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号密钥信息 + */ + public static final class CreatedIamUserKeyPairData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * IAM 子账号 Access Key + */ + @SerializedName("access_key") + private String accessKey; + + /** + * IAM 子账号 Secret Key + */ + @SerializedName("secret_key") + private String secretKey; + + /** + * 关联用户的记录 ID + */ + @SerializedName("user_id") + private String userId; + + /** + * 密钥创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 密钥是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * IAM 子账号 Access Key + * + * @return accessKey + */ + public String getAccessKey() { + return this.accessKey; + } + + /** + * 获取变量值 + * IAM 子账号 Secret Key + * + * @return secretKey + */ + public String getSecretKey() { + return this.secretKey; + } + + /** + * 获取变量值 + * 关联用户的记录 ID + * + * @return userId + */ + public String getUserId() { + return this.userId; + } + + /** + * 获取变量值 + * 密钥创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 密钥是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的 IAM 子账号密钥响应 + */ + public static final class CreatedIamUserKeyPairResp { + + /** + * IAM 子账号密钥信息 + */ + @SerializedName("data") + private CreatedIamUserKeyPairData data; + + /** + * 获取变量值 + * IAM 子账号密钥信息 + * + * @return data + */ + public CreatedIamUserKeyPairData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDeleteGroup.java b/src/main/java/com/qiniu/iam/apis/ApiDeleteGroup.java new file mode 100644 index 000000000..549a78bfa --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDeleteGroup.java @@ -0,0 +1,114 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; + + +/** + * 删除用户分组 + */ +public class ApiDeleteGroup extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDeleteGroup(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDeleteGroup(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.DELETE); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDeleteGroupPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiDeleteGroupPolicies.java new file mode 100644 index 000000000..b240886cf --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDeleteGroupPolicies.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 从用户分组中删除授权策略 + */ +public class ApiDeleteGroupPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDeleteGroupPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDeleteGroupPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 从用户分组中删除授权策略参数 + */ + private DeletedGroupIamPoliciesParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + * @param data 从用户分组中删除授权策略参数 【必须】 + */ + public Request(String urlPrefix, String alias, DeletedGroupIamPoliciesParam data) { + super(urlPrefix); + this.setMethod(MethodType.PATCH); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 从用户分组中删除授权策略参数 + */ + public static final class DeletedGroupIamPoliciesParam { + + /** + * 授权策略别名集合 + */ + @SerializedName("policy_aliases") + private String[] policyAliases; + + /** + * 设置变量值 + * + * @param policyAliases 授权策略别名集合 + * @return Request + */ + public DeletedGroupIamPoliciesParam setPolicyAliases(String[] policyAliases) { + this.policyAliases = policyAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDeleteGroupUsers.java b/src/main/java/com/qiniu/iam/apis/ApiDeleteGroupUsers.java new file mode 100644 index 000000000..86f1a2316 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDeleteGroupUsers.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 从用户分组中删除 IAM 子账号 + */ +public class ApiDeleteGroupUsers extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDeleteGroupUsers(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDeleteGroupUsers(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 从用户分组删除 IAM 子账号参数 + */ + private DeletedGroupIamUsersParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + * @param data 从用户分组删除 IAM 子账号参数 【必须】 + */ + public Request(String urlPrefix, String alias, DeletedGroupIamUsersParam data) { + super(urlPrefix); + this.setMethod(MethodType.DELETE); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 从用户分组删除 IAM 子账号参数 + */ + public static final class DeletedGroupIamUsersParam { + + /** + * IAM 子账号别名集合 + */ + @SerializedName("user_aliases") + private String[] userAliases; + + /** + * 设置变量值 + * + * @param userAliases IAM 子账号别名集合 + * @return Request + */ + public DeletedGroupIamUsersParam setUserAliases(String[] userAliases) { + this.userAliases = userAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDeletePolicy.java b/src/main/java/com/qiniu/iam/apis/ApiDeletePolicy.java new file mode 100644 index 000000000..33085e89e --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDeletePolicy.java @@ -0,0 +1,114 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; + + +/** + * 删除指定的授权策略 + */ +public class ApiDeletePolicy extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDeletePolicy(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDeletePolicy(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 授权策略别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 授权策略别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.DELETE); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDeleteUser.java b/src/main/java/com/qiniu/iam/apis/ApiDeleteUser.java new file mode 100644 index 000000000..de8ff091d --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDeleteUser.java @@ -0,0 +1,114 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; + + +/** + * 删除 IAM 子账号 + */ +public class ApiDeleteUser extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDeleteUser(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDeleteUser(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.DELETE); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDeleteUserKeypair.java b/src/main/java/com/qiniu/iam/apis/ApiDeleteUserKeypair.java new file mode 100644 index 000000000..c64c979e4 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDeleteUserKeypair.java @@ -0,0 +1,126 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; + + +/** + * 删除 IAM 子账号密钥 + */ +public class ApiDeleteUserKeypair extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDeleteUserKeypair(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDeleteUserKeypair(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * IAM 子账号 Access Key + */ + private String accessKey; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param accessKey IAM 子账号 Access Key 【必须】 + */ + public Request(String urlPrefix, String alias, String accessKey) { + super(urlPrefix); + this.setMethod(MethodType.DELETE); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.accessKey = accessKey; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.accessKey == null) { + throw new QiniuException(new NullPointerException("accessKey can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("keypairs"); + addPathSegment(this.accessKey); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDeleteUserPolicy.java b/src/main/java/com/qiniu/iam/apis/ApiDeleteUserPolicy.java new file mode 100644 index 000000000..561670b32 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDeleteUserPolicy.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 删除 IAM 子账号特定的授权策略 + */ +public class ApiDeleteUserPolicy extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDeleteUserPolicy(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDeleteUserPolicy(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 为子账号删除授权策略参数 + */ + private DeletedIamUserPoliciesParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param data 为子账号删除授权策略参数 【必须】 + */ + public Request(String urlPrefix, String alias, DeletedIamUserPoliciesParam data) { + super(urlPrefix); + this.setMethod(MethodType.DELETE); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为子账号删除授权策略参数 + */ + public static final class DeletedIamUserPoliciesParam { + + /** + * 授权策略别名集合 + */ + @SerializedName("policy_aliases") + private String[] policyAliases; + + /** + * 设置变量值 + * + * @param policyAliases 授权策略别名集合 + * @return Request + */ + public DeletedIamUserPoliciesParam setPolicyAliases(String[] policyAliases) { + this.policyAliases = policyAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiDisableUserKeypair.java b/src/main/java/com/qiniu/iam/apis/ApiDisableUserKeypair.java new file mode 100644 index 000000000..25b30add3 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiDisableUserKeypair.java @@ -0,0 +1,127 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; + + +/** + * 禁用 IAM 子账号密钥 + */ +public class ApiDisableUserKeypair extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiDisableUserKeypair(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiDisableUserKeypair(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * IAM 子账号 Access Key + */ + private String accessKey; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param accessKey IAM 子账号 Access Key 【必须】 + */ + public Request(String urlPrefix, String alias, String accessKey) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.accessKey = accessKey; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.accessKey == null) { + throw new QiniuException(new NullPointerException("accessKey can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("keypairs"); + addPathSegment(this.accessKey); + addPathSegment("disable"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiEnableUserKeypair.java b/src/main/java/com/qiniu/iam/apis/ApiEnableUserKeypair.java new file mode 100644 index 000000000..d384da4a5 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiEnableUserKeypair.java @@ -0,0 +1,127 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; + + +/** + * 启用 IAM 子账号密钥 + */ +public class ApiEnableUserKeypair extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiEnableUserKeypair(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiEnableUserKeypair(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * IAM 子账号 Access Key + */ + private String accessKey; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param accessKey IAM 子账号 Access Key 【必须】 + */ + public Request(String urlPrefix, String alias, String accessKey) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.accessKey = accessKey; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.accessKey == null) { + throw new QiniuException(new NullPointerException("accessKey can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("keypairs"); + addPathSegment(this.accessKey); + addPathSegment("enable"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetActions.java b/src/main/java/com/qiniu/iam/apis/ApiGetActions.java new file mode 100644 index 000000000..4a8369830 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetActions.java @@ -0,0 +1,372 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询 IAM 的操作 + */ +public class ApiGetActions extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetActions(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetActions(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 操作对应的服务别名 + */ + private String service = null; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + */ + public Request(String urlPrefix) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + } + + /** + * 设置参数【可选】 + * + * @param service 操作对应的服务别名 + * @return Request + */ + public Request setService(String service) { + this.service = service; + return this; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/actions"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.service != null) { + addQueryPair("service", this.service); + } + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的接口操作列表响应 + */ + private GetActionsResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetActionsResp.class); + } + + /** + * 响应信息 + * + * @return GetActionsResp + */ + public GetActionsResp getData() { + return this.data; + } + + /** + * 返回的接口操作 + */ + public static final class GetAction { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 接口操作名称 + */ + @SerializedName("name") + private String name; + + /** + * 接口操作别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 接口操作对应的服务 + */ + @SerializedName("service") + private String service; + + /** + * 接口操作权限粒度,0: 操作级,不限制资源,1: 资源级,只能访问特定资源 + */ + @SerializedName("scope") + private Integer scope; + + /** + * 接口操作是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 接口操作创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 接口操作上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 接口操作名称 + * + * @return name + */ + public String getName() { + return this.name; + } + + /** + * 获取变量值 + * 接口操作别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 接口操作对应的服务 + * + * @return service + */ + public String getService() { + return this.service; + } + + /** + * 获取变量值 + * 接口操作权限粒度,0: 操作级,不限制资源,1: 资源级,只能访问特定资源 + * + * @return scope + */ + public Integer getScope() { + return this.scope; + } + + /** + * 获取变量值 + * 接口操作是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 接口操作创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 接口操作上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + } + + /** + * 返回的接口操作列表信息 + */ + public static final class GetActionsData { + + /** + * 接口操作数量 + */ + @SerializedName("count") + private Integer count; + + /** + * 接口操作列表 + */ + @SerializedName("list") + private GetAction[] list; + + /** + * 获取变量值 + * 接口操作数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * 接口操作列表 + * + * @return list + */ + public GetAction[] getList() { + return this.list; + } + } + + /** + * 返回的接口操作列表响应 + */ + public static final class GetActionsResp { + + /** + * 接口操作信息 + */ + @SerializedName("data") + private GetActionsData data; + + /** + * 获取变量值 + * 接口操作信息 + * + * @return data + */ + public GetActionsData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetAudits.java b/src/main/java/com/qiniu/iam/apis/ApiGetAudits.java new file mode 100644 index 000000000..d2cc0dfa8 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetAudits.java @@ -0,0 +1,531 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询审计日志列表 + */ +public class ApiGetAudits extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetAudits(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetAudits(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * IAM 子账号 UID + */ + private Integer iuid = null; + + /** + * 操作对应的服务别名 + */ + private String service = null; + + /** + * 操作别名 + */ + private String action = null; + + /** + * 操作别名 + */ + private String resource = null; + + /** + * 操作开始时间 + */ + private String startTime = null; + + /** + * 操作截止时间 + */ + private String endTime = null; + + /** + * 下页标记 + */ + private String marker = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer limit = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + */ + public Request(String urlPrefix) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + } + + /** + * 设置参数【可选】 + * + * @param iuid IAM 子账号 UID + * @return Request + */ + public Request setIuid(Integer iuid) { + this.iuid = iuid; + return this; + } + + /** + * 设置参数【可选】 + * + * @param service 操作对应的服务别名 + * @return Request + */ + public Request setService(String service) { + this.service = service; + return this; + } + + /** + * 设置参数【可选】 + * + * @param action 操作别名 + * @return Request + */ + public Request setAction(String action) { + this.action = action; + return this; + } + + /** + * 设置参数【可选】 + * + * @param resource 操作别名 + * @return Request + */ + public Request setResource(String resource) { + this.resource = resource; + return this; + } + + /** + * 设置参数【可选】 + * + * @param startTime 操作开始时间 + * @return Request + */ + public Request setStartTime(String startTime) { + this.startTime = startTime; + return this; + } + + /** + * 设置参数【可选】 + * + * @param endTime 操作截止时间 + * @return Request + */ + public Request setEndTime(String endTime) { + this.endTime = endTime; + return this; + } + + /** + * 设置参数【可选】 + * + * @param marker 下页标记 + * @return Request + */ + public Request setMarker(String marker) { + this.marker = marker; + return this; + } + + /** + * 设置参数【可选】 + * + * @param limit 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setLimit(Integer limit) { + this.limit = limit; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/audits"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.iuid != null) { + addQueryPair("iuid", this.iuid); + } + if (this.service != null) { + addQueryPair("service", this.service); + } + if (this.action != null) { + addQueryPair("action", this.action); + } + if (this.resource != null) { + addQueryPair("resource", this.resource); + } + if (this.startTime != null) { + addQueryPair("start_time", this.startTime); + } + if (this.endTime != null) { + addQueryPair("end_time", this.endTime); + } + if (this.marker != null) { + addQueryPair("marker", this.marker); + } + if (this.limit != null) { + addQueryPair("limit", this.limit); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的审计日志列表响应 + */ + private GetAuditLogsResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetAuditLogsResp.class); + } + + /** + * 响应信息 + * + * @return GetAuditLogsResp + */ + public GetAuditLogsResp getData() { + return this.data; + } + + /** + * 返回的审计日志 + */ + public static final class GetAuditLog { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 子账号 uid + */ + @SerializedName("iuid") + private Integer iuid; + + /** + * 接口操作对应的服务 + */ + @SerializedName("service") + private String service; + + /** + * 接口操作别名 + */ + @SerializedName("action") + private String action; + + /** + * 日志创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 请求发生时间 + */ + @SerializedName("event_time") + private String eventTime; + + /** + * 请求持续时间,毫秒 + */ + @SerializedName("duration_ms") + private Integer durationMs; + + /** + * 源 IP + */ + @SerializedName("source_ip") + private String sourceIp; + + /** + * 用户代理 + */ + @SerializedName("user_event") + private String userEvent; + + /** + * 错误码 + */ + @SerializedName("error_code") + private Integer errorCode; + + /** + * 错误消息 + */ + @SerializedName("error_message") + private String errorMessage; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 子账号 uid + * + * @return iuid + */ + public Integer getIuid() { + return this.iuid; + } + + /** + * 获取变量值 + * 接口操作对应的服务 + * + * @return service + */ + public String getService() { + return this.service; + } + + /** + * 获取变量值 + * 接口操作别名 + * + * @return action + */ + public String getAction() { + return this.action; + } + + /** + * 获取变量值 + * 日志创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 请求发生时间 + * + * @return eventTime + */ + public String getEventTime() { + return this.eventTime; + } + + /** + * 获取变量值 + * 请求持续时间,毫秒 + * + * @return durationMs + */ + public Integer getDurationMs() { + return this.durationMs; + } + + /** + * 获取变量值 + * 源 IP + * + * @return sourceIp + */ + public String getSourceIp() { + return this.sourceIp; + } + + /** + * 获取变量值 + * 用户代理 + * + * @return userEvent + */ + public String getUserEvent() { + return this.userEvent; + } + + /** + * 获取变量值 + * 错误码 + * + * @return errorCode + */ + public Integer getErrorCode() { + return this.errorCode; + } + + /** + * 获取变量值 + * 错误消息 + * + * @return errorMessage + */ + public String getErrorMessage() { + return this.errorMessage; + } + } + + /** + * 返回的审计日志列表信息 + */ + public static final class GetAuditLogsData { + + /** + * 下页标记 + */ + @SerializedName("marker") + private String marker; + + /** + * 审计日志列表 + */ + @SerializedName("list") + private GetAuditLog[] list; + + /** + * 获取变量值 + * 下页标记 + * + * @return marker + */ + public String getMarker() { + return this.marker; + } + + /** + * 获取变量值 + * 审计日志列表 + * + * @return list + */ + public GetAuditLog[] getList() { + return this.list; + } + } + + /** + * 返回的审计日志列表响应 + */ + public static final class GetAuditLogsResp { + + /** + * 审计日志信息 + */ + @SerializedName("data") + private GetAuditLogsData data; + + /** + * 获取变量值 + * 审计日志信息 + * + * @return data + */ + public GetAuditLogsData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetGroup.java b/src/main/java/com/qiniu/iam/apis/ApiGetGroup.java new file mode 100644 index 000000000..a858a398c --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetGroup.java @@ -0,0 +1,271 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询指定用户分组详情 + */ +public class ApiGetGroup extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetGroup(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetGroup(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的用户分组响应 + */ + private GetGroupResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetGroupResp.class); + } + + /** + * 响应信息 + * + * @return GetGroupResp + */ + public GetGroupResp getData() { + return this.data; + } + + /** + * 返回的用户分组信息 + */ + public static final class GetGroupData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 用户分组别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 用户分组是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 用户分组创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 用户分组上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 用户分组别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 用户分组描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 用户分组是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 用户分组创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 用户分组上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + } + + /** + * 返回的用户分组响应 + */ + public static final class GetGroupResp { + + /** + * 用户分组信息 + */ + @SerializedName("data") + private GetGroupData data; + + /** + * 获取变量值 + * 用户分组信息 + * + * @return data + */ + public GetGroupData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetGroupPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiGetGroupPolicies.java new file mode 100644 index 000000000..eae0a563b --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetGroupPolicies.java @@ -0,0 +1,419 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询用户分组下分配的授权策略 + */ +public class ApiGetGroupPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetGroupPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetGroupPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的用户分组下的授权策略列表响应 + */ + private GetGroupPoliciesResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetGroupPoliciesResp.class); + } + + /** + * 响应信息 + * + * @return GetGroupPoliciesResp + */ + public GetGroupPoliciesResp getData() { + return this.data; + } + + /** + * 授权策略规则 + */ + public static final class Statement { + + /** + * 授权策略规则的操作集合 + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合 + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 获取变量值 + * 授权策略规则的操作集合 + * + * @return actions + */ + public String[] getActions() { + return this.actions; + } + + /** + * 获取变量值 + * 授权策略规则的资源集合 + * + * @return resources + */ + public String[] getResources() { + return this.resources; + } + + /** + * 获取变量值 + * 授权策略规则的生效类型,允许访问或拒绝访问 + * + * @return effect + */ + public String getEffect() { + return this.effect; + } + } + + /** + * 返回的用户分组下的授权策略 + */ + public static final class GroupPolicy { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 授权策略别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 授权策略创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 授权策略上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private Statement[] statement; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 授权策略别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 授权策略描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 授权策略是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 授权策略创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 授权策略上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 授权策略规则集合 + * + * @return statement + */ + public Statement[] getStatement() { + return this.statement; + } + } + + /** + * 返回的用户分组下的授权策略列表信息 + */ + public static final class GetGroupPoliciesData { + + /** + * 用户分组下的授权策略数量 + */ + @SerializedName("count") + private Integer count; + + /** + * 用户分组下的授权策略列表 + */ + @SerializedName("list") + private GroupPolicy[] list; + + /** + * 获取变量值 + * 用户分组下的授权策略数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * 用户分组下的授权策略列表 + * + * @return list + */ + public GroupPolicy[] getList() { + return this.list; + } + } + + /** + * 返回的用户分组下的授权策略列表响应 + */ + public static final class GetGroupPoliciesResp { + + /** + * 用户分组下的授权策略信息 + */ + @SerializedName("data") + private GetGroupPoliciesData data; + + /** + * 获取变量值 + * 用户分组下的授权策略信息 + * + * @return data + */ + public GetGroupPoliciesData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetGroupServiceActionResources.java b/src/main/java/com/qiniu/iam/apis/ApiGetGroupServiceActionResources.java new file mode 100644 index 000000000..96f17997b --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetGroupServiceActionResources.java @@ -0,0 +1,216 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 列举用户分组指定服务操作下的可访问资源 + */ +public class ApiGetGroupServiceActionResources extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetGroupServiceActionResources(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetGroupServiceActionResources(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String groupAlias; + + /** + * 资源操作关联的服务 + */ + private String service; + + /** + * 资源操作别名 + */ + private String actionAlias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param groupAlias 用户分组别名 【必须】 + * @param service 资源操作关联的服务 【必须】 + * @param actionAlias 资源操作别名 【必须】 + */ + public Request(String urlPrefix, String groupAlias, String service, String actionAlias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.groupAlias = groupAlias; + this.service = service; + this.actionAlias = actionAlias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.groupAlias == null) { + throw new QiniuException(new NullPointerException("groupAlias can't empty")); + } + if (this.service == null) { + throw new QiniuException(new NullPointerException("service can't empty")); + } + if (this.actionAlias == null) { + throw new QiniuException(new NullPointerException("actionAlias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.groupAlias); + addPathSegment("services"); + addPathSegment(this.service); + addPathSegment("actions"); + addPathSegment(this.actionAlias); + addPathSegment("resources"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的用户分组指定服务操作下的可访问资源列表响应 + */ + private GetGroupServiceActionResourcesResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetGroupServiceActionResourcesResp.class); + } + + /** + * 响应信息 + * + * @return GetGroupServiceActionResourcesResp + */ + public GetGroupServiceActionResourcesResp getData() { + return this.data; + } + + /** + * 返回的用户分组指定服务操作下的可访问资源列表信息 + */ + public static final class GetGroupServiceActionResources { + + /** + * 可用资源 + */ + @SerializedName("allow") + private String[] allowedResources; + + /** + * 禁用资源 + */ + @SerializedName("deny") + private String[] deniedResources; + + /** + * 获取变量值 + * 可用资源 + * + * @return allowedResources + */ + public String[] getAllowedResources() { + return this.allowedResources; + } + + /** + * 获取变量值 + * 禁用资源 + * + * @return deniedResources + */ + public String[] getDeniedResources() { + return this.deniedResources; + } + } + + /** + * 返回的用户分组指定服务操作下的可访问资源列表响应 + */ + public static final class GetGroupServiceActionResourcesResp { + + /** + * 用户分组指定服务操作下的可访问资源列表信息 + */ + @SerializedName("data") + private GetGroupServiceActionResources data; + + /** + * 获取变量值 + * 用户分组指定服务操作下的可访问资源列表信息 + * + * @return data + */ + public GetGroupServiceActionResources getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetGroupUsers.java b/src/main/java/com/qiniu/iam/apis/ApiGetGroupUsers.java new file mode 100644 index 000000000..cd21dcfd5 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetGroupUsers.java @@ -0,0 +1,365 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询用户分组下的 IAM 子账户列表 + */ +public class ApiGetGroupUsers extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetGroupUsers(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetGroupUsers(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的用户分组下的 IAM 子账号列表响应 + */ + private GetGroupIamUsersResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetGroupIamUsersResp.class); + } + + /** + * 响应信息 + * + * @return GetGroupIamUsersResp + */ + public GetGroupIamUsersResp getData() { + return this.data; + } + + /** + * 返回的用户分组下的 IAM 子账号 + */ + public static final class GroupIamUser { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 子账号 uid + */ + @SerializedName("iuid") + private Integer iuid; + + /** + * 子账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 子账号创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("last_login_time") + private String lastLoginTime; + + /** + * 子账号是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 子账号 uid + * + * @return iuid + */ + public Integer getIuid() { + return this.iuid; + } + + /** + * 获取变量值 + * 子账号别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 子账号创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return lastLoginTime + */ + public String getLastLoginTime() { + return this.lastLoginTime; + } + + /** + * 获取变量值 + * 子账号是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的用户分组下的 IAM 子账号列表信息 + */ + public static final class GetGroupIamUsersData { + + /** + * 用户分组下的 IAM 子账号数量 + */ + @SerializedName("count") + private Integer count; + + /** + * 用户分组下的 IAM 子账号列表 + */ + @SerializedName("list") + private GroupIamUser[] list; + + /** + * 获取变量值 + * 用户分组下的 IAM 子账号数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * 用户分组下的 IAM 子账号列表 + * + * @return list + */ + public GroupIamUser[] getList() { + return this.list; + } + } + + /** + * 返回的用户分组下的 IAM 子账号列表响应 + */ + public static final class GetGroupIamUsersResp { + + /** + * 用户分组下的 IAM 子账号信息 + */ + @SerializedName("data") + private GetGroupIamUsersData data; + + /** + * 获取变量值 + * 用户分组下的 IAM 子账号信息 + * + * @return data + */ + public GetGroupIamUsersData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetGroups.java b/src/main/java/com/qiniu/iam/apis/ApiGetGroups.java new file mode 100644 index 000000000..13edbc96d --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetGroups.java @@ -0,0 +1,337 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 列举用户分组列表 + */ +public class ApiGetGroups extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetGroups(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetGroups(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + */ + public Request(String urlPrefix) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的用户分组列表响应 + */ + private GetGroupsResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetGroupsResp.class); + } + + /** + * 响应信息 + * + * @return GetGroupsResp + */ + public GetGroupsResp getData() { + return this.data; + } + + /** + * 返回的用户分组 + */ + public static final class GetGroup { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 用户分组别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 用户分组是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 用户分组创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 用户分组上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 用户分组别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 用户分组描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 用户分组是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 用户分组创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 用户分组上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + } + + /** + * 返回的用户分组列表信息 + */ + public static final class GetGroupsData { + + /** + * 用户分组数量 + */ + @SerializedName("count") + private Integer count; + + /** + * 用户分组列表 + */ + @SerializedName("list") + private GetGroup[] list; + + /** + * 获取变量值 + * 用户分组数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * 用户分组列表 + * + * @return list + */ + public GetGroup[] getList() { + return this.list; + } + } + + /** + * 返回的用户分组列表响应 + */ + public static final class GetGroupsResp { + + /** + * 用户分组信息 + */ + @SerializedName("data") + private GetGroupsData data; + + /** + * 获取变量值 + * 用户分组信息 + * + * @return data + */ + public GetGroupsData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiGetPolicies.java new file mode 100644 index 000000000..6db0275ee --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetPolicies.java @@ -0,0 +1,407 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 列举授权策略列表 + */ +public class ApiGetPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + */ + public Request(String urlPrefix) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的授权策略列表响应 + */ + private GetPoliciesResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetPoliciesResp.class); + } + + /** + * 响应信息 + * + * @return GetPoliciesResp + */ + public GetPoliciesResp getData() { + return this.data; + } + + /** + * 授权策略规则 + */ + public static final class Statement { + + /** + * 授权策略规则的操作集合 + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合 + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 获取变量值 + * 授权策略规则的操作集合 + * + * @return actions + */ + public String[] getActions() { + return this.actions; + } + + /** + * 获取变量值 + * 授权策略规则的资源集合 + * + * @return resources + */ + public String[] getResources() { + return this.resources; + } + + /** + * 获取变量值 + * 授权策略规则的生效类型,允许访问或拒绝访问 + * + * @return effect + */ + public String getEffect() { + return this.effect; + } + } + + /** + * 返回的授权策略 + */ + public static final class Policy { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 授权策略别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 授权策略创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 授权策略上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private Statement[] statement; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 授权策略别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 授权策略描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 授权策略是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 授权策略创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 授权策略上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 授权策略规则集合 + * + * @return statement + */ + public Statement[] getStatement() { + return this.statement; + } + } + + /** + * 返回的授权策略列表信息 + */ + public static final class GetPoliciesData { + + /** + * 授权策略数量 + */ + @SerializedName("count") + private Integer count; + + /** + * 授权策略列表 + */ + @SerializedName("list") + private Policy[] list; + + /** + * 获取变量值 + * 授权策略数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * 授权策略列表 + * + * @return list + */ + public Policy[] getList() { + return this.list; + } + } + + /** + * 返回的授权策略列表响应 + */ + public static final class GetPoliciesResp { + + /** + * 授权策略信息 + */ + @SerializedName("data") + private GetPoliciesData data; + + /** + * 获取变量值 + * 授权策略信息 + * + * @return data + */ + public GetPoliciesData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetPolicy.java b/src/main/java/com/qiniu/iam/apis/ApiGetPolicy.java new file mode 100644 index 000000000..31368414c --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetPolicy.java @@ -0,0 +1,341 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询指定授权策略详情 + */ +public class ApiGetPolicy extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetPolicy(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetPolicy(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 授权策略别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 授权策略别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的授权策略响应 + */ + private GetPolicyResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetPolicyResp.class); + } + + /** + * 响应信息 + * + * @return GetPolicyResp + */ + public GetPolicyResp getData() { + return this.data; + } + + /** + * 授权策略规则 + */ + public static final class Statement { + + /** + * 授权策略规则的操作集合 + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合 + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 获取变量值 + * 授权策略规则的操作集合 + * + * @return actions + */ + public String[] getActions() { + return this.actions; + } + + /** + * 获取变量值 + * 授权策略规则的资源集合 + * + * @return resources + */ + public String[] getResources() { + return this.resources; + } + + /** + * 获取变量值 + * 授权策略规则的生效类型,允许访问或拒绝访问 + * + * @return effect + */ + public String getEffect() { + return this.effect; + } + } + + /** + * 返回的授权策略信息 + */ + public static final class GetPolicyData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 授权策略别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 授权策略创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 授权策略上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private Statement[] statement; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 授权策略别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 授权策略描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 授权策略是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 授权策略创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 授权策略上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 授权策略规则集合 + * + * @return statement + */ + public Statement[] getStatement() { + return this.statement; + } + } + + /** + * 返回的授权策略响应 + */ + public static final class GetPolicyResp { + + /** + * 授权策略信息 + */ + @SerializedName("data") + private GetPolicyData data; + + /** + * 获取变量值 + * 授权策略信息 + * + * @return data + */ + public GetPolicyData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetPolicyGroups.java b/src/main/java/com/qiniu/iam/apis/ApiGetPolicyGroups.java new file mode 100644 index 000000000..384108589 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetPolicyGroups.java @@ -0,0 +1,349 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询授权策略分配的用户分组列表 + */ +public class ApiGetPolicyGroups extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetPolicyGroups(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetPolicyGroups(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 授权策略别名 + */ + private String alias; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 授权策略别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + addPathSegment(this.alias); + addPathSegment("groups"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的授权策略分配的用户分组列表响应 + */ + private GetPolicyGroupsResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetPolicyGroupsResp.class); + } + + /** + * 响应信息 + * + * @return GetPolicyGroupsResp + */ + public GetPolicyGroupsResp getData() { + return this.data; + } + + /** + * 返回的授权策略分配的用户分组 + */ + public static final class GetPolicyGroup { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 用户分组别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 用户分组是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 用户分组创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 用户分组上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 用户分组别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 用户分组描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 用户分组是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 用户分组创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 用户分组上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + } + + /** + * 返回的授权策略分配的用户分组列表信息 + */ + public static final class GetPolicyGroupsData { + + /** + * 授权策略分配的用户分组数量 + */ + @SerializedName("count") + private Integer count; + + /** + * 授权策略分配的用户分组列表 + */ + @SerializedName("list") + private GetPolicyGroup[] list; + + /** + * 获取变量值 + * 授权策略分配的用户分组数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * 授权策略分配的用户分组列表 + * + * @return list + */ + public GetPolicyGroup[] getList() { + return this.list; + } + } + + /** + * 返回的授权策略分配的用户分组列表响应 + */ + public static final class GetPolicyGroupsResp { + + /** + * 授权策略分配的用户分组信息 + */ + @SerializedName("data") + private GetPolicyGroupsData data; + + /** + * 获取变量值 + * 授权策略分配的用户分组信息 + * + * @return data + */ + public GetPolicyGroupsData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetPolicyUsers.java b/src/main/java/com/qiniu/iam/apis/ApiGetPolicyUsers.java new file mode 100644 index 000000000..f4af72840 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetPolicyUsers.java @@ -0,0 +1,365 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询授权策略分配的用 IAM 子账号列表 + */ +public class ApiGetPolicyUsers extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetPolicyUsers(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetPolicyUsers(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 授权策略别名 + */ + private String alias; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 授权策略别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + addPathSegment(this.alias); + addPathSegment("users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的授权策略分配的 IAM 子账号列表响应 + */ + private GetPolicyIamUsersResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetPolicyIamUsersResp.class); + } + + /** + * 响应信息 + * + * @return GetPolicyIamUsersResp + */ + public GetPolicyIamUsersResp getData() { + return this.data; + } + + /** + * 返回的授权策略分配的 IAM 子账号 + */ + public static final class PolicyIamUser { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 子账号 uid + */ + @SerializedName("iuid") + private Integer iuid; + + /** + * 子账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 子账号创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("last_login_time") + private String lastLoginTime; + + /** + * 子账号是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 子账号 uid + * + * @return iuid + */ + public Integer getIuid() { + return this.iuid; + } + + /** + * 获取变量值 + * 子账号别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 子账号创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return lastLoginTime + */ + public String getLastLoginTime() { + return this.lastLoginTime; + } + + /** + * 获取变量值 + * 子账号是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的授权策略分配的 IAM 子账号列表信息 + */ + public static final class GetPolicyIamUsersData { + + /** + * 授权策略分配的 IAM 子账号数量 + */ + @SerializedName("count") + private Integer count; + + /** + * 授权策略分配的 IAM 子账号列表 + */ + @SerializedName("list") + private PolicyIamUser[] list; + + /** + * 获取变量值 + * 授权策略分配的 IAM 子账号数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * 授权策略分配的 IAM 子账号列表 + * + * @return list + */ + public PolicyIamUser[] getList() { + return this.list; + } + } + + /** + * 返回的授权策略分配的 IAM 子账号列表响应 + */ + public static final class GetPolicyIamUsersResp { + + /** + * 授权策略分配的 IAM 子账号信息 + */ + @SerializedName("data") + private GetPolicyIamUsersData data; + + /** + * 获取变量值 + * 授权策略分配的 IAM 子账号信息 + * + * @return data + */ + public GetPolicyIamUsersData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetServices.java b/src/main/java/com/qiniu/iam/apis/ApiGetServices.java new file mode 100644 index 000000000..d9272327b --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetServices.java @@ -0,0 +1,181 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询 IAM 的服务列表 + */ +public class ApiGetServices extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetServices(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetServices(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + */ + public Request(String urlPrefix) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/services"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的服务列表响应 + */ + private GetServicesResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetServicesResp.class); + } + + /** + * 响应信息 + * + * @return GetServicesResp + */ + public GetServicesResp getData() { + return this.data; + } + + /** + * 返回的服务列表响应 + */ + public static final class GetServicesResp { + + /** + * 服务列表信息 + */ + @SerializedName("data") + private String[] data; + + /** + * 获取变量值 + * 服务列表信息 + * + * @return data + */ + public String[] getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetUser.java b/src/main/java/com/qiniu/iam/apis/ApiGetUser.java new file mode 100644 index 000000000..4b342cad8 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetUser.java @@ -0,0 +1,287 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 获取 IAM 子账号 + */ +public class ApiGetUser extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetUser(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetUser(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号响应 + */ + private GetIamUserResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetIamUserResp.class); + } + + /** + * 响应信息 + * + * @return GetIamUserResp + */ + public GetIamUserResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号信息 + */ + public static final class GetIamUserData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 子账号 uid + */ + @SerializedName("iuid") + private Integer iuid; + + /** + * 子账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 子账号创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("last_login_time") + private String lastLoginTime; + + /** + * 子账号是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 子账号 uid + * + * @return iuid + */ + public Integer getIuid() { + return this.iuid; + } + + /** + * 获取变量值 + * 子账号别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 子账号创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return lastLoginTime + */ + public String getLastLoginTime() { + return this.lastLoginTime; + } + + /** + * 获取变量值 + * 子账号是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的 IAM 子账号响应 + */ + public static final class GetIamUserResp { + + /** + * IAM 子账号信息 + */ + @SerializedName("data") + private GetIamUserData data; + + /** + * 获取变量值 + * IAM 子账号信息 + * + * @return data + */ + public GetIamUserData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetUserAvailableServices.java b/src/main/java/com/qiniu/iam/apis/ApiGetUserAvailableServices.java new file mode 100644 index 000000000..fee50a15c --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetUserAvailableServices.java @@ -0,0 +1,154 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 列举子账号可用服务 + */ +public class ApiGetUserAvailableServices extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetUserAvailableServices(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetUserAvailableServices(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("services"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号可用服务列表响应 + */ + private GetIamUserAvailableServicesResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetIamUserAvailableServicesResp.class); + } + + /** + * 响应信息 + * + * @return GetIamUserAvailableServicesResp + */ + public GetIamUserAvailableServicesResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号可用服务列表响应 + */ + public static final class GetIamUserAvailableServicesResp { + + /** + * IAM 子账号可用服务信息 + */ + @SerializedName("data") + private String[] data; + + /** + * 获取变量值 + * IAM 子账号可用服务信息 + * + * @return data + */ + public String[] getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetUserGroups.java b/src/main/java/com/qiniu/iam/apis/ApiGetUserGroups.java new file mode 100644 index 000000000..436d8d270 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetUserGroups.java @@ -0,0 +1,349 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询子账号所属用户分组列表 + */ +public class ApiGetUserGroups extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetUserGroups(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetUserGroups(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("groups"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号分组列表响应 + */ + private GetIamUserGroupsResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetIamUserGroupsResp.class); + } + + /** + * 响应信息 + * + * @return GetIamUserGroupsResp + */ + public GetIamUserGroupsResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号分组 + */ + public static final class IamUserGroup { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 用户分组别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 用户分组是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 用户分组创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 用户分组上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 用户分组别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 用户分组描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 用户分组是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 用户分组创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 用户分组上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + } + + /** + * 返回的 IAM 子账号分组列表信息 + */ + public static final class GetIamUserGroupsData { + + /** + * IAM 子账号分组数量 + */ + @SerializedName("count") + private Integer count; + + /** + * IAM 子账号分组列表 + */ + @SerializedName("list") + private IamUserGroup[] list; + + /** + * 获取变量值 + * IAM 子账号分组数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * IAM 子账号分组列表 + * + * @return list + */ + public IamUserGroup[] getList() { + return this.list; + } + } + + /** + * 返回的 IAM 子账号分组列表响应 + */ + public static final class GetIamUserGroupsResp { + + /** + * IAM 子账号分组信息 + */ + @SerializedName("data") + private GetIamUserGroupsData data; + + /** + * 获取变量值 + * IAM 子账号分组信息 + * + * @return data + */ + public GetIamUserGroupsData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetUserKeypairs.java b/src/main/java/com/qiniu/iam/apis/ApiGetUserKeypairs.java new file mode 100644 index 000000000..a6d3ad6b0 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetUserKeypairs.java @@ -0,0 +1,333 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 列举 IAM 子账号密钥 + */ +public class ApiGetUserKeypairs extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetUserKeypairs(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetUserKeypairs(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("keypairs"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号密钥列表响应 + */ + private GetIamUserKeyPairsResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetIamUserKeyPairsResp.class); + } + + /** + * 响应信息 + * + * @return GetIamUserKeyPairsResp + */ + public GetIamUserKeyPairsResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号密钥 + */ + public static final class GetIamUserKeyPair { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * IAM 子账号 Access Key + */ + @SerializedName("access_key") + private String accessKey; + + /** + * IAM 子账号 Secret Key + */ + @SerializedName("secret_key") + private String secretKey; + + /** + * 关联用户的记录 ID + */ + @SerializedName("user_id") + private String userId; + + /** + * 密钥创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 密钥是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * IAM 子账号 Access Key + * + * @return accessKey + */ + public String getAccessKey() { + return this.accessKey; + } + + /** + * 获取变量值 + * IAM 子账号 Secret Key + * + * @return secretKey + */ + public String getSecretKey() { + return this.secretKey; + } + + /** + * 获取变量值 + * 关联用户的记录 ID + * + * @return userId + */ + public String getUserId() { + return this.userId; + } + + /** + * 获取变量值 + * 密钥创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 密钥是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的 IAM 子账号密钥列表信息 + */ + public static final class GetIamUserKeyPairsData { + + /** + * IAM 子账号密钥数量 + */ + @SerializedName("count") + private Integer count; + + /** + * IAM 子账号密钥列表 + */ + @SerializedName("list") + private GetIamUserKeyPair[] list; + + /** + * 获取变量值 + * IAM 子账号密钥数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * IAM 子账号密钥列表 + * + * @return list + */ + public GetIamUserKeyPair[] getList() { + return this.list; + } + } + + /** + * 返回的 IAM 子账号密钥列表响应 + */ + public static final class GetIamUserKeyPairsResp { + + /** + * IAM 子账号密钥信息 + */ + @SerializedName("data") + private GetIamUserKeyPairsData data; + + /** + * 获取变量值 + * IAM 子账号密钥信息 + * + * @return data + */ + public GetIamUserKeyPairsData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetUserPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiGetUserPolicies.java new file mode 100644 index 000000000..14b8100e9 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetUserPolicies.java @@ -0,0 +1,419 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询子账号下的授权策略 + */ +public class ApiGetUserPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetUserPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetUserPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + */ + public Request(String urlPrefix, String alias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号的授权策略列表响应 + */ + private GetIamUserPoliciesResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetIamUserPoliciesResp.class); + } + + /** + * 响应信息 + * + * @return GetIamUserPoliciesResp + */ + public GetIamUserPoliciesResp getData() { + return this.data; + } + + /** + * 授权策略规则 + */ + public static final class Statement { + + /** + * 授权策略规则的操作集合 + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合 + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 获取变量值 + * 授权策略规则的操作集合 + * + * @return actions + */ + public String[] getActions() { + return this.actions; + } + + /** + * 获取变量值 + * 授权策略规则的资源集合 + * + * @return resources + */ + public String[] getResources() { + return this.resources; + } + + /** + * 获取变量值 + * 授权策略规则的生效类型,允许访问或拒绝访问 + * + * @return effect + */ + public String getEffect() { + return this.effect; + } + } + + /** + * 返回的 IAM 子账号的授权策略 + */ + public static final class GetIamUserPolicy { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 授权策略别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 授权策略创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 授权策略上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private Statement[] statement; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 授权策略别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 授权策略描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 授权策略是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 授权策略创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 授权策略上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 授权策略规则集合 + * + * @return statement + */ + public Statement[] getStatement() { + return this.statement; + } + } + + /** + * 返回的 IAM 子账号的授权策略列表信息 + */ + public static final class GetIamUserPoliciesData { + + /** + * IAM 子账号的授权策略数量 + */ + @SerializedName("count") + private Integer count; + + /** + * IAM 子账号的授权策略列表 + */ + @SerializedName("list") + private GetIamUserPolicy[] list; + + /** + * 获取变量值 + * IAM 子账号的授权策略数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * IAM 子账号的授权策略列表 + * + * @return list + */ + public GetIamUserPolicy[] getList() { + return this.list; + } + } + + /** + * 返回的 IAM 子账号的授权策略列表响应 + */ + public static final class GetIamUserPoliciesResp { + + /** + * IAM 子账号的授权策略信息 + */ + @SerializedName("data") + private GetIamUserPoliciesData data; + + /** + * 获取变量值 + * IAM 子账号的授权策略信息 + * + * @return data + */ + public GetIamUserPoliciesData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetUserServiceActionResources.java b/src/main/java/com/qiniu/iam/apis/ApiGetUserServiceActionResources.java new file mode 100644 index 000000000..c6ceff3fa --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetUserServiceActionResources.java @@ -0,0 +1,216 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 列举子账号指定服务操作下的可访问资源 + */ +public class ApiGetUserServiceActionResources extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetUserServiceActionResources(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetUserServiceActionResources(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String userAlias; + + /** + * 资源操作关联的服务 + */ + private String service; + + /** + * 资源操作别名 + */ + private String actionAlias; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param userAlias 子账号别名 【必须】 + * @param service 资源操作关联的服务 【必须】 + * @param actionAlias 资源操作别名 【必须】 + */ + public Request(String urlPrefix, String userAlias, String service, String actionAlias) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.userAlias = userAlias; + this.service = service; + this.actionAlias = actionAlias; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.userAlias == null) { + throw new QiniuException(new NullPointerException("userAlias can't empty")); + } + if (this.service == null) { + throw new QiniuException(new NullPointerException("service can't empty")); + } + if (this.actionAlias == null) { + throw new QiniuException(new NullPointerException("actionAlias can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.userAlias); + addPathSegment("services"); + addPathSegment(this.service); + addPathSegment("actions"); + addPathSegment(this.actionAlias); + addPathSegment("resources"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号指定服务操作下的可访问资源列表响应 + */ + private GetIamUserServiceActionResourcesResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetIamUserServiceActionResourcesResp.class); + } + + /** + * 响应信息 + * + * @return GetIamUserServiceActionResourcesResp + */ + public GetIamUserServiceActionResourcesResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号指定服务操作下的可访问资源列表信息 + */ + public static final class GetIamUserServiceActionResources { + + /** + * 可用资源 + */ + @SerializedName("allow") + private String[] allowedResources; + + /** + * 禁用资源 + */ + @SerializedName("deny") + private String[] deniedResources; + + /** + * 获取变量值 + * 可用资源 + * + * @return allowedResources + */ + public String[] getAllowedResources() { + return this.allowedResources; + } + + /** + * 获取变量值 + * 禁用资源 + * + * @return deniedResources + */ + public String[] getDeniedResources() { + return this.deniedResources; + } + } + + /** + * 返回的 IAM 子账号指定服务操作下的可访问资源列表响应 + */ + public static final class GetIamUserServiceActionResourcesResp { + + /** + * IAM 子账号指定服务操作下的可访问资源列表信息 + */ + @SerializedName("data") + private GetIamUserServiceActionResources data; + + /** + * 获取变量值 + * IAM 子账号指定服务操作下的可访问资源列表信息 + * + * @return data + */ + public GetIamUserServiceActionResources getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiGetUsers.java b/src/main/java/com/qiniu/iam/apis/ApiGetUsers.java new file mode 100644 index 000000000..bcd6c9d28 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiGetUsers.java @@ -0,0 +1,372 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 列举 IAM 子账号 + */ +public class ApiGetUsers extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiGetUsers(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiGetUsers(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias = null; + + /** + * 分页页号,从 1 开始,默认 1 + */ + private Integer page = null; + + /** + * 分页大小,默认 20,最大 2000 + */ + private Integer pageSize = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + */ + public Request(String urlPrefix) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + } + + /** + * 设置参数【可选】 + * + * @param alias 子账号别名 + * @return Request + */ + public Request setAlias(String alias) { + this.alias = alias; + return this; + } + + /** + * 设置参数【可选】 + * + * @param page 分页页号,从 1 开始,默认 1 + * @return Request + */ + public Request setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pageSize 分页大小,默认 20,最大 2000 + * @return Request + */ + public Request setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + if (this.alias != null) { + addQueryPair("alias", this.alias); + } + if (this.page != null) { + addQueryPair("page", this.page); + } + if (this.pageSize != null) { + addQueryPair("page_size", this.pageSize); + } + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号列表响应 + */ + private GetIamUsersResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), GetIamUsersResp.class); + } + + /** + * 响应信息 + * + * @return GetIamUsersResp + */ + public GetIamUsersResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号 + */ + public static final class GetIamUser { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 子账号 uid + */ + @SerializedName("iuid") + private Integer iuid; + + /** + * 子账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 子账号创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("last_login_time") + private String lastLoginTime; + + /** + * 子账号是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 子账号 uid + * + * @return iuid + */ + public Integer getIuid() { + return this.iuid; + } + + /** + * 获取变量值 + * 子账号别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 子账号创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return lastLoginTime + */ + public String getLastLoginTime() { + return this.lastLoginTime; + } + + /** + * 获取变量值 + * 子账号是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的 IAM 子账号列表信息 + */ + public static final class GetIamUsersData { + + /** + * IAM 子账号数量 + */ + @SerializedName("count") + private Integer count; + + /** + * IAM 子账号列表 + */ + @SerializedName("list") + private GetIamUser[] list; + + /** + * 获取变量值 + * IAM 子账号数量 + * + * @return count + */ + public Integer getCount() { + return this.count; + } + + /** + * 获取变量值 + * IAM 子账号列表 + * + * @return list + */ + public GetIamUser[] getList() { + return this.list; + } + } + + /** + * 返回的 IAM 子账号列表响应 + */ + public static final class GetIamUsersResp { + + /** + * IAM 子账号信息 + */ + @SerializedName("data") + private GetIamUsersData data; + + /** + * 获取变量值 + * IAM 子账号信息 + * + * @return data + */ + public GetIamUsersData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiModifyGroup.java b/src/main/java/com/qiniu/iam/apis/ApiModifyGroup.java new file mode 100644 index 000000000..178b8a4e4 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiModifyGroup.java @@ -0,0 +1,323 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 更新用户分组信息 + */ +public class ApiModifyGroup extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiModifyGroup(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiModifyGroup(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 修改用户分组参数 + */ + private ModifyGroupParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param data 修改用户分组参数 【必须】 + */ + public Request(String urlPrefix, String alias, ModifyGroupParam data) { + super(urlPrefix); + this.setMethod(MethodType.PATCH); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 修改用户分组参数 + */ + public static final class ModifyGroupParam { + + /** + * 新的用户分组别名,由 `A-Za-z0-9` 组成 + */ + @SerializedName("alias") + private String newAlias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 设置变量值 + * + * @param newAlias 新的用户分组别名,由 `A-Za-z0-9` 组成 + * @return Request + */ + public ModifyGroupParam setNewAlias(String newAlias) { + this.newAlias = newAlias; + return this; + } + + /** + * 设置变量值 + * + * @param description 用户分组描述 + * @return Request + */ + public ModifyGroupParam setDescription(String description) { + this.description = description; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的用户分组响应 + */ + private ModifyGroupResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), ModifyGroupResp.class); + } + + /** + * 响应信息 + * + * @return ModifyGroupResp + */ + public ModifyGroupResp getData() { + return this.data; + } + + /** + * 返回的用户分组信息 + */ + public static final class ModifyGroupData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 用户分组别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 用户分组描述 + */ + @SerializedName("description") + private String description; + + /** + * 用户分组是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 用户分组创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 用户分组上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 用户分组别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 用户分组描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 用户分组是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 用户分组创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 用户分组上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + } + + /** + * 返回的用户分组响应 + */ + public static final class ModifyGroupResp { + + /** + * 用户分组信息 + */ + @SerializedName("data") + private ModifyGroupData data; + + /** + * 获取变量值 + * 用户分组信息 + * + * @return data + */ + public ModifyGroupData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiModifyGroupPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiModifyGroupPolicies.java new file mode 100644 index 000000000..ea1c90d17 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiModifyGroupPolicies.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 添加授权策略到用户分组 + */ +public class ApiModifyGroupPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiModifyGroupPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiModifyGroupPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 为用户分组修改授权策略参数 + */ + private ModifiedGroupIamPoliciesParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + * @param data 为用户分组修改授权策略参数 【必须】 + */ + public Request(String urlPrefix, String alias, ModifiedGroupIamPoliciesParam data) { + super(urlPrefix); + this.setMethod(MethodType.PATCH); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为用户分组修改授权策略参数 + */ + public static final class ModifiedGroupIamPoliciesParam { + + /** + * 授权策略别名集合 + */ + @SerializedName("policy_aliases") + private String[] policyAliases; + + /** + * 设置变量值 + * + * @param policyAliases 授权策略别名集合 + * @return Request + */ + public ModifiedGroupIamPoliciesParam setPolicyAliases(String[] policyAliases) { + this.policyAliases = policyAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiModifyGroupUsers.java b/src/main/java/com/qiniu/iam/apis/ApiModifyGroupUsers.java new file mode 100644 index 000000000..b468f34be --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiModifyGroupUsers.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 添加 IAM 子账号到用户分组 + */ +public class ApiModifyGroupUsers extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiModifyGroupUsers(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiModifyGroupUsers(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 为用户分组修改 IAM 子账号参数 + */ + private ModifiedGroupIamUsersParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + * @param data 为用户分组修改 IAM 子账号参数 【必须】 + */ + public Request(String urlPrefix, String alias, ModifiedGroupIamUsersParam data) { + super(urlPrefix); + this.setMethod(MethodType.PATCH); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为用户分组修改 IAM 子账号参数 + */ + public static final class ModifiedGroupIamUsersParam { + + /** + * IAM 子账号别名集合 + */ + @SerializedName("user_aliases") + private String[] userAliases; + + /** + * 设置变量值 + * + * @param userAliases IAM 子账号别名集合 + * @return Request + */ + public ModifiedGroupIamUsersParam setUserAliases(String[] userAliases) { + this.userAliases = userAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiModifyPolicy.java b/src/main/java/com/qiniu/iam/apis/ApiModifyPolicy.java new file mode 100644 index 000000000..5d49b036e --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiModifyPolicy.java @@ -0,0 +1,467 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 修改授权策略 + */ +public class ApiModifyPolicy extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiModifyPolicy(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiModifyPolicy(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 授权策略别名 + */ + private String alias; + + /** + * 修改授权策略参数 + */ + private ModifyPolicyParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 授权策略别名 【必须】 + * @param data 修改授权策略参数 【必须】 + */ + public Request(String urlPrefix, String alias, ModifyPolicyParam data) { + super(urlPrefix); + this.setMethod(MethodType.PATCH); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 授权策略规则 + */ + public static final class ModifyStatement { + + /** + * 授权策略规则的操作集合,action 查询参考 action 接口,格式为 service/action_alias + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合,格式为 qrn:product:region:uid:[resource-type/]resource-id ;可以简写为 qrn:product:::resource-id + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 设置变量值 + * + * @param actions 授权策略规则的操作集合,action 查询参考 action 接口,格式为 service/action_alias + * @return Request + */ + public ModifyStatement setActions(String[] actions) { + this.actions = actions; + return this; + } + + /** + * 设置变量值 + * + * @param resources 授权策略规则的资源集合,格式为 qrn:product:region:uid:[resource-type/]resource-id ;可以简写为 qrn:product:::resource-id + * @return Request + */ + public ModifyStatement setResources(String[] resources) { + this.resources = resources; + return this; + } + + /** + * 设置变量值 + * + * @param effect 授权策略规则的生效类型,允许访问或拒绝访问 + * @return Request + */ + public ModifyStatement setEffect(String effect) { + this.effect = effect; + return this; + } + } + + /** + * 修改授权策略参数 + */ + public static final class ModifyPolicyParam { + + /** + * 授权策略别名,由 `A-Za-z0-9` 组成 + */ + @SerializedName("alias") + private String newAlias; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private ModifyStatement[] statement; + + /** + * 设置变量值 + * + * @param newAlias 授权策略别名,由 `A-Za-z0-9` 组成 + * @return Request + */ + public ModifyPolicyParam setNewAlias(String newAlias) { + this.newAlias = newAlias; + return this; + } + + /** + * 设置变量值 + * + * @param description 授权策略描述 + * @return Request + */ + public ModifyPolicyParam setDescription(String description) { + this.description = description; + return this; + } + + /** + * 设置变量值 + * + * @param statement 授权策略规则集合 + * @return Request + */ + public ModifyPolicyParam setStatement(ModifyStatement[] statement) { + this.statement = statement; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的授权策略响应 + */ + private ModifiedPolicyResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), ModifiedPolicyResp.class); + } + + /** + * 响应信息 + * + * @return ModifiedPolicyResp + */ + public ModifiedPolicyResp getData() { + return this.data; + } + + /** + * 授权策略规则 + */ + public static final class ModifiedStatement { + + /** + * 授权策略规则的操作集合 + */ + @SerializedName("action") + private String[] actions; + + /** + * 授权策略规则的资源集合 + */ + @SerializedName("resource") + private String[] resources; + + /** + * 授权策略规则的生效类型,允许访问或拒绝访问 + */ + @SerializedName("effect") + private String effect; + + /** + * 获取变量值 + * 授权策略规则的操作集合 + * + * @return actions + */ + public String[] getActions() { + return this.actions; + } + + /** + * 获取变量值 + * 授权策略规则的资源集合 + * + * @return resources + */ + public String[] getResources() { + return this.resources; + } + + /** + * 获取变量值 + * 授权策略规则的生效类型,允许访问或拒绝访问 + * + * @return effect + */ + public String getEffect() { + return this.effect; + } + } + + /** + * 返回的授权策略信息 + */ + public static final class ModifiedPolicyData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 授权策略别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 授权策略描述 + */ + @SerializedName("description") + private String description; + + /** + * 授权策略是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 授权策略创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 授权策略上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 授权策略规则集合 + */ + @SerializedName("statement") + private ModifiedStatement[] statement; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 授权策略别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 授权策略描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 授权策略是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + + /** + * 获取变量值 + * 授权策略创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 授权策略上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 授权策略规则集合 + * + * @return statement + */ + public ModifiedStatement[] getStatement() { + return this.statement; + } + } + + /** + * 返回的授权策略响应 + */ + public static final class ModifiedPolicyResp { + + /** + * 授权策略信息 + */ + @SerializedName("data") + private ModifiedPolicyData data; + + /** + * 获取变量值 + * 授权策略信息 + * + * @return data + */ + public ModifiedPolicyData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiModifyUser.java b/src/main/java/com/qiniu/iam/apis/ApiModifyUser.java new file mode 100644 index 000000000..0b82bafae --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiModifyUser.java @@ -0,0 +1,339 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 修改 IAM 子账号 + */ +public class ApiModifyUser extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiModifyUser(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiModifyUser(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 修改 IAM 子账号参数 + */ + private ModifiedIamUserParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param data 修改 IAM 子账号参数 【必须】 + */ + public Request(String urlPrefix, String alias, ModifiedIamUserParam data) { + super(urlPrefix); + this.setMethod(MethodType.PATCH); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 修改 IAM 子账号参数 + */ + public static final class ModifiedIamUserParam { + + /** + * 子账号是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 子账号密码 + */ + @SerializedName("password") + private String password; + + /** + * 设置变量值 + * + * @param enabled 子账号是否启用 + * @return Request + */ + public ModifiedIamUserParam setEnabled(Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * 设置变量值 + * + * @param password 子账号密码 + * @return Request + */ + public ModifiedIamUserParam setPassword(String password) { + this.password = password; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的 IAM 子账号响应 + */ + private ModifiedIamUserResp data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), ModifiedIamUserResp.class); + } + + /** + * 响应信息 + * + * @return ModifiedIamUserResp + */ + public ModifiedIamUserResp getData() { + return this.data; + } + + /** + * 返回的 IAM 子账号信息 + */ + public static final class ModifiedIamUserData { + + /** + * 记录 ID + */ + @SerializedName("id") + private String id; + + /** + * 根用户 uid + */ + @SerializedName("root_uid") + private Integer rootUid; + + /** + * 子账号 uid + */ + @SerializedName("iuid") + private Integer iuid; + + /** + * 子账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 子账号创建时间 + */ + @SerializedName("created_at") + private String createdAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("updated_at") + private String updatedAt; + + /** + * 子账号上次更新时间 + */ + @SerializedName("last_login_time") + private String lastLoginTime; + + /** + * 子账号是否启用 + */ + @SerializedName("enabled") + private Boolean enabled; + + /** + * 获取变量值 + * 记录 ID + * + * @return id + */ + public String getId() { + return this.id; + } + + /** + * 获取变量值 + * 根用户 uid + * + * @return rootUid + */ + public Integer getRootUid() { + return this.rootUid; + } + + /** + * 获取变量值 + * 子账号 uid + * + * @return iuid + */ + public Integer getIuid() { + return this.iuid; + } + + /** + * 获取变量值 + * 子账号别名 + * + * @return alias + */ + public String getAlias() { + return this.alias; + } + + /** + * 获取变量值 + * 子账号创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return updatedAt + */ + public String getUpdatedAt() { + return this.updatedAt; + } + + /** + * 获取变量值 + * 子账号上次更新时间 + * + * @return lastLoginTime + */ + public String getLastLoginTime() { + return this.lastLoginTime; + } + + /** + * 获取变量值 + * 子账号是否启用 + * + * @return enabled + */ + public Boolean getEnabled() { + return this.enabled; + } + } + + /** + * 返回的 IAM 子账号响应 + */ + public static final class ModifiedIamUserResp { + + /** + * IAM 子账号信息 + */ + @SerializedName("data") + private ModifiedIamUserData data; + + /** + * 获取变量值 + * IAM 子账号信息 + * + * @return data + */ + public ModifiedIamUserData getData() { + return this.data; + } + } + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiModifyUserPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiModifyUserPolicies.java new file mode 100644 index 000000000..f7f15f8bb --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiModifyUserPolicies.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 为子账号添加授权策略 + */ +public class ApiModifyUserPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiModifyUserPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiModifyUserPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 为子账号修改授权策略参数 + */ + private ModifiedIamUserPoliciesParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param data 为子账号修改授权策略参数 【必须】 + */ + public Request(String urlPrefix, String alias, ModifiedIamUserPoliciesParam data) { + super(urlPrefix); + this.setMethod(MethodType.PATCH); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为子账号修改授权策略参数 + */ + public static final class ModifiedIamUserPoliciesParam { + + /** + * 授权策略别名集合 + */ + @SerializedName("policy_aliases") + private String[] policyAliases; + + /** + * 设置变量值 + * + * @param policyAliases 授权策略别名集合 + * @return Request + */ + public ModifiedIamUserPoliciesParam setPolicyAliases(String[] policyAliases) { + this.policyAliases = policyAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiUpdateGroupPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiUpdateGroupPolicies.java new file mode 100644 index 000000000..52f23dc0e --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiUpdateGroupPolicies.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 为用户分组重新分配授权策略 + */ +public class ApiUpdateGroupPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiUpdateGroupPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiUpdateGroupPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 为用户分组重新分配授权策略参数 + */ + private UpdatedGroupIamPoliciesParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + * @param data 为用户分组重新分配授权策略参数 【必须】 + */ + public Request(String urlPrefix, String alias, UpdatedGroupIamPoliciesParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为用户分组重新分配授权策略参数 + */ + public static final class UpdatedGroupIamPoliciesParam { + + /** + * 授权策略别名集合 + */ + @SerializedName("policy_aliases") + private String[] policyAliases; + + /** + * 设置变量值 + * + * @param policyAliases 授权策略别名集合 + * @return Request + */ + public UpdatedGroupIamPoliciesParam setPolicyAliases(String[] policyAliases) { + this.policyAliases = policyAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiUpdateGroupUsers.java b/src/main/java/com/qiniu/iam/apis/ApiUpdateGroupUsers.java new file mode 100644 index 000000000..53448f8dc --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiUpdateGroupUsers.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 为用户分组中重新分配 IAM 子账号 + */ +public class ApiUpdateGroupUsers extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiUpdateGroupUsers(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiUpdateGroupUsers(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 用户分组别名 + */ + private String alias; + + /** + * 为用户分组重新分配 IAM 子账号参数 + */ + private UpdatedGroupIamUsersParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 用户分组别名 【必须】 + * @param data 为用户分组重新分配 IAM 子账号参数 【必须】 + */ + public Request(String urlPrefix, String alias, UpdatedGroupIamUsersParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/groups"); + addPathSegment(this.alias); + addPathSegment("users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为用户分组重新分配 IAM 子账号参数 + */ + public static final class UpdatedGroupIamUsersParam { + + /** + * IAM 子账号别名集合 + */ + @SerializedName("user_aliases") + private String[] userAliases; + + /** + * 设置变量值 + * + * @param userAliases IAM 子账号别名集合 + * @return Request + */ + public UpdatedGroupIamUsersParam setUserAliases(String[] userAliases) { + this.userAliases = userAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiUpdatePolicyGroups.java b/src/main/java/com/qiniu/iam/apis/ApiUpdatePolicyGroups.java new file mode 100644 index 000000000..a6010bf13 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiUpdatePolicyGroups.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 重新分配用户分组给指定策略 + */ +public class ApiUpdatePolicyGroups extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiUpdatePolicyGroups(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiUpdatePolicyGroups(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 为授权策略重新分配分组参数 + */ + private UpdatedPolicyGroupsParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param data 为授权策略重新分配分组参数 【必须】 + */ + public Request(String urlPrefix, String alias, UpdatedPolicyGroupsParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + addPathSegment(this.alias); + addPathSegment("groups"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为授权策略重新分配分组参数 + */ + public static final class UpdatedPolicyGroupsParam { + + /** + * 分组别名集合 + */ + @SerializedName("group_aliases") + private String[] groupAliases; + + /** + * 设置变量值 + * + * @param groupAliases 分组别名集合 + * @return Request + */ + public UpdatedPolicyGroupsParam setGroupAliases(String[] groupAliases) { + this.groupAliases = groupAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiUpdatePolicyUsers.java b/src/main/java/com/qiniu/iam/apis/ApiUpdatePolicyUsers.java new file mode 100644 index 000000000..b820c9d90 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiUpdatePolicyUsers.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 重新分配用户给指定授权策略 + */ +public class ApiUpdatePolicyUsers extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiUpdatePolicyUsers(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiUpdatePolicyUsers(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 授权策略分组别名 + */ + private String alias; + + /** + * 为授权策略重新分配 IAM 子账号参数 + */ + private UpdatedPolicyIamUsersParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 授权策略分组别名 【必须】 + * @param data 为授权策略重新分配 IAM 子账号参数 【必须】 + */ + public Request(String urlPrefix, String alias, UpdatedPolicyIamUsersParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/policies"); + addPathSegment(this.alias); + addPathSegment("users"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为授权策略重新分配 IAM 子账号参数 + */ + public static final class UpdatedPolicyIamUsersParam { + + /** + * IAM 子账号别名集合 + */ + @SerializedName("user_aliases") + private String[] userAliases; + + /** + * 设置变量值 + * + * @param userAliases IAM 子账号别名集合 + * @return Request + */ + public UpdatedPolicyIamUsersParam setUserAliases(String[] userAliases) { + this.userAliases = userAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiUpdateUserGroups.java b/src/main/java/com/qiniu/iam/apis/ApiUpdateUserGroups.java new file mode 100644 index 000000000..ff0827961 --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiUpdateUserGroups.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 为用户重新分配分组 + */ +public class ApiUpdateUserGroups extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiUpdateUserGroups(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiUpdateUserGroups(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 为用户重新分配分组参数 + */ + private UpdatedIamUserGroupsParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param data 为用户重新分配分组参数 【必须】 + */ + public Request(String urlPrefix, String alias, UpdatedIamUserGroupsParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("groups"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为用户重新分配分组参数 + */ + public static final class UpdatedIamUserGroupsParam { + + /** + * 分组别名集合 + */ + @SerializedName("group_aliases") + private String[] groupAliases; + + /** + * 设置变量值 + * + * @param groupAliases 分组别名集合 + * @return Request + */ + public UpdatedIamUserGroupsParam setGroupAliases(String[] groupAliases) { + this.groupAliases = groupAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/iam/apis/ApiUpdateUserPolicies.java b/src/main/java/com/qiniu/iam/apis/ApiUpdateUserPolicies.java new file mode 100644 index 000000000..4db55e4fa --- /dev/null +++ b/src/main/java/com/qiniu/iam/apis/ApiUpdateUserPolicies.java @@ -0,0 +1,152 @@ +package com.qiniu.iam.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 为子账号重新分配授权策略 + */ +public class ApiUpdateUserPolicies extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiUpdateUserPolicies(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiUpdateUserPolicies(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 子账号别名 + */ + private String alias; + + /** + * 为子账号重新分配授权策略参数 + */ + private UpdatedIamUserPoliciesParam data; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param alias 子账号别名 【必须】 + * @param data 为子账号重新分配授权策略参数 【必须】 + */ + public Request(String urlPrefix, String alias, UpdatedIamUserPoliciesParam data) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.alias = alias; + this.data = data; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.alias == null) { + throw new QiniuException(new NullPointerException("alias can't empty")); + } + if (this.data == null) { + throw new QiniuException(new NullPointerException("data can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("iam/v1/users"); + addPathSegment(this.alias); + addPathSegment("policies"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + byte[] body = Json.encode(this.data).getBytes(Constants.UTF_8); + this.setBody(body, 0, body.length, Client.JsonMime); + + super.buildBodyInfo(); + } + + /** + * 为子账号重新分配授权策略参数 + */ + public static final class UpdatedIamUserPoliciesParam { + + /** + * 授权策略别名集合 + */ + @SerializedName("policy_aliases") + private String[] policyAliases; + + /** + * 设置变量值 + * + * @param policyAliases 授权策略别名集合 + * @return Request + */ + public UpdatedIamUserPoliciesParam setPolicyAliases(String[] policyAliases) { + this.policyAliases = policyAliases; + return this; + } + } + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + } + + } +} diff --git a/src/main/java/com/qiniu/linking/README.md b/src/main/java/com/qiniu/linking/README.md index af977268f..0e31a1283 100644 --- a/src/main/java/com/qiniu/linking/README.md +++ b/src/main/java/com/qiniu/linking/README.md @@ -3,39 +3,37 @@ ## Features - 设备管理 - - [x] 新建设备: deviceManager.createDevice(appid,deviceName) - - [x] 新建网关设备: deviceManager.createDevice(appid, Device) - - [x] 获取设备列表:deviceManager.listDevice(appid,prefix,marker,limit,online) - - [x] 查询设备: deviceManager.getDevice(appid,deviceName) - - [x] 更新设备信息: deviceManager.updateDevice(appid,deviceName,operations) - - [x] 添加dak: deviceManager.addDeviceKey(appid,deviceName) - - [x] 通过dak查询设备: deviceManager.getDeviceByAccessKey(dak) - - [x] 删除dak: deviceManager.deleteDeviceKey(appid,deviceName,dak) - - [x] 获取设备的dak列表: deviceManager.queryDeviceKey(appid,deviceName1) - - [x] 将dak移到另外的设备上去: deviceManager.cloneDeviceKey(appid,fromDeviceName,toDeviceName,cleanSelfKeys,deleteDevice,dak) + - [x] 新建设备: deviceManager.createDevice(appid,deviceName) + - [x] 新建网关设备: deviceManager.createDevice(appid, Device) + - [x] 获取设备列表:deviceManager.listDevice(appid,prefix,marker,limit,online) + - [x] 查询设备: deviceManager.getDevice(appid,deviceName) + - [x] 更新设备信息: deviceManager.updateDevice(appid,deviceName,operations) + - [x] 添加dak: deviceManager.addDeviceKey(appid,deviceName) + - [x] 通过dak查询设备: deviceManager.getDeviceByAccessKey(dak) + - [x] 删除dak: deviceManager.deleteDeviceKey(appid,deviceName,dak) + - [x] 获取设备的dak列表: deviceManager.queryDeviceKey(appid,deviceName1) + - [x] 将dak移到另外的设备上去: deviceManager.cloneDeviceKey( + appid,fromDeviceName,toDeviceName,cleanSelfKeys,deleteDevice,dak) - dtoken生成 - - [x] 生成获取设备状态的token: auth.generateLinkingDeviceStatusTokenWithExpires(appid,deviceName,expires,actions) - - [x] 生成获取视频的token: auth.generateLinkingDeviceVodTokenWithExpires(appid,deviceName,expires) - - [x] 生成具有多种功能的token: auth.generateLinkingDeviceTokenWithExpires(appid,deviceName,expires) + - [x] 生成获取设备状态的token: auth.generateLinkingDeviceStatusTokenWithExpires(appid,deviceName,expires,actions) + - [x] 生成获取视频的token: auth.generateLinkingDeviceVodTokenWithExpires(appid,deviceName,expires) + - [x] 生成具有多种功能的token: auth.generateLinkingDeviceTokenWithExpires(appid,deviceName,expires) ## Contents - - [Usage](#usage) - - [设备管理](#设备管理) - - [新建设备](#新建设备) - - [新建网关设备](#新建网关设备) - - [获取设备列表](#获取设备列表) - - [查询设备](#查询设备) - - [更新设备信息](#更新设备信息) - - [添加dak](#添加dak) - - [通过dak查询设备](#通过dak查询设备) - - [删除dak](#删除dak) - - [获取设备的dak列表](#获取设备的dak列表) - - [将dak移到另外的设备上去](#将dak移到另外的设备上去) - - [dtoken](#dtoken) - - + - [设备管理](#设备管理) + - [新建设备](#新建设备) + - [新建网关设备](#新建网关设备) + - [获取设备列表](#获取设备列表) + - [查询设备](#查询设备) + - [更新设备信息](#更新设备信息) + - [添加dak](#添加dak) + - [通过dak查询设备](#通过dak查询设备) + - [删除dak](#删除dak) + - [获取设备的dak列表](#获取设备的dak列表) + - [将dak移到另外的设备上去](#将dak移到另外的设备上去) + - [dtoken](#dtoken) ## Usage @@ -63,6 +61,7 @@ device.setType(1); device.setMaxChannel(64); deviceManager.createDevice(appid, device); ``` + #### 获取设备列表 ```java @@ -70,11 +69,13 @@ DeviceListing deviceslist = deviceManager.listDevice(appid,prefix,marker,limit,o Device[] devices = deviceslist.items; String marker = deviceslist.marker; ``` + #### 查询设备 ```java Device device = deviceManager.getDevice(appid,deviceName); ``` + #### 更新设备信息 ```java @@ -82,52 +83,62 @@ PatchOperation[] operations={new PatchOperation("replace","segmentExpireDays",9) Device device= deviceManager.updateDevice(appid,deviceName,operations); //返回更新后的设备 ``` + #### 添加dak ```java DeviceKey[] keys = deviceManager.addDeviceKey(appid,deviceName); ``` + #### 通过dak查询设备 ```java Device device = deviceManager.getDeviceByAccessKey(dak); ``` + #### 删除dak ```java deviceManager.deleteDeviceKey(appid,deviceName,dak); ``` + #### 获取设备的dak列表 ```java DeviceKey[] keys = deviceManager.queryDeviceKey(appid,deviceName); ``` + #### 将dak移到另外的设备上去 ```java deviceManager.cloneDeviceKey(appid,fromDeviceName,toDeviceName2,true, false,dak) ``` - ### dtoken #### 生成具有多种功能的token: + ```java String[] = new String token = auth.generateLinkingDeviceTokenWithExpires(appid,deviceName,expires,actions); ``` +#### 生成获取视频的token: -#### 生成获取视频的token: ```java String token = auth.generateLinkingDeviceVodTokenWithExpires(appid,deviceName,expires) ``` + #### 生成获取设备状态的token: + ```java String[] actions = new String[]{Auth.DTOKEN_ACTION_STATUS,Auth.DTOKEN_ACTION_VOD,Auth.DTOKEN_ACTION_TUTK}; String token = auth.generateLinkingDeviceStatusTokenWithExpires(appid,deviceName,expires) ``` + 视频播放相关 api 编程模型说明: -如用户请求视频相关api(例如:[https://developer.qiniu.com/linking/api/5650/playback](https://developer.qiniu.com/linking/api/5650/playback))时进行业务服务器中转,会造成访问路径比较长, 因此建议服务端只进行dtoken的签算并提供给播放端,播放端直接请求视频播放相关的API,提升播放体验。 +如用户请求视频相关api( +例如:[https://developer.qiniu.com/linking/api/5650/playback](https://developer.qiniu.com/linking/api/5650/playback)) +时进行业务服务器中转,会造成访问路径比较长, 因此建议服务端只进行dtoken的签算并提供给播放端,播放端直接请求视频播放相关的API,提升播放体验。 具体下token签算参考 [https://developer.qiniu.com/linking/api/5680/the-signature-in-the-url](https://developer.qiniu.com/linking/api/5680/the-signature-in-the-url) ![WeChatWorkScreenshot_7a66f4d2-943f-4e19-bc09-04a394fe69f6](https://user-images.githubusercontent.com/34932312/68568688-41e01a00-0497-11ea-983c-9274a0ffb19f.png) diff --git a/src/main/java/com/qiniu/media/apis/ApiPfop.java b/src/main/java/com/qiniu/media/apis/ApiPfop.java new file mode 100644 index 000000000..1df99d5fa --- /dev/null +++ b/src/main/java/com/qiniu/media/apis/ApiPfop.java @@ -0,0 +1,281 @@ +package com.qiniu.media.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; +import com.qiniu.util.StringMap; + + +/** + * 触发持久化数据处理命令 + */ +public class ApiPfop extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiPfop(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiPfop(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 空间名称 + */ + private String bucketName; + + /** + * 对象名称 + */ + private String objectName; + + /** + * 数据处理命令列表,以 `;` 分隔,可以指定多个数据处理命令 + */ + private String fops = null; + + /** + * 处理结果通知接收 URL + */ + private String notifyUrl = null; + + /** + * 强制执行数据处理,设为 `1`,则可强制执行数据处理并覆盖原结果 + */ + private Integer force = null; + + /** + * 任务类型,支持 `0` 表示普通任务,`1` 表示闲时任务 + */ + private Integer type = null; + + /** + * 对列名,仅适用于普通任务 + */ + private String pipeline = null; + + /** + * 工作流模板 ID + */ + private String workflowTemplateId = null; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param bucketName 空间名称 【必须】 + * @param objectName 对象名称 【必须】 + */ + public Request(String urlPrefix, String bucketName, String objectName) { + super(urlPrefix); + this.setMethod(MethodType.POST); + this.setAuthType(AuthTypeQiniu); + this.bucketName = bucketName; + this.objectName = objectName; + } + + /** + * 设置参数【可选】 + * + * @param fops 数据处理命令列表,以 `;` 分隔,可以指定多个数据处理命令 + * @return Request + */ + public Request setFops(String fops) { + this.fops = fops; + return this; + } + + /** + * 设置参数【可选】 + * + * @param notifyUrl 处理结果通知接收 URL + * @return Request + */ + public Request setNotifyUrl(String notifyUrl) { + this.notifyUrl = notifyUrl; + return this; + } + + /** + * 设置参数【可选】 + * + * @param force 强制执行数据处理,设为 `1`,则可强制执行数据处理并覆盖原结果 + * @return Request + */ + public Request setForce(Integer force) { + this.force = force; + return this; + } + + /** + * 设置参数【可选】 + * + * @param type 任务类型,支持 `0` 表示普通任务,`1` 表示闲时任务 + * @return Request + */ + public Request setType(Integer type) { + this.type = type; + return this; + } + + /** + * 设置参数【可选】 + * + * @param pipeline 对列名,仅适用于普通任务 + * @return Request + */ + public Request setPipeline(String pipeline) { + this.pipeline = pipeline; + return this; + } + + /** + * 设置参数【可选】 + * + * @param workflowTemplateId 工作流模板 ID + * @return Request + */ + public Request setWorkflowTemplateId(String workflowTemplateId) { + this.workflowTemplateId = workflowTemplateId; + return this; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.bucketName == null) { + throw new QiniuException(new NullPointerException("bucketName can't empty")); + } + if (this.objectName == null) { + throw new QiniuException(new NullPointerException("objectName can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("pfop/"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + StringMap fields = new StringMap(); + fields.put("bucket", this.bucketName); + fields.put("key", this.objectName); + if (this.fops != null) { + fields.put("fops", this.fops); + } + if (this.notifyUrl != null) { + fields.put("notifyURL", this.notifyUrl); + } + if (this.force != null) { + fields.put("force", this.force); + } + if (this.type != null) { + fields.put("type", this.type); + } + if (this.pipeline != null) { + fields.put("pipeline", this.pipeline); + } + if (this.workflowTemplateId != null) { + fields.put("workflowTemplateID", this.workflowTemplateId); + } + this.setFormBody(fields); + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的持久化数据处理任务 ID + */ + private PfopId data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), PfopId.class); + } + + /** + * 响应信息 + * + * @return PfopId + */ + public PfopId getData() { + return this.data; + } + + /** + * 返回的持久化数据处理任务 ID + */ + public static final class PfopId { + + /** + * 持久化数据处理任务 ID + */ + @SerializedName("persistentId") + private String persistentId; + + /** + * 获取变量值 + * 持久化数据处理任务 ID + * + * @return persistentId + */ + public String getPersistentId() { + return this.persistentId; + } + } + } +} diff --git a/src/main/java/com/qiniu/media/apis/ApiPrefop.java b/src/main/java/com/qiniu/media/apis/ApiPrefop.java new file mode 100644 index 000000000..c285221c8 --- /dev/null +++ b/src/main/java/com/qiniu/media/apis/ApiPrefop.java @@ -0,0 +1,432 @@ +package com.qiniu.media.apis; + +import com.google.gson.annotations.SerializedName; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.MethodType; +import com.qiniu.storage.Api; +import com.qiniu.util.Json; + + +/** + * 查询持久化数据处理命令的执行状态 + */ +public class ApiPrefop extends Api { + + /** + * api 构建函数 + * + * @param client 请求 Client + */ + public ApiPrefop(Client client) { + super(client); + } + + /** + * api 构建函数 + * + * @param client 请求 Client + * @param config 请求流程的配置信息 + **/ + public ApiPrefop(Client client, Config config) { + super(client, config); + } + + /** + * 发起请求 + * + * @param request 请求对象【必须】 + * @return 响应对象 + * @throws QiniuException 请求异常 + */ + public Response request(Request request) throws QiniuException { + return new Response(requestWithInterceptor(request)); + } + + /** + * 请求信息 + */ + public static class Request extends Api.Request { + + /** + * 持久化数据处理任务 ID + */ + private String persistentId; + + /** + * 请求构造函数 + * + * @param urlPrefix 请求 scheme + host 【可选】 + * 若为空则会直接从 HostProvider 中获取 + * @param persistentId 持久化数据处理任务 ID 【必须】 + */ + public Request(String urlPrefix, String persistentId) { + super(urlPrefix); + this.setMethod(MethodType.GET); + this.setAuthType(AuthTypeQiniu); + this.persistentId = persistentId; + } + + @Override + protected void prepareToRequest() throws QiniuException { + if (this.persistentId == null) { + throw new QiniuException(new NullPointerException("persistentId can't empty")); + } + + super.prepareToRequest(); + } + + @Override + protected void buildPath() throws QiniuException { + addPathSegment("status/get/prefop"); + super.buildPath(); + } + + @Override + protected void buildQuery() throws QiniuException { + + addQueryPair("id", this.persistentId); + + super.buildQuery(); + } + + @Override + protected void buildHeader() throws QiniuException { + + super.buildHeader(); + } + + @Override + protected void buildBodyInfo() throws QiniuException { + + super.buildBodyInfo(); + } + + } + + /** + * 响应信息 + */ + public static class Response extends Api.Response { + + /** + * 返回的持久化数据处理任务信息 + */ + private PfopTask data; + + protected Response(com.qiniu.http.Response response) throws QiniuException { + super(response); + + this.data = Json.decode(response.bodyString(), PfopTask.class); + } + + /** + * 响应信息 + * + * @return PfopTask + */ + public PfopTask getData() { + return this.data; + } + + /** + * 返回的持久化数据处理任务中的云处理操作状态 + */ + public static final class PfopTaskItem { + + /** + * 云操作命令 + */ + @SerializedName("cmd") + private String command; + + /** + * 云操作状态码 + */ + @SerializedName("code") + private Integer code; + + /** + * 与状态码相对应的详细描述 + */ + @SerializedName("desc") + private String description; + + /** + * 如果处理失败,该字段会给出失败的详细原因 + */ + @SerializedName("error") + private String error; + + /** + * 云处理结果保存在服务端的唯一标识 + */ + @SerializedName("hash") + private String hash; + + /** + * 云处理结果的外链对象名称 + */ + @SerializedName("key") + private String objectName; + + /** + * 是否返回了旧的数据 + */ + @SerializedName("returnOld") + private Integer returnOld; + + /** + * 获取变量值 + * 云操作命令 + * + * @return command + */ + public String getCommand() { + return this.command; + } + + /** + * 获取变量值 + * 云操作状态码 + * + * @return code + */ + public Integer getCode() { + return this.code; + } + + /** + * 获取变量值 + * 与状态码相对应的详细描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 如果处理失败,该字段会给出失败的详细原因 + * + * @return error + */ + public String getError() { + return this.error; + } + + /** + * 获取变量值 + * 云处理结果保存在服务端的唯一标识 + * + * @return hash + */ + public String getHash() { + return this.hash; + } + + /** + * 获取变量值 + * 云处理结果的外链对象名称 + * + * @return objectName + */ + public String getObjectName() { + return this.objectName; + } + + /** + * 获取变量值 + * 是否返回了旧的数据 + * + * @return returnOld + */ + public Integer getReturnOld() { + return this.returnOld; + } + } + + /** + * 返回的持久化数据处理任务信息 + */ + public static final class PfopTask { + + /** + * 持久化数据处理任务 ID + */ + @SerializedName("id") + private String persistentId; + + /** + * 持久化数据处理任务状态码 + */ + @SerializedName("code") + private Integer code; + + /** + * 与状态码相对应的详细描述 + */ + @SerializedName("desc") + private String description; + + /** + * 源对象名称 + */ + @SerializedName("inputKey") + private String objectName; + + /** + * 源空间名称 + */ + @SerializedName("inputBucket") + private String bucketName; + + /** + * 云处理操作的处理队列 + */ + @SerializedName("pipeline") + private String pipeline; + + /** + * 如果没有,则表示通过 `api+fops` 命令提交的任务,否则遵循规则 `: `,其中 `` 当前可选 `workflow` 或 `trigger` + */ + @SerializedName("taskFrom") + private String taskFrom; + + /** + * 云处理请求的请求 ID + */ + @SerializedName("reqid") + private String requestId; + + /** + * 任务类型,支持 `0` 表示普通任务,`1` 表示闲时任务 + */ + @SerializedName("type") + private Integer type; + + /** + * 任务创建时间 + */ + @SerializedName("creationDate") + private String createdAt; + + /** + * 云处理操作列表 + */ + @SerializedName("items") + private PfopTaskItem[] items; + + /** + * 获取变量值 + * 持久化数据处理任务 ID + * + * @return persistentId + */ + public String getPersistentId() { + return this.persistentId; + } + + /** + * 获取变量值 + * 持久化数据处理任务状态码 + * + * @return code + */ + public Integer getCode() { + return this.code; + } + + /** + * 获取变量值 + * 与状态码相对应的详细描述 + * + * @return description + */ + public String getDescription() { + return this.description; + } + + /** + * 获取变量值 + * 源对象名称 + * + * @return objectName + */ + public String getObjectName() { + return this.objectName; + } + + /** + * 获取变量值 + * 源空间名称 + * + * @return bucketName + */ + public String getBucketName() { + return this.bucketName; + } + + /** + * 获取变量值 + * 云处理操作的处理队列 + * + * @return pipeline + */ + public String getPipeline() { + return this.pipeline; + } + + /** + * 获取变量值 + * 如果没有,则表示通过 `api+fops` 命令提交的任务,否则遵循规则 `: `,其中 `` 当前可选 `workflow` 或 `trigger` + * + * @return taskFrom + */ + public String getTaskFrom() { + return this.taskFrom; + } + + /** + * 获取变量值 + * 云处理请求的请求 ID + * + * @return requestId + */ + public String getRequestId() { + return this.requestId; + } + + /** + * 获取变量值 + * 任务类型,支持 `0` 表示普通任务,`1` 表示闲时任务 + * + * @return type + */ + public Integer getType() { + return this.type; + } + + /** + * 获取变量值 + * 任务创建时间 + * + * @return createdAt + */ + public String getCreatedAt() { + return this.createdAt; + } + + /** + * 获取变量值 + * 云处理操作列表 + * + * @return items + */ + public PfopTaskItem[] getItems() { + return this.items; + } + } + } +} diff --git a/src/main/java/com/qiniu/processing/OperationManager.java b/src/main/java/com/qiniu/processing/OperationManager.java index ab231cac2..62fcbd0c0 100644 --- a/src/main/java/com/qiniu/processing/OperationManager.java +++ b/src/main/java/com/qiniu/processing/OperationManager.java @@ -2,7 +2,9 @@ import com.qiniu.common.QiniuException; import com.qiniu.http.Client; -import com.qiniu.http.Response; +import com.qiniu.media.apis.ApiPfop; +import com.qiniu.media.apis.ApiPrefop; +import com.qiniu.storage.Api; import com.qiniu.storage.Configuration; import com.qiniu.util.Auth; import com.qiniu.util.StringMap; @@ -80,25 +82,100 @@ public String pfop(String bucket, String key, String fops) throws QiniuException * @param bucket 空间名 * @param key 文件名 * @param fops fops指令,如果有多个指令,需要使用分号(;)进行拼接,例如 avthumb/mp4/xxx|saveas/xxx;vframe/jpg/xxx|saveas/xxx - * @param params notifyURL、force、pipeline、type等参数 + * @param params notifyURL、force、pipeline、type、persistentWorkflowTemplateID等参数 * @return persistentId 请求返回的任务ID,可以根据该ID查询任务状态 * @throws QiniuException 触发失败异常,包含错误响应等信息 * 相关链接 */ public String pfop(String bucket, String key, String fops, StringMap params) throws QiniuException { - params = params == null ? new StringMap() : params; - params.put("bucket", bucket).put("key", key).put("fops", fops); - byte[] data = StringUtils.utf8Bytes(params.formString()); - String url = configuration.apiHost(auth.accessKey, bucket) + "/pfop/"; - StringMap headers = auth.authorizationV2(url, "POST", data, Client.FormMime); - Response response = client.post(url, data, headers, Client.FormMime); + if (params == null) { + params = new StringMap(); + } + params.put("fops", fops); + return pfop(bucket, key, params); + } + + /** + * 发送请求对空间中的文件进行持久化处理 + * + * @param bucket 空间名 + * @param key 文件名 + * @param params notifyURL、force、pipeline、type、fops、persistentWorkflowTemplateID 等参数 + * @return persistentId 请求返回的任务ID,可以根据该ID查询任务状态 + * @throws QiniuException 触发失败异常,包含错误响应等信息 + * 相关链接 + */ + public String pfop(String bucket, String key, StringMap params) throws QiniuException { + Integer force = null; + if (params.get("force") != null) { + if (params.get("force") instanceof Integer) { + force = (Integer) params.get("force"); + } else { + throw QiniuException.unrecoverable("force type error, should be Integer"); + } + } + String pipeline = null; + if (params.get("pipeline") != null) { + if (params.get("pipeline") instanceof String) { + pipeline = (String) params.get("pipeline"); + } else { + throw QiniuException.unrecoverable("pipeline type error, should be String"); + } + } + String notifyUrl = null; + if (params.get("notifyURL") != null) { + if (params.get("notifyURL") instanceof String) { + notifyUrl = (String) params.get("notifyURL"); + } else { + throw QiniuException.unrecoverable("notifyURL type error, should be String"); + } + } + Integer type = null; + if (params.get("type") != null) { + if (params.get("type") instanceof Integer) { + type = (Integer) params.get("type"); + } else { + throw QiniuException.unrecoverable("type type error, should be Integer"); + } + } + String fops = null; + if (params.get("fops") != null) { + if (params.get("fops") instanceof String) { + fops = (String) params.get("fops"); + } else { + throw QiniuException.unrecoverable("fops type error, should be String"); + } + } + String workflowTemplateID = null; + if (params.get("persistentWorkflowTemplateID") != null) { + if (params.get("persistentWorkflowTemplateID") instanceof String) { + workflowTemplateID = (String) params.get("persistentWorkflowTemplateID"); + } else { + throw QiniuException.unrecoverable("persistentWorkflowTemplateID type error, should be String"); + } + } + + String url = configuration.apiHost(auth.accessKey, bucket); + ApiPfop.Request request = new ApiPfop.Request(url, bucket, key) + .setFops(fops) + .setWorkflowTemplateId(workflowTemplateID) + .setPipeline(pipeline) + .setForce(force) + .setNotifyUrl(notifyUrl) + .setType(type); + ApiPfop api = new ApiPfop(client, new Api.Config.Builder() + .setAuth(auth) + .build()); + ApiPfop.Response response = api.request(request); + if (response == null) { + throw QiniuException.unrecoverable("unknown error"); + } if (!response.isOK()) { - throw new QiniuException(response); + throw new QiniuException(response.getResponse()); } - PfopResult status = response.jsonToObject(PfopResult.class); - response.close(); + ApiPfop.Response.PfopId status = response.getData(); if (status != null) { - return status.persistentId; + return status.getPersistentId(); } return null; } @@ -211,14 +288,7 @@ public OperationStatus prefop(String persistentId) throws QiniuException { */ @Deprecated public T prefop(String persistentId, Class retClass) throws QiniuException { - String url = String.format("%s/status/get/prefop?id=%s", configuration.apiHost(), persistentId); - Response response = this.client.get(url); - if (!response.isOK()) { - throw new QiniuException(response); - } - T object = response.jsonToObject(retClass); - response.close(); - return object; + return prefop(null, persistentId, retClass); } /** @@ -245,17 +315,25 @@ public OperationStatus prefop(String bucket, String persistentId) throws QiniuEx * @throws QiniuException 异常 */ public T prefop(String bucket, String persistentId, Class retClass) throws QiniuException { - String url = String.format("%s/status/get/prefop?id=%s", configuration.apiHost(auth.accessKey, bucket), persistentId); - Response response = this.client.get(url); + String url = null; + if (!StringUtils.isNullOrEmpty(bucket)) { + url = configuration.apiHost(auth.accessKey, bucket); + } else { + url = configuration.apiHost(); + } + + ApiPrefop.Request request = new ApiPrefop.Request(url, persistentId); + ApiPrefop api = new ApiPrefop(client, new Api.Config.Builder() + .setAuth(auth) + .build()); + ApiPrefop.Response response = api.request(request); + if (response == null) { + throw QiniuException.unrecoverable("unknown error"); + } if (!response.isOK()) { - throw new QiniuException(response); + throw new QiniuException(response.getResponse()); } - T object = response.jsonToObject(retClass); - response.close(); - return object; - } - private class PfopResult { - public String persistentId; + return response.getResponse().jsonToObject(retClass); } } diff --git a/src/main/java/com/qiniu/processing/OperationStatus.java b/src/main/java/com/qiniu/processing/OperationStatus.java index 64bf80abb..33e577ce4 100644 --- a/src/main/java/com/qiniu/processing/OperationStatus.java +++ b/src/main/java/com/qiniu/processing/OperationStatus.java @@ -30,6 +30,13 @@ public class OperationStatus { */ public String inputBucket; + /*** + * taskFrom + * 1. 如果没有 taskFrom, 则表示是通过 api+fops命令 提交的任务, 否则见 2 + * 2. taskFrom 字段规则: : ,其中 source 当前可选: workflow|trigger + **/ + public String taskFrom; + /** * 云处理操作的处理队列 */ diff --git a/src/main/java/com/qiniu/qvs/DeviceManager.java b/src/main/java/com/qiniu/qvs/DeviceManager.java index 6f462a38f..ebd677434 100644 --- a/src/main/java/com/qiniu/qvs/DeviceManager.java +++ b/src/main/java/com/qiniu/qvs/DeviceManager.java @@ -1,9 +1,9 @@ package com.qiniu.qvs; import com.qiniu.common.QiniuException; -import com.qiniu.qvs.model.*; import com.qiniu.http.Client; import com.qiniu.http.Response; +import com.qiniu.qvs.model.*; import com.qiniu.util.Auth; import com.qiniu.util.StringMap; import com.qiniu.util.UrlUtils; diff --git a/src/main/java/com/qiniu/qvs/README.md b/src/main/java/com/qiniu/qvs/README.md index 74097c9f4..669a70b45 100644 --- a/src/main/java/com/qiniu/qvs/README.md +++ b/src/main/java/com/qiniu/qvs/README.md @@ -4,13 +4,13 @@ - 空间管理 - [x] 创建空间: createNameSpace(NameSpace nameSpace) - - [x] 删除空间: deleteNameSpace(String namespaceId) - - [x] 更新空间: updateNameSpace(String namespaceId, PatchOperation[] patchOperation) - - [x] 查询空间信息: queryNameSpace(String namespaceId) - - [x] 获取空间列表: listNameSpace(int offset, int line, String sortBy) - - [x] 禁用空间: disableNameSpace(String namespaceId) + - [x] 删除空间: deleteNameSpace(String namespaceId) + - [x] 更新空间: updateNameSpace(String namespaceId, PatchOperation[] patchOperation) + - [x] 查询空间信息: queryNameSpace(String namespaceId) + - [x] 获取空间列表: listNameSpace(int offset, int line, String sortBy) + - [x] 禁用空间: disableNameSpace(String namespaceId) - [x] 启用空间: enableNameSpace(String namespaceId) - + - 流管理 - [x] 创建流: createStream(String namespaceId, Stream stream) - [x] 删除流: deleteStream(String namespaceId, String streamId) @@ -20,19 +20,20 @@ - [x] 获取流地址 - [x] 动态模式: dynamicPublishPlayURL(String namespaceId, String streamId, DynamicLiveRoute dynamicLiveRoute) - [x] 静态模式: staticPublishPlayURL(String namespaceId, String streamId, StaticLiveRoute staticLiveRoute) - - [x] 禁用流: disableStream(String namespaceId, String streamId) + - [x] 禁用流: disableStream(String namespaceId, String streamId) - [x] 启用流: enableStream(String namespaceId, String streamId) - - [x] 查询推流记录: queryStreamPubHistories(String namespaceId, String streamId, int start, int end, int offset, int line) + - [x] 查询推流记录: queryStreamPubHistories(String namespaceId, String streamId, int start, int end, int offset, int + line) - [x] 停用流: stopStream(String namespaceId, String streamId) - + - 设备管理 - - [x] 创建设备: createDevice(String namespaceId, Device device) - - [x] 删除设备: deleteDevice(String namespaceId, String gbId) - - [x] 更新设备: updateDevice(String namespaceId, String gbId, PatchOperation[] patchOperation) - - [x] 查询设备信息: queryDevice(String namespaceId, String gbId) - - [x] 获取设备列表: listDevice(String namespaceId, int offset, int line, String prefix, String state, int qtype) - - [x] 获取通道列表: listChannels(String namespaceId, String gbId, String prefix) - - [x] 启动设备拉流: startDevice(String namespaceId, String gbId, String channels) + - [x] 创建设备: createDevice(String namespaceId, Device device) + - [x] 删除设备: deleteDevice(String namespaceId, String gbId) + - [x] 更新设备: updateDevice(String namespaceId, String gbId, PatchOperation[] patchOperation) + - [x] 查询设备信息: queryDevice(String namespaceId, String gbId) + - [x] 获取设备列表: listDevice(String namespaceId, int offset, int line, String prefix, String state, int qtype) + - [x] 获取通道列表: listChannels(String namespaceId, String gbId, String prefix) + - [x] 启动设备拉流: startDevice(String namespaceId, String gbId, String channels) - [x] 停止设备拉流: stopDevice(String namespaceId, String gbId, String channels) - 模板管理 @@ -43,43 +44,44 @@ - [x] 获取模板列表: listTemplate(int offset, int line, int templateType, String match) - 录制管理相关接口 - - [x] 查询录制记录: queryStreamRecordHistories(String namespaceId, String streamId, int start, int end, int line, String marker) - - [x] 获取截图列表: streamsSnapshots(String namespaceId, String streamId, int start, int end, int type, int line, String marker) + - [x] 查询录制记录: queryStreamRecordHistories(String namespaceId, String streamId, int start, int end, int line, + String marker) + - [x] 获取截图列表: streamsSnapshots(String namespaceId, String streamId, int start, int end, int type, int line, + String marker) - [x] 获取直播封面截图: queryStreamCover(String namespaceId, String streamId) ## Contents - - [Usage](#usage) - - [Init](#Init) - - - [空间管理](#空间管理) - - - [创建空间](#创建空间) - - [查询空间](#查询空间) - - [更新空间](#更新空间) - - [获取空间列表](#获取空间列表) - - [禁用空间](#禁用空间) - - [启用空间](#启用空间) - - [删除空间](#删除空间) - - - [流管理](#流管理) - - * [创建流](#创建流) - * [查询流](#查询流) - * [更新流](#更新流) - * [获取流列表](#获取流列表) - * [静态模式获取流地址](#静态模式获取流地址) - * [动态模式获取流地址](#动态模式获取流地址) - * [查询推流历史记录](#查询推流历史记录) - * [禁用流](#禁用流) - * [启用流](#启用流) - * [删除流](#删除流) - * [停用流](#停用流) - + - [Init](#Init) + + - [空间管理](#空间管理) + + - [创建空间](#创建空间) + - [查询空间](#查询空间) + - [更新空间](#更新空间) + - [获取空间列表](#获取空间列表) + - [禁用空间](#禁用空间) + - [启用空间](#启用空间) + - [删除空间](#删除空间) + + - [流管理](#流管理) + + * [创建流](#创建流) + * [查询流](#查询流) + * [更新流](#更新流) + * [获取流列表](#获取流列表) + * [静态模式获取流地址](#静态模式获取流地址) + * [动态模式获取流地址](#动态模式获取流地址) + * [查询推流历史记录](#查询推流历史记录) + * [禁用流](#禁用流) + * [启用流](#启用流) + * [删除流](#删除流) + * [停用流](#停用流) + - [设备管理](#设备管理) - + - [创建设备](#创建设备) - [删除设备](#删除设备) - [查询设备](#查询设备) @@ -88,22 +90,20 @@ - [获取通道列表](#获取通道列表) - [启动设备拉流](#启动设备拉流) - [停止设备拉流](#停止设备拉流) - - - [模板管理](#模板管理) - - * [创建模板](#创建模板) - * [查询模板](#查询模板) - * [更新模板](#更新模板) - * [获取模板列表](#获取模板列表) - * [删除模板](#删除模板) - - - [录制管理](#录制管理) - - - [查询录制记录](#查询录制记录) - - [查询流封面](#查询流封面) - - [获取截图列表](#获取截图列表) - - + + - [模板管理](#模板管理) + + * [创建模板](#创建模板) + * [查询模板](#查询模板) + * [更新模板](#更新模板) + * [获取模板列表](#获取模板列表) + * [删除模板](#删除模板) + + - [录制管理](#录制管理) + + - [查询录制记录](#查询录制记录) + - [查询流封面](#查询流封面) + - [获取截图列表](#获取截图列表) ## Usage @@ -183,8 +183,6 @@ nameSpaceManager.enableNameSpace(namespaceId); nameSpaceManager.deleteNameSpace(namespaceId); ``` - - ### 流管理 #### 创建流 @@ -279,8 +277,6 @@ streamManager.deleteStream(namespaceId, stream.getStreamID()); streamManager.stopStream(namespaceId, stream.getStreamID()); ``` - - ### 设备管理 #### 创建设备 @@ -354,8 +350,6 @@ deviceManager.startDevice(namespaceId, device.getGbId(), "31011500991320000056") deviceManager.stopDevice(namespaceId, device.getGbId(), "31011500991320000056"); ``` - - ### 模板管理 #### 创建模板 diff --git a/src/main/java/com/qiniu/qvs/model/ChannelInfo.java b/src/main/java/com/qiniu/qvs/model/ChannelInfo.java index 155d2a6a0..843a278d1 100644 --- a/src/main/java/com/qiniu/qvs/model/ChannelInfo.java +++ b/src/main/java/com/qiniu/qvs/model/ChannelInfo.java @@ -11,27 +11,27 @@ public ChannelInfo(String[] channels, int start, int end) { this.end = end; } - public void setChannels(String[] channels) { - this.channels = channels; - } - - public void setStart(int start) { - this.start = start; - } - - public void setEnd(int end) { - this.end = end; - } - public String[] getChannels() { return channels; } + public void setChannels(String[] channels) { + this.channels = channels; + } + public int getStart() { return start; } + public void setStart(int start) { + this.start = start; + } + public int getEnd() { return end; } + + public void setEnd(int end) { + this.end = end; + } } diff --git a/src/main/java/com/qiniu/rtc/QRTC.java b/src/main/java/com/qiniu/rtc/QRTC.java index 69b02633f..90d8bd034 100644 --- a/src/main/java/com/qiniu/rtc/QRTC.java +++ b/src/main/java/com/qiniu/rtc/QRTC.java @@ -23,15 +23,13 @@ public class QRTC { //版本号 public static final String VERSION = "8.0"; + private static final Map holder = new ConcurrentHashMap<>(16); + private static volatile QRTCClient client = null; private QRTC() { } - private static volatile QRTCClient client = null; - - private static final Map holder = new ConcurrentHashMap<>(16); - /** * 初始化QRTCClient * diff --git a/src/main/java/com/qiniu/rtc/QRTCClient.java b/src/main/java/com/qiniu/rtc/QRTCClient.java index a74464582..8984406b7 100644 --- a/src/main/java/com/qiniu/rtc/QRTCClient.java +++ b/src/main/java/com/qiniu/rtc/QRTCClient.java @@ -19,17 +19,15 @@ public class QRTCClient { private final String accessKey; private final String secretKey; - + // 应用ID + private final String appId; //rtc 房间服务接口 private RoomService roomService; private ForwardService forwardService; private CallbackService callbackService; private MergeService mergeService; private MergeServiceV4 mergeServiceV4; - private AppService appService; - // 应用ID - private final String appId; //初始化的时候就把auth做了 public QRTCClient(String accessKey, String secretKey, String appId) { @@ -165,7 +163,7 @@ public Response call() throws QiniuException { * 指定一个用户踢出房间 * * @param roomName roomName - * @param userId userId + * @param userId userId * @return QRTCResult * @throws QiniuException 异常 */ @@ -183,8 +181,8 @@ public Response call() throws QiniuException { * 获取当前所有活跃的房间 * * @param roomNamePrefix roomNamePrefix - * @param offset offset - * @param limit limit + * @param offset offset + * @param limit limit * @return QRTCResult * @throws QiniuException 异常 */ @@ -223,7 +221,7 @@ public String getRoomToken(String roomName, String userId, * 创建单路转推任务 * * @param roomId roomId - * @param param param + * @param param param * @return QRTCResult * @throws QiniuException 异常 */ @@ -241,7 +239,7 @@ public Response call() throws QiniuException { * 停止单路转推的能力 * * @param roomId roomId - * @param param param + * @param param param * @return QRTCResult * @throws QiniuException 异常 */ @@ -279,7 +277,7 @@ public Response call() throws QiniuException { /** * 创建合流任务 * - * @param roomName roomName + * @param roomName roomName * @param mergeParam mergeParam * @return QRTCResult * @throws QiniuException 异常 @@ -299,8 +297,8 @@ public Response call() throws QiniuException { * 更新合流track信息 * * @param mergeTrackParam mergeTrackParam - * @param roomName roomName - * @param jobId jobId + * @param roomName roomName + * @param jobId jobId * @return QRTCResult * @throws QiniuException 异常 */ @@ -321,8 +319,8 @@ public Response call() throws QiniuException { * 更新合理水印信息 * * @param watermarksParam watermarksParam - * @param roomName roomName - * @param jobId jobId + * @param roomName roomName + * @param jobId jobId * @return QRTCResult * @throws QiniuException 异常 */ diff --git a/src/main/java/com/qiniu/rtc/model/ForwardParam.java b/src/main/java/com/qiniu/rtc/model/ForwardParam.java index 36518f748..5e58e3d03 100644 --- a/src/main/java/com/qiniu/rtc/model/ForwardParam.java +++ b/src/main/java/com/qiniu/rtc/model/ForwardParam.java @@ -20,6 +20,9 @@ public ForwardParam(String id, String publishUrl, String playerId) { this.playerId = playerId; } + public ForwardParam() { + } + @Data public static class TrackInfo { private String trackId; @@ -31,7 +34,4 @@ public TrackInfo(String trackId) { public TrackInfo() { } } - - public ForwardParam() { - } } diff --git a/src/main/java/com/qiniu/rtc/model/MergeTrackParam.java b/src/main/java/com/qiniu/rtc/model/MergeTrackParam.java index 9d325b82e..38250ccbc 100644 --- a/src/main/java/com/qiniu/rtc/model/MergeTrackParam.java +++ b/src/main/java/com/qiniu/rtc/model/MergeTrackParam.java @@ -12,22 +12,6 @@ public class MergeTrackParam { private List remove; private List all; - @Data - public static class MergeTrack { - private String trackID; - private int x; - private int y; - private int z; - private int w; - private int h; - - /** - * @see com.qiniu.rtc.model.StretchModeEnum - */ - private String stretchMode; - private boolean supportSei = false; - } - public enum ModeEnum { //增量,指定add和remove INCREMENT(0), @@ -44,4 +28,20 @@ public int getVal() { return val; } } + + @Data + public static class MergeTrack { + private String trackID; + private int x; + private int y; + private int z; + private int w; + private int h; + + /** + * @see com.qiniu.rtc.model.StretchModeEnum + */ + private String stretchMode; + private boolean supportSei = false; + } } diff --git a/src/main/java/com/qiniu/rtc/service/AbstractService.java b/src/main/java/com/qiniu/rtc/service/AbstractService.java index 703b67abf..62d6709f3 100644 --- a/src/main/java/com/qiniu/rtc/service/AbstractService.java +++ b/src/main/java/com/qiniu/rtc/service/AbstractService.java @@ -10,13 +10,12 @@ import com.qiniu.util.StringMap; public abstract class AbstractService { + public static final String JSON_MIME = "application/json"; + protected final String host = "https://rtc.qiniuapi.com"; protected Client httpClient; protected Auth auth; - protected final String host = "https://rtc.qiniuapi.com"; protected Gson gson; - public static final String JSON_MIME = "application/json"; - /** * 初始化 * diff --git a/src/main/java/com/qiniu/rtc/service/ForwardService.java b/src/main/java/com/qiniu/rtc/service/ForwardService.java index 3de9e356d..b15b79d13 100644 --- a/src/main/java/com/qiniu/rtc/service/ForwardService.java +++ b/src/main/java/com/qiniu/rtc/service/ForwardService.java @@ -60,7 +60,7 @@ public Response stopForwardJob(String appId, String roomId, ForwardParam param) * 参数校验 * * @param roomId 房间ID - * @param param 转推参数对象 + * @param param 转推参数对象 * @throws IllegalArgumentException 参数不合法异常 */ private void checkParams(String roomId, ForwardParam param) throws IllegalArgumentException { diff --git a/src/main/java/com/qiniu/rtc/service/MergeServiceV4.java b/src/main/java/com/qiniu/rtc/service/MergeServiceV4.java index 8bd0c5787..4f13836ac 100644 --- a/src/main/java/com/qiniu/rtc/service/MergeServiceV4.java +++ b/src/main/java/com/qiniu/rtc/service/MergeServiceV4.java @@ -1,9 +1,9 @@ package com.qiniu.rtc.service; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Response; import com.qiniu.rtc.model.MergeJob; import com.qiniu.util.Auth; -import com.qiniu.http.Response; -import com.qiniu.common.QiniuException; import com.qiniu.util.StringUtils; import java.util.HashMap; diff --git a/src/main/java/com/qiniu/rtc/service/RoomService.java b/src/main/java/com/qiniu/rtc/service/RoomService.java index b452f1a70..b6c0a682d 100644 --- a/src/main/java/com/qiniu/rtc/service/RoomService.java +++ b/src/main/java/com/qiniu/rtc/service/RoomService.java @@ -3,9 +3,9 @@ import com.qiniu.common.QiniuException; import com.qiniu.http.Response; +import com.qiniu.rtc.model.RoomAccess; import com.qiniu.rtc.model.RoomParam; import com.qiniu.rtc.model.UrlParam; -import com.qiniu.rtc.model.RoomAccess; import com.qiniu.util.Auth; /** diff --git a/src/main/java/com/qiniu/storage/Api.java b/src/main/java/com/qiniu/storage/Api.java index dd4fe7621..9fa54f4a2 100644 --- a/src/main/java/com/qiniu/storage/Api.java +++ b/src/main/java/com/qiniu/storage/Api.java @@ -6,11 +6,12 @@ import com.qiniu.http.RequestStreamBody; import com.qiniu.util.*; import okhttp3.MediaType; -import okhttp3.MultipartBody; import okhttp3.RequestBody; +import okio.Buffer; import okio.BufferedSink; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLEncoder; @@ -31,8 +32,7 @@ public class Api { * @param client 请求的 Client【必须】 **/ protected Api(Client client) { - this.client = client; - this.interceptors = null; + this(client, (Config) null); } /** @@ -41,7 +41,7 @@ protected Api(Client client) { * @param client 请求的 Client 【必须】 * @param config 请求的流程的配置信息 **/ - Api(Client client, Config config) { + protected Api(Client client, Config config) { this(client, Api.createInterceptors(config)); } @@ -51,7 +51,7 @@ protected Api(Client client) { * @param client 请求的 Client【必须】 * @param interceptors 请求的拦截器 **/ - Api(Client client, Interceptor... interceptors) { + protected Api(Client client, Interceptor... interceptors) { if (client == null) { client = new Client(); } @@ -125,6 +125,11 @@ protected com.qiniu.http.Response requestByClient(Request request) throws QiniuE ApiUtils.throwInvalidRequestParamException("request"); } + request = request.clone(); + if (request == null) { + throw QiniuException.unrecoverable("request clone error, just retry"); + } + request.prepareToRequest(); return innerRequest(request); @@ -135,6 +140,11 @@ protected com.qiniu.http.Response requestWithInterceptor(Request request) throws ApiUtils.throwInvalidRequestParamException("request"); } + request = request.clone(); + if (request == null) { + throw QiniuException.unrecoverable("request clone error, just retry"); + } + request.prepareToRequest(); if (interceptors == null || interceptors.size() == 0) { @@ -167,6 +177,10 @@ protected Response request(Request request) throws QiniuException { return new Response(requestWithInterceptor(request)); } + interface Handler { + Response handle(Request request) throws QiniuException; + } + public static final class Config { public static final int DebugLevelNone = ApiInterceptorDebug.LevelPrintNone; @@ -254,66 +268,142 @@ private Config(Auth auth, int hostRetryMax, int singleHostRetryMax, Retry.Interv public static final class Builder { private Auth auth; - private int hostRetryMax; - private int singleHostRetryMax; - private Retry.Interval retryInterval; - private Retry.RetryCondition retryCondition; - private Retry.HostFreezeCondition hostFreezeCondition; - private HostProvider hostProvider; - private int hostFreezeDuration; - private int requestDebugLevel; + private int hostRetryMax = 1; + private int singleHostRetryMax = 1; + private Retry.Interval retryInterval = Retry.defaultInterval(); + private Retry.RetryCondition retryCondition = Retry.defaultCondition(); + private Retry.HostFreezeCondition hostFreezeCondition = Retry.defaultHostFreezeCondition(); + private HostProvider hostProvider = null; + private int hostFreezeDuration = 10 * 60 * 1000; + private int requestDebugLevel = DebugLevelNone; private int responseDebugLevel; + /** + * 设置鉴权信息 + * + * @param auth 鉴权信息 + * @return Builder + **/ public Builder setAuth(Auth auth) { this.auth = auth; return this; } + /** + * 当有多个 Host,在请求失败且请求可以重试时,最多切换 Host 的次数 + * 已经使用过的 Host 在冻结期内不会被使用 + * + * @param hostRetryMax 切换 Host 的最大次数 + * @return Builder + **/ public Builder setHostRetryMax(int hostRetryMax) { this.hostRetryMax = hostRetryMax; return this; } + /** + * 在请求失败且请求可以重试时,单个域名最大可以重试的次数 + * + * @param singleHostRetryMax 单个域名最大可以重试的次数 + * @return Builder + **/ public Builder setSingleHostRetryMax(int singleHostRetryMax) { this.singleHostRetryMax = singleHostRetryMax; return this; } + /** + * 设置请求重试的时间间隔 + * + * @param retryInterval 固定大小的重试时间间隔,单位:毫秒 + * @return Builder + **/ public Builder setRetryInterval(int retryInterval) { this.retryInterval = Retry.staticInterval(retryInterval); return this; } + /** + * 设置请求重试的时间间隔 + * + * @param retryInterval 可动态调整的重试时间间隔 + * @return Builder + **/ public Builder setRetryInterval(Retry.Interval retryInterval) { this.retryInterval = retryInterval; return this; } + /** + * 设置重试条件 + * + * @param retryCondition 重试条件 + * @return Builder + **/ public Builder setRetryCondition(Retry.RetryCondition retryCondition) { this.retryCondition = retryCondition; return this; } + /** + * 设置域名冻结时间 + * 当某个域名请求失败,且该域名短时间内不可在使用则会被冻结,切换其他域名进行重试 + * + * @param hostFreezeDuration 域名冻结时间,单位:毫秒 + * @return Builder + **/ public Builder setHostFreezeDuration(int hostFreezeDuration) { this.hostFreezeDuration = hostFreezeDuration; return this; } + /** + * 设置域名提供者 + * 当请求域名被冻结,且可以请求切换域名进行重试,此时会尝试从域名提供者中获取一个域名进行重试 + * + * @param hostProvider 域名提供者 + * @return Builder + **/ public Builder setHostProvider(HostProvider hostProvider) { this.hostProvider = hostProvider; return this; } + /** + * 设置域名冻结条件 + * 根据相应情况来判断域名是否可以再次被使用,不过不可则需要冻结(比如:服务内部繁忙需切换域名重试) + * + * @param hostFreezeCondition 域名冻结条件 + * @return Builder + **/ public Builder setHostFreezeCondition(Retry.HostFreezeCondition hostFreezeCondition) { this.hostFreezeCondition = hostFreezeCondition; return this; } + /** + * 设置请求 Debug 的等级 + * {@link #DebugLevelNone} + * {@link #DebugLevelNormal} + * {@link #DebugLevelDetail} + * + * @param requestDebugLevel 请求 Debug 的等级 + * @return Builder + **/ public Builder setRequestDebugLevel(int requestDebugLevel) { this.requestDebugLevel = requestDebugLevel; return this; } + /** + * 设置响应 Debug 的等级 + * {@link #DebugLevelNone} + * {@link #DebugLevelNormal} + * {@link #DebugLevelDetail} + * + * @param responseDebugLevel 响应 Debug 的等级 + * @return Builder + **/ public Builder setResponseDebugLevel(int responseDebugLevel) { this.responseDebugLevel = responseDebugLevel; return this; @@ -330,6 +420,16 @@ public Config build() { */ public static class Request implements Cloneable { + protected static final int AuthTypeNone = 0; + protected static final int AuthTypeQiniu = 1; + + /** + * 鉴权类型 + * 0:不鉴权 + * 1:Qiniu 鉴权 + */ + private int authType = AuthTypeNone; + /** * 请求的 scheme * eg: https @@ -400,6 +500,10 @@ protected Request(String urlPrefix) { } try { + if (!urlPrefix.startsWith("http://") && !urlPrefix.startsWith("https://")) { + urlPrefix = "http://" + urlPrefix; + } + URL url = new URL(urlPrefix); this.scheme = url.getProtocol(); this.host = url.getHost(); @@ -441,6 +545,19 @@ protected Request(String scheme, String host) { this.host = host; } + /** + * 设置鉴权类型 + * 0:不鉴权 + * 1:Qiniu 鉴权 + */ + protected int getAuthType() { + return this.authType; + } + + protected void setAuthType(int authType) { + this.authType = authType; + } + /** * 获取请求的 urlPrefix, scheme + host * eg: https://upload.qiniu.com @@ -489,6 +606,18 @@ protected void addPathSegment(String segment) { path = null; } + protected void addPathSegment(Boolean segment) { + addPathSegment((Boolean) segment ? "true" : "false"); + } + + protected void addPathSegment(Integer segment) { + addPathSegment(segment + ""); + } + + protected void addPathSegment(Long segment) { + addPathSegment(segment + ""); + } + String getMethodString() { if (method == null) { return "GET"; @@ -503,6 +632,18 @@ MethodType getMethod() { return method; } + /** + * 设置 Http 请求方式 + * + * @param method Http 请求方式 + */ + protected void setMethod(MethodType method) { + if (method == null) { + return; + } + this.method = method; + } + /** * 获取 url 的 path 信息 * @@ -528,7 +669,6 @@ protected void buildPath() throws QiniuException { } } - /** * 增加 query 键值对 * @@ -543,6 +683,18 @@ protected void addQueryPair(String key, String value) { query = null; } + protected void addQueryPair(String key, Integer value) { + addQueryPair(key, value + ""); + } + + protected void addQueryPair(String key, Long value) { + addQueryPair(key, value + ""); + } + + protected void addQueryPair(String key, Boolean value) { + addQueryPair(key, value + ""); + } + /** * 获取 query 字符串 * @@ -584,20 +736,9 @@ protected void buildQuery() throws QiniuException { query = builder.toString(); } - /** - * 设置 Http 请求方式 - * - * @param method Http 请求方式 - */ - protected void setMethod(MethodType method) { - if (method == null) { - return; - } - this.method = method; - } - /** * 增加请求头 + * 注:用户不可使用此方法 * * @param key key * @param value value @@ -628,12 +769,12 @@ public StringMap getHeader() throws QiniuException { header.put(key, this.header.get(key)); } - if (body == null || body.contentType == null + if (body == null || body.getContentType() == null || header.keySet().contains("Content-Type")) { return header; } - header.put("Content-Type", body.contentType.toString()); + header.put("Content-Type", body.getContentType().toString()); return header; } @@ -644,7 +785,6 @@ public StringMap getHeader() throws QiniuException { * @throws QiniuException 组装 header 时的异常,一般为缺失必要参数的异常 */ protected void buildHeader() throws QiniuException { - } /** @@ -710,10 +850,20 @@ protected void setBody(InputStream body, String contentType, long limitSize) { contentType = Client.DefaultMime; } Request.Body.InputStreamBody b = new Request.Body.InputStreamBody(body, contentType, limitSize); - b.streamBodySinkSize = streamBodySinkSize; + b.setSinkSize(streamBodySinkSize); this.body = b; } + /** + * 设置表单请求体 + * 此方式配置的 body 支持重试,不支持 auth + * + * @param fields 表单 fields + **/ + protected void setFormBody(StringMap fields) { + this.body = new Body.FormBody(fields); + } + /** * 设置表单请求体 * 此方式配置的 body 支持重试,不支持 auth @@ -724,11 +874,14 @@ protected void setBody(InputStream body, String contentType, long limitSize) { * @param body 表单 byte[] 类型 body 【必须】 * @param contentType 表单 body 的 Mime type **/ - protected void setFormBody(String name, String fileName, StringMap fields, byte[] body, String contentType) { + protected void setMultipartBody(String name, String fileName, StringMap fields, byte[] body, String contentType) { if (StringUtils.isNullOrEmpty(contentType)) { contentType = Client.DefaultMime; } - this.body = new Request.Body.FormBody(name, fileName, fields, body, contentType); + if (body == null) { + body = new byte[0]; + } + this.body = new Body.MultipartBody(name, fileName, fields, body, contentType); } /** @@ -741,11 +894,11 @@ protected void setFormBody(String name, String fileName, StringMap fields, byte[ * @param body 表单 File 类型 body 【必须】 * @param contentType 表单 body 的 Mime type **/ - protected void setFormBody(String name, String fileName, StringMap fields, File body, String contentType) { + protected void setMultipartBody(String name, String fileName, StringMap fields, File body, String contentType) { if (StringUtils.isNullOrEmpty(contentType)) { contentType = Client.DefaultMime; } - this.body = new Request.Body.FormBody(name, fileName, fields, body, contentType); + this.body = new Body.MultipartBody(name, fileName, fields, body, contentType); } /** @@ -756,10 +909,11 @@ protected void setFormBody(String name, String fileName, StringMap fields, File * @param streamBodySinkSize 每次读取 streamBody 的大小 * @return Request */ + @Deprecated public Request setStreamBodySinkSize(long streamBodySinkSize) { this.streamBodySinkSize = streamBodySinkSize; - if (body != null && body instanceof Request.Body.InputStreamBody) { - ((Body.InputStreamBody) body).streamBodySinkSize = streamBodySinkSize; + if (this.body instanceof Body.InputStreamBody) { + ((Body.InputStreamBody) this.body).setSinkSize(streamBodySinkSize); } return this; } @@ -773,15 +927,10 @@ public boolean hasBody() { return body != null; } - private RequestBody getRequestBody() { + RequestBody getRequestBody() { if (!hasBody()) { return Body.BytesBody.empty().get(); } - - if (body instanceof Body.InputStreamBody) { - ((Body.InputStreamBody) body).streamBodySinkSize = streamBodySinkSize; - } - return body.get(); } @@ -798,7 +947,10 @@ byte[] getBytesBody() { * @throws QiniuException 异常 */ protected void buildBodyInfo() throws QiniuException { - + if (!this.method.hasContent() || this.body != null) { + return; + } + this.body = new Request.Body.BytesBody(new byte[]{}, 0, 0, Client.FormMime); } boolean canRetry() { @@ -840,6 +992,21 @@ protected static class Pair { * Key of this Pair. */ private K key; + /** + * Value of this this Pair. + */ + private V value; + + /** + * Creates a new pair + * + * @param key The key for this pair + * @param value The value to use for this pair + */ + protected Pair(K key, V value) { + this.key = key; + this.value = value; + } /** * Gets the key for this pair. @@ -850,11 +1017,6 @@ K getKey() { return key; } - /** - * Value of this this Pair. - */ - private V value; - /** * Gets the value for this pair. * @@ -864,17 +1026,6 @@ V getValue() { return value; } - /** - * Creates a new pair - * - * @param key The key for this pair - * @param value The value to use for this pair - */ - protected Pair(K key, V value) { - this.key = key; - this.value = value; - } - /** *

String representation of this * Pair.

@@ -937,10 +1088,14 @@ public boolean equals(Object o) { private abstract static class Body { - protected final MediaType contentType; + protected RequestBody body; - protected Body(String contentType) { - this.contentType = MediaType.parse(contentType); + protected MediaType getContentType() { + if (this.body == null) { + return null; + } + + return this.body.contentType(); } protected boolean canReset() { @@ -951,7 +1106,9 @@ protected void reset() throws QiniuException { throw QiniuException.unrecoverable("not support reset"); } - protected abstract RequestBody get(); + protected RequestBody get() { + return body; + } protected byte[] getBytes() { return null; @@ -961,16 +1118,23 @@ private static final class BytesBody extends Body { private final byte[] bytes; private final int offset; private final int length; - - private static BytesBody empty() { - return new BytesBody(new byte[0], 0, 0, Client.DefaultMime); - } + private final String contentType; private BytesBody(byte[] bytes, int offset, int length, String contentType) { - super(contentType); this.bytes = bytes; this.offset = offset; this.length = length; + this.contentType = contentType; + this.body = createByteRequestBody(this); + } + + private static BytesBody empty() { + return new BytesBody(new byte[0], 0, 0, Client.DefaultMime); + } + + private static RequestBody createByteRequestBody(BytesBody bytesBody) { + MediaType ct = MediaType.parse(bytesBody.contentType); + return RequestBody.create(ct, bytesBody.bytes, bytesBody.offset, bytesBody.length); } @Override @@ -980,11 +1144,7 @@ protected boolean canReset() { @Override protected void reset() throws QiniuException { - } - - @Override - protected RequestBody get() { - return RequestBody.create(contentType, bytes, offset, length); + this.body = createByteRequestBody(this); } @Override @@ -1000,49 +1160,58 @@ public byte[] getBytes() { } private static final class InputStreamBody extends Body { - private final InputStream stream; - - private final long limitSize; - - private long streamBodySinkSize = 1024 * 10; private InputStreamBody(InputStream stream, String contentType, long limitSize) { - super(contentType); - this.stream = stream; - this.limitSize = limitSize; + MediaType ct = MediaType.parse(contentType); + RequestStreamBody b = new RequestStreamBody(stream, ct, limitSize); + b.setSinkSize(1024 * 10); + this.body = b; } - @Override - protected RequestBody get() { - RequestStreamBody b = new RequestStreamBody(stream, contentType, limitSize); - b.setSinkSize(streamBodySinkSize); - return b; + private void setSinkSize(long sinkSize) { + if (this.body instanceof RequestStreamBody) { + ((RequestStreamBody) this.body).setSinkSize(sinkSize); + } } } private static final class FormBody extends Body { - private final String name; - private final String fileName; + private final StringMap fields; - private final byte[] bytes; - private final File file; + private byte[] bytes; - private FormBody(String name, String fileName, StringMap fields, byte[] body, String contentType) { - super(contentType); - this.name = name; - this.fileName = fileName; + private FormBody(StringMap fields) { this.fields = fields; - this.bytes = body; - this.file = null; + try { + this.setupBody(); + } catch (QiniuException e) { + e.printStackTrace(); + } } - private FormBody(String name, String fileName, StringMap fields, File body, String contentType) { - super(contentType); - this.name = name; - this.fileName = fileName; - this.fields = fields; - this.bytes = null; - this.file = body; + private static okhttp3.FormBody createFormRequestBody(FormBody formBody) { + final okhttp3.FormBody.Builder builder = new okhttp3.FormBody.Builder(); + if (formBody.fields != null) { + formBody.fields.forEach(new StringMap.Consumer() { + @Override + public void accept(String key, Object value) { + builder.add(key, value.toString()); + } + }); + } + return builder.build(); + } + + private void setupBody() throws QiniuException { + okhttp3.FormBody formBody = createFormRequestBody(this); + Buffer buffer = new Buffer(); + try { + formBody.writeTo(buffer); + } catch (IOException e) { + throw QiniuException.unrecoverable(e); + } + this.bytes = buffer.readByteArray(); + this.body = formBody; } @Override @@ -1052,26 +1221,72 @@ protected boolean canReset() { @Override protected void reset() throws QiniuException { + this.setupBody(); } @Override - protected RequestBody get() { + public byte[] getBytes() { + return bytes; + } + } + + + private static final class MultipartBody extends Body { + + private final String name; + private final String fileName; + private final StringMap fields; + private final File fileBody; + private final String bodyContentType; + private byte[] bytes; + private byte[] bytesBody; + + private MultipartBody(String name, String fileName, StringMap fields, byte[] body, String bodyContentType) { + this.bodyContentType = bodyContentType; + this.name = name; + this.fileName = fileName; + this.fields = fields; + this.bytesBody = body; + this.fileBody = null; + try { + this.setupBody(); + } catch (QiniuException e) { + e.printStackTrace(); + } + } + + private MultipartBody(String name, String fileName, StringMap fields, File body, String bodyContentType) { + this.name = name; + this.fileName = fileName; + this.fields = fields; + this.bodyContentType = bodyContentType; + this.bytesBody = null; + this.fileBody = body; + try { + this.setupBody(); + } catch (QiniuException e) { + e.printStackTrace(); + } + } + + private static okhttp3.MultipartBody createFormRequestBody(MultipartBody formBody) { + MediaType contentType = MediaType.parse(formBody.bodyContentType); RequestBody body = null; - if (bytes != null) { - body = RequestBody.create(contentType, bytes); - } else if (file != null) { - body = RequestBody.create(contentType, file); + if (formBody.bytesBody != null) { + body = RequestBody.create(contentType, formBody.bytesBody); + } else if (formBody.fileBody != null) { + body = RequestBody.create(contentType, formBody.fileBody); } else { body = RequestBody.create(contentType, new byte[0]); } - final MultipartBody.Builder b = new MultipartBody.Builder(); - if (!StringUtils.isNullOrEmpty(name)) { - b.addFormDataPart(name, fileName, body); + final okhttp3.MultipartBody.Builder b = new okhttp3.MultipartBody.Builder(); + if (!StringUtils.isNullOrEmpty(formBody.name)) { + b.addFormDataPart(formBody.name, formBody.fileName, body); } - if (fields != null) { - fields.forEach(new StringMap.Consumer() { + if (formBody.fields != null) { + formBody.fields.forEach(new StringMap.Consumer() { @Override public void accept(String key, Object value) { b.addFormDataPart(key, value.toString()); @@ -1083,31 +1298,62 @@ public void accept(String key, Object value) { return b.build(); } + + private void setupBody() throws QiniuException { + okhttp3.MultipartBody formBody = createFormRequestBody(this); + + // 只有使用 bytesBody 和 fileBody 都没有时才会处理,其他不处理 + // bytes 用作签名,Multipart 不做签名 + // bytes + if (this.bytesBody == null && this.fileBody == null) { + Buffer buffer = new Buffer(); + try { + formBody.writeTo(buffer); + } catch (IOException e) { + throw QiniuException.unrecoverable(e); + } + this.bytes = buffer.readByteArray(); + } + + this.body = formBody; + } + + @Override + protected boolean canReset() { + return true; + } + + @Override + protected void reset() throws QiniuException { + this.setupBody(); + } + + @Override + public byte[] getBytes() { + return bytes; + } } } } - /** * api 响应基类 */ public static class Response { + /** + * 原响应结果 + */ + private final com.qiniu.http.Response response; /** * 响应数据 */ private StringMap dataMap; - /** * 响应数据 */ private Object[] dataArray; - /** - * 原响应结果 - */ - private final com.qiniu.http.Response response; - /** * 构建 Response * @@ -1120,15 +1366,27 @@ protected Response(com.qiniu.http.Response response) throws QiniuException { return; } - String bodyString = response.bodyString(); - try { - if (bodyString.startsWith("[")) { - this.dataArray = Json.decodeArray(bodyString); - } else { - this.dataMap = Json.decode(bodyString); + // 七牛只有 Json 和 流,流外部处理,SDK 不关闭 + // Json 会自动关闭 + if (response.isJson()) { + String bodyString = response.bodyString(); + try { + if (bodyString.startsWith("[")) { + this.dataArray = Json.decodeArray(bodyString); + } else { + this.dataMap = Json.decode(bodyString); + } + } catch (Exception e) { + e.printStackTrace(); } - } catch (Exception e) { - e.printStackTrace(); + return; + } + + // 没有 Body + if (response.getResponse() != null + && response.getResponse().body() != null + && response.getResponse().body().contentLength() == 0) { + response.close(); } } @@ -1234,11 +1492,6 @@ public Object getValueFromDataMap(String... keyPath) { } } - - interface Handler { - Response handle(Request request) throws QiniuException; - } - abstract static class Interceptor { static final int PriorityDefault = 100; diff --git a/src/main/java/com/qiniu/storage/ApiInterceptorAuth.java b/src/main/java/com/qiniu/storage/ApiInterceptorAuth.java index 795f1e721..ff845a6c7 100644 --- a/src/main/java/com/qiniu/storage/ApiInterceptorAuth.java +++ b/src/main/java/com/qiniu/storage/ApiInterceptorAuth.java @@ -26,16 +26,20 @@ Api.Response intercept(Api.Request request, Api.Handler handler) throws QiniuExc return handler.handle(request); } - String url = request.getUrl().toString(); - String method = request.getMethodString(); - Headers headers = Headers.of(request.getHeader()); - byte[] body = request.getBytesBody(); - String authorization = "Qiniu " + auth.signQiniuAuthorization(url, method, body, headers); - request.addHeaderField("Authorization", authorization); + if (request.getAuthType() == Api.Request.AuthTypeQiniu) { + String url = request.getUrl().toString(); + String method = request.getMethodString(); + Headers headers = Headers.of(request.getHeader()); + byte[] body = request.getBytesBody(); + String authorization = "Qiniu " + auth.signQiniuAuthorization(url, method, body, headers); + request.addHeaderField("Authorization", authorization); + } + return handler.handle(request); } static final class Builder { + private Auth auth; Builder setAuth(Auth auth) { @@ -43,6 +47,10 @@ Builder setAuth(Auth auth) { return this; } + Builder setAuthType(int authType) { + return this; + } + Api.Interceptor build() { return new ApiInterceptorAuth(auth); } diff --git a/src/main/java/com/qiniu/storage/ApiInterceptorDebug.java b/src/main/java/com/qiniu/storage/ApiInterceptorDebug.java index 95bd64c61..480cfc920 100644 --- a/src/main/java/com/qiniu/storage/ApiInterceptorDebug.java +++ b/src/main/java/com/qiniu/storage/ApiInterceptorDebug.java @@ -26,15 +26,15 @@ final class ApiInterceptorDebug extends Api.Interceptor { private final int responseLevel; - private static boolean isNonePrintLevel(int level) { - return level != LevelPrintNormal && level != LevelPrintDetail; - } - private ApiInterceptorDebug(int requestLevel, int responseLevel) { this.requestLevel = requestLevel; this.responseLevel = responseLevel; } + private static boolean isNonePrintLevel(int level) { + return level != LevelPrintNormal && level != LevelPrintDetail; + } + @Override int priority() { return Api.Interceptor.PriorityDebug; diff --git a/src/main/java/com/qiniu/storage/ApiInterceptorRetryHosts.java b/src/main/java/com/qiniu/storage/ApiInterceptorRetryHosts.java index 54bd8c3f5..ee0f7753c 100644 --- a/src/main/java/com/qiniu/storage/ApiInterceptorRetryHosts.java +++ b/src/main/java/com/qiniu/storage/ApiInterceptorRetryHosts.java @@ -11,11 +11,6 @@ class ApiInterceptorRetryHosts extends Api.Interceptor { private final Retry.HostFreezeCondition hostFreezeCondition; private final HostProvider hostProvider; - @Override - int priority() { - return Api.Interceptor.PriorityRetryHosts; - } - private ApiInterceptorRetryHosts(int retryMax, Retry.Interval retryInterval, Retry.RetryCondition retryCondition, @@ -30,6 +25,11 @@ private ApiInterceptorRetryHosts(int retryMax, this.hostProvider = hostProvider; } + @Override + int priority() { + return Api.Interceptor.PriorityRetryHosts; + } + @Override Api.Response intercept(Api.Request request, Api.Handler handler) throws QiniuException { if (request == null || hostProvider == null) { diff --git a/src/main/java/com/qiniu/storage/AutoRegion.java b/src/main/java/com/qiniu/storage/AutoRegion.java index 932cac1fc..ab96060ad 100644 --- a/src/main/java/com/qiniu/storage/AutoRegion.java +++ b/src/main/java/com/qiniu/storage/AutoRegion.java @@ -3,7 +3,10 @@ import com.qiniu.common.QiniuException; import com.qiniu.http.Client; import com.qiniu.http.Response; -import com.qiniu.util.*; +import com.qiniu.util.Cache; +import com.qiniu.util.StringUtils; +import com.qiniu.util.UrlSafeBase64; +import com.qiniu.util.UrlUtils; import java.util.ArrayList; import java.util.Arrays; @@ -13,23 +16,20 @@ class AutoRegion extends Region { + /** + * 全局空间信息缓存,此缓存绑定了 token、bucket,全局有效。 + */ + private static final Cache globalRegionCache = new Cache.Builder<>(UCRet.class) + .setVersion("v1") + .builder(); /** * uc接口域名 */ private List ucServers = new ArrayList<>(); - /** * 空间机房,域名信息缓存,此缓存绑定了 token、bucket,且仅 AutoRegion 对象内部有效。 */ private Map regions; - - /** - * 全局空间信息缓存,此缓存绑定了 token、bucket,全局有效。 - */ - private static final Cache globalRegionCache = new Cache.Builder<>(UCRet.class) - .setVersion("v1") - .builder(); - /** * 定义HTTP请求管理相关方法 */ @@ -72,6 +72,20 @@ private AutoRegion() { this.regions = new ConcurrentHashMap<>(); } + static Region regionGroup(UCRet ret) { + if (ret == null || ret.hosts == null || ret.hosts.length == 0) { + return null; + } + + RegionGroup group = new RegionGroup(); + for (ServerRets host : ret.hosts) { + Region region = host.createRegion(); + group.addRegion(region); + } + + return group; + } + /** * 通过 API 接口查询上传域名 */ @@ -100,20 +114,6 @@ private UCRet queryRegionInfoFromServerIfNeeded(RegionIndex index) throws QiniuE return ret; } - static Region regionGroup(UCRet ret) { - if (ret == null || ret.hosts == null || ret.hosts.length == 0) { - return null; - } - - RegionGroup group = new RegionGroup(); - for (ServerRets host : ret.hosts) { - Region region = host.createRegion(); - group.addRegion(region); - } - - return group; - } - /** * 首先从缓存读取Region信息,如果没有则发送请求从接口查询 * diff --git a/src/main/java/com/qiniu/storage/BucketManager.java b/src/main/java/com/qiniu/storage/BucketManager.java index 57ed0bb17..e17245469 100644 --- a/src/main/java/com/qiniu/storage/BucketManager.java +++ b/src/main/java/com/qiniu/storage/BucketManager.java @@ -1168,6 +1168,7 @@ private Response get(String url) throws QiniuException { private Response get(String url, Api.Interceptor[] interceptors) throws QiniuException { Api.Request request = new Api.Request(url); + request.setAuthType(Api.Request.AuthTypeQiniu); return new Api(client, interceptors).requestWithInterceptor(request); } @@ -1178,6 +1179,7 @@ private Response post(String url, byte[] body) throws QiniuException { private Response post(String url, byte[] body, Api.Interceptor[] interceptors) throws QiniuException { Api.Request request = new Api.Request(url); + request.setAuthType(Api.Request.AuthTypeQiniu); request.setMethod(MethodType.POST); if (body == null) { body = new byte[0]; diff --git a/src/main/java/com/qiniu/storage/Configuration.java b/src/main/java/com/qiniu/storage/Configuration.java index 84d7497f2..022f76e16 100644 --- a/src/main/java/com/qiniu/storage/Configuration.java +++ b/src/main/java/com/qiniu/storage/Configuration.java @@ -14,15 +14,14 @@ */ public final class Configuration implements Cloneable { + static final String ucBackUpHost0 = "kodo-config.qiniuapi.com"; + static final String ucBackUpHost1 = "uc.qbox.me"; /** * 特殊默认域名 */ public static String defaultRsHost = "rs.qiniu.com"; public static String defaultApiHost = "api.qiniu.com"; public static String defaultUcHost = "uc.qiniuapi.com"; - static final String ucBackUpHost0 = "kodo-config.qiniuapi.com"; - static final String ucBackUpHost1 = "uc.qbox.me"; - static final String[] defaultUcHosts = new String[]{defaultUcHost, ucBackUpHost0, ucBackUpHost1}; /** diff --git a/src/main/java/com/qiniu/storage/DownloadUrl.java b/src/main/java/com/qiniu/storage/DownloadUrl.java index 00d7ec504..7259a463c 100644 --- a/src/main/java/com/qiniu/storage/DownloadUrl.java +++ b/src/main/java/com/qiniu/storage/DownloadUrl.java @@ -39,21 +39,21 @@ public DownloadUrl(String domain, boolean useHttps, String key) { } /** - * 设置下载 domain + * 获取下载 domain * - * @param domain 下载 domain + * @return 下载 domain */ - protected void setDomain(String domain) { - this.domain = domain; + protected String getDomain() { + return domain; } /** - * 获取下载 domain + * 设置下载 domain * - * @return 下载 domain + * @param domain 下载 domain */ - protected String getDomain() { - return domain; + protected void setDomain(String domain) { + this.domain = domain; } /** @@ -164,7 +164,7 @@ public String buildURL() throws QiniuException { didSetKeyForUrl(request); if (!StringUtils.isNullOrEmpty(fop)) { - request.addQueryPair(fop, null); + request.addQueryPair(fop, (String) null); } for (Api.Request.Pair pair : customQuerys) { diff --git a/src/main/java/com/qiniu/storage/FormUploader.java b/src/main/java/com/qiniu/storage/FormUploader.java index 6aaa07630..2215464bc 100644 --- a/src/main/java/com/qiniu/storage/FormUploader.java +++ b/src/main/java/com/qiniu/storage/FormUploader.java @@ -83,9 +83,9 @@ Response uploadFlows() throws QiniuException { Api.Request request = new Api.Request(urlPrefix); request.setMethod(MethodType.POST); if (data != null) { - request.setFormBody("file", filename, params, data, mime); + request.setMultipartBody("file", filename, params, data, mime); } else { - request.setFormBody("file", filename, params, file, mime); + request.setMultipartBody("file", filename, params, file, mime); } return api.requestWithInterceptor(request); } diff --git a/src/main/java/com/qiniu/storage/HostProvider.java b/src/main/java/com/qiniu/storage/HostProvider.java index 9722a3889..d6ca736e1 100644 --- a/src/main/java/com/qiniu/storage/HostProvider.java +++ b/src/main/java/com/qiniu/storage/HostProvider.java @@ -39,9 +39,9 @@ public static HostProvider arrayProvider(String... hosts) { private static final class ArrayProvider extends HostProvider { - private int nextIndex = 0; private final String[] values; private final Map items = new HashMap<>(); + private int nextIndex = 0; private ArrayProvider(String... values) { super(); diff --git a/src/main/java/com/qiniu/storage/Region.java b/src/main/java/com/qiniu/storage/Region.java index 4d93959cc..8ebacd1d1 100644 --- a/src/main/java/com/qiniu/storage/Region.java +++ b/src/main/java/com/qiniu/storage/Region.java @@ -436,12 +436,20 @@ public Builder region(String region) { } public Builder srcUpHost(String... srcUpHosts) { - this.region.srcUpHosts = Arrays.asList(srcUpHosts); + if (srcUpHosts == null) { + this.region.srcUpHosts = null; + } else { + this.region.srcUpHosts = Arrays.asList(srcUpHosts); + } return this; } public Builder accUpHost(String... accUpHosts) { - this.region.accUpHosts = Arrays.asList(accUpHosts); + if (accUpHosts == null) { + this.region.accUpHosts = null; + } else { + this.region.accUpHosts = Arrays.asList(accUpHosts); + } return this; } @@ -506,6 +514,13 @@ public Region autoRegion(int retryMax, int retryInterval, int hostFreezeDuration * @return 区域信息 */ public Region build() { + if (region.srcUpHosts == null) { + region.srcUpHosts = new ArrayList<>(); + } + if (region.accUpHosts == null) { + region.accUpHosts = new ArrayList<>(); + } + return region; } } diff --git a/src/main/java/com/qiniu/storage/RegionGroup.java b/src/main/java/com/qiniu/storage/RegionGroup.java index ea4f42c5a..3b38eec24 100644 --- a/src/main/java/com/qiniu/storage/RegionGroup.java +++ b/src/main/java/com/qiniu/storage/RegionGroup.java @@ -7,10 +7,9 @@ public class RegionGroup extends Region implements Cloneable { + private final List regionList = new ArrayList<>(); private Region currentRegion = null; private int currentRegionIndex = 0; - private final List regionList = new ArrayList<>(); - public synchronized boolean addRegion(Region region) { if (region == null) { diff --git a/src/main/java/com/qiniu/storage/ResumeUploadPerformer.java b/src/main/java/com/qiniu/storage/ResumeUploadPerformer.java index b30fec945..0d81acd80 100644 --- a/src/main/java/com/qiniu/storage/ResumeUploadPerformer.java +++ b/src/main/java/com/qiniu/storage/ResumeUploadPerformer.java @@ -10,14 +10,13 @@ abstract class ResumeUploadPerformer { final Client client; - private final Recorder recorder; - private final Configuration config; final ConfigHelper configHelper; - final String key; final UploadToken token; final ResumeUploadSource uploadSource; final UploadOptions options; + private final Recorder recorder; + private final Configuration config; private Api.Config uploadApiConfig; ResumeUploadPerformer(Client client, String key, UploadToken token, ResumeUploadSource source, diff --git a/src/main/java/com/qiniu/storage/ResumeUploadSourceStream.java b/src/main/java/com/qiniu/storage/ResumeUploadSourceStream.java index f173bbac1..5d20bc4d8 100644 --- a/src/main/java/com/qiniu/storage/ResumeUploadSourceStream.java +++ b/src/main/java/com/qiniu/storage/ResumeUploadSourceStream.java @@ -6,10 +6,10 @@ public class ResumeUploadSourceStream extends ResumeUploadSource { - private long readOffset = 0; - private boolean isAllDataRead; private final InputStream inputStream; private final String fileName; + private long readOffset = 0; + private boolean isAllDataRead; ResumeUploadSourceStream(InputStream inputStream, Configuration config, String recordKey, String fileName) { super(config, recordKey); diff --git a/src/main/java/com/qiniu/storage/ResumeUploader.java b/src/main/java/com/qiniu/storage/ResumeUploader.java index ef172acf6..e289c2edb 100644 --- a/src/main/java/com/qiniu/storage/ResumeUploader.java +++ b/src/main/java/com/qiniu/storage/ResumeUploader.java @@ -129,6 +129,13 @@ private ResumeUploader(Client client, String key, String upToken, ResumeUploadSo this.options = options == null ? UploadOptions.defaultOptions() : options; } + private static String getRecorderKey(String key, File file, Recorder recorder) { + if (recorder == null) { + return null; + } + return recorder.recorderKeyGenerate(key, file); + } + /** * 上传文件 */ @@ -239,13 +246,6 @@ private void checkParam() throws QiniuException { } } - private static String getRecorderKey(String key, File file, Recorder recorder) { - if (recorder == null) { - return null; - } - return recorder.recorderKeyGenerate(key, file); - } - // recorder void recoverUploadProgressFromLocal() { if (recorder == null || source == null || StringUtils.isNullOrEmpty(source.recordKey)) { diff --git a/src/main/java/com/qiniu/storage/Retry.java b/src/main/java/com/qiniu/storage/Retry.java index 5c5b9f3c9..733a8330c 100644 --- a/src/main/java/com/qiniu/storage/Retry.java +++ b/src/main/java/com/qiniu/storage/Retry.java @@ -60,14 +60,6 @@ static Boolean requestShouldSwitchHost(Response response, QiniuException excepti return true; } - public interface Interval { - - /** - * 重试时间间隔,单位:毫秒 - **/ - int interval(); - } - public static Interval defaultInterval() { return staticInterval(200); } @@ -81,14 +73,6 @@ public int interval() { }; } - public interface RetryCondition { - - /** - * 是否需要重试 - **/ - boolean shouldRetry(Api.Request request, Api.Response response, QiniuException exception); - } - public static RetryCondition defaultCondition() { return new RetryCondition() { @Override @@ -98,10 +82,6 @@ public boolean shouldRetry(Api.Request request, Api.Response response, QiniuExce }; } - public interface HostFreezeCondition { - boolean shouldFreezeHost(Api.Request request, Api.Response response, QiniuException exception); - } - public static HostFreezeCondition defaultHostFreezeCondition() { return new HostFreezeCondition() { @Override @@ -110,4 +90,24 @@ public boolean shouldFreezeHost(Api.Request request, Api.Response response, Qini } }; } + + public interface Interval { + + /** + * 重试时间间隔,单位:毫秒 + **/ + int interval(); + } + + public interface RetryCondition { + + /** + * 是否需要重试 + **/ + boolean shouldRetry(Api.Request request, Api.Response response, QiniuException exception); + } + + public interface HostFreezeCondition { + boolean shouldFreezeHost(Api.Request request, Api.Response response, QiniuException exception); + } } diff --git a/src/main/java/com/qiniu/storage/UpHostHelper.java b/src/main/java/com/qiniu/storage/UpHostHelper.java index 5725b6e6c..908df461d 100644 --- a/src/main/java/com/qiniu/storage/UpHostHelper.java +++ b/src/main/java/com/qiniu/storage/UpHostHelper.java @@ -32,11 +32,15 @@ String upHost(Region region, String upToken, String lastUsedHost, boolean change try { accHosts = region.getAccUpHost(regionReqInfo); srcHosts = region.getSrcUpHost(regionReqInfo); - } catch (QiniuException e) { // it will success soon. + } catch (Exception e) { // it will success soon. if (mustReturnUpHost && conf.useDefaultUpHostIfNone) { return failedUpHost("failed_get_region"); } else { - throw e; + if (e instanceof QiniuException) { + throw e; + } else { + throw QiniuException.unrecoverable(e); + } } } @@ -50,7 +54,7 @@ String upHost(Region region, String upToken, String lastUsedHost, boolean change return regionHost.upHost(accHosts, srcHosts, lastUsedHost, changeHost); } - private String failedUpHost(String regionKey) { + private String failedUpHost(String regionKey) throws QiniuException { List srcHosts; List accHosts; @@ -75,42 +79,44 @@ private String failedUpHost(String regionKey) { srcHosts = regionHost.lastSrcHosts; accHosts = regionHost.lastAccHosts; } - String host = regionHost.upHost(accHosts, srcHosts, null, false); - return host; + return regionHost.upHost(accHosts, srcHosts, null, false); } String getRegionKey(List srcHosts, List accHosts) { String host = null; String lhost = null; - for (String a : srcHosts) { - if (host == null) { - host = a; - lhost = a; - } - if (a.length() < host.length()) { - host = a; - } - if (a.length() > lhost.length()) { - lhost = a; + + if (srcHosts != null) { + for (String a : srcHosts) { + if (host == null) { + host = a; + lhost = a; + } + if (a.length() < host.length()) { + host = a; + } + if (a.length() > lhost.length()) { + lhost = a; + } } } - if (host != null) { - return host + ";+=-_" + lhost; - } - for (String a : accHosts) { - if (host == null) { - host = a; - lhost = a; - } - if (a.length() < host.length()) { - host = a; - } - if (a.length() > lhost.length()) { - lhost = a; + if (host == null && accHosts != null) { + for (String a : accHosts) { + if (host == null) { + host = a; + lhost = a; + } + if (a.length() < host.length()) { + host = a; + } + if (a.length() > lhost.length()) { + lhost = a; + } } } + return host + ";+=-_" + lhost; } @@ -126,6 +132,14 @@ class RegionUpHost { volatile String lastHost; private void initHostMark(List f, List s) { + if (f == null) { + f = new ArrayList<>(); + } + + if (s == null) { + s = new ArrayList<>(); + } + ArrayList _lastHosts = new ArrayList<>(); int _mainHostCount = 0; @@ -181,7 +195,12 @@ private void randomAdd(ArrayList _lastHosts, ArrayList iidx, Ra } } - String upHost(List accHosts, List srcHosts, String lastUsedHost, boolean changeHost) { + String upHost(List accHosts, List srcHosts, String lastUsedHost, boolean changeHost) throws QiniuException { + if ((accHosts == null || accHosts.isEmpty()) + && (srcHosts == null || srcHosts.isEmpty())) { + throw QiniuException.unrecoverable("no up host found"); + } + if (lastAccHosts != accHosts || lastSrcHosts != srcHosts) { lastAccHosts = accHosts; lastSrcHosts = srcHosts; diff --git a/src/main/java/com/qiniu/storage/UploadOptions.java b/src/main/java/com/qiniu/storage/UploadOptions.java index 5d6fe6344..d3befc9f0 100644 --- a/src/main/java/com/qiniu/storage/UploadOptions.java +++ b/src/main/java/com/qiniu/storage/UploadOptions.java @@ -24,10 +24,6 @@ public final class UploadOptions { */ public final boolean checkCrc; - public static UploadOptions defaultOptions() { - return new UploadOptions.Builder().build(); - } - private UploadOptions(StringMap params, StringMap metaDataParam, String mimeType, @@ -38,6 +34,9 @@ private UploadOptions(StringMap params, this.checkCrc = checkCrc; } + public static UploadOptions defaultOptions() { + return new UploadOptions.Builder().build(); + } public static class Builder { diff --git a/src/main/java/com/qiniu/storage/model/BucketReferAntiLeech.java b/src/main/java/com/qiniu/storage/model/BucketReferAntiLeech.java index 3216f7d90..d39307d88 100644 --- a/src/main/java/com/qiniu/storage/model/BucketReferAntiLeech.java +++ b/src/main/java/com/qiniu/storage/model/BucketReferAntiLeech.java @@ -80,7 +80,7 @@ public BucketReferAntiLeech setPattern(String pattern) throws Exception { * 追加pattern
* pattern * - * @param pattern 防盗链匹配规则 + * @param pattern 防盗链匹配规则 * @return 防盗链信息 * @throws Exception 异常 */ diff --git a/src/main/java/com/qiniu/storage/model/UploadPolicy.java b/src/main/java/com/qiniu/storage/model/UploadPolicy.java index 99bb3e356..43206a680 100644 --- a/src/main/java/com/qiniu/storage/model/UploadPolicy.java +++ b/src/main/java/com/qiniu/storage/model/UploadPolicy.java @@ -17,18 +17,15 @@ public final class UploadPolicy { * [bucket]:[keyPrefix],表示只允许用户上传指定以 keyPrefix 为前缀的文件,当且仅当 isPrefixalScope 字段为 1 时生效,isPrefixalScope 为 1 时无法覆盖上传。 */ public final String scope; - - /** - * 若为 1,表示允许用户上传以 scope 的 keyPrefix 为前缀的文件。 - */ - public int isPrefixalScope; - /** * 上传凭证有效截止时间。Unix时间戳,单位为秒。该截止时间为上传完成后,在七牛空间生成文件的校验时间,而非上传的开始时间, * 一般建议设置为上传开始时间 + 3600s,用户可根据具体的业务场景对凭证截止时间进行调整。 */ public final long deadline; - + /** + * 若为 1,表示允许用户上传以 scope 的 keyPrefix 为前缀的文件。 + */ + public int isPrefixalScope; /** * 若非0, 即使Scope为 Bucket:Key 的形式也是 insert only */ diff --git a/src/main/java/com/qiniu/util/Auth.java b/src/main/java/com/qiniu/util/Auth.java index a7aca466a..597a1d235 100755 --- a/src/main/java/com/qiniu/util/Auth.java +++ b/src/main/java/com/qiniu/util/Auth.java @@ -10,7 +10,10 @@ import java.net.URI; import java.security.GeneralSecurityException; import java.security.SecureRandom; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; public final class Auth { public static final String DISABLE_QINIU_TIMESTAMP_SIGNATURE_ENV_KEY = DefaultHeader.DISABLE_TIMESTAMP_SIGNATURE_ENV_KEY; @@ -52,6 +55,7 @@ public final class Auth { "persistentOps", "persistentNotifyUrl", "persistentPipeline", + "persistentWorkflowTemplateID", "deleteAfterDays", "fileType", @@ -557,6 +561,26 @@ public String generateLinkingDeviceStatusTokenWithExpires(String appid, String d return generateLinkingDeviceTokenWithExpires(appid, deviceName, expires, new String[]{DTOKEN_ACTION_STATUS}); } + public static class Request { + private final String url; + private final String method; + private final Headers header; + private final byte[] body; + + /** + * @param url 回调地址 + * @param method 回调请求方式 + * @param header 回调头,注意 Content-Type Key 字段需为:{@link Auth#HTTP_HEADER_KEY_CONTENT_TYPE},大小写敏感 + * @param body 回调请求体。原始请求体,不要解析后再封装成新的请求体--可能导致签名不一致。 + **/ + public Request(String url, String method, Headers header, byte[] body) { + this.url = url; + this.method = method; + this.header = header; + this.body = body; + } + } + class LinkingDtokenStatement { @SerializedName("action") private String action; @@ -593,24 +617,4 @@ public int compareTo(Header o) { } } } - - public static class Request { - private final String url; - private final String method; - private final Headers header; - private final byte[] body; - - /** - * @param url 回调地址 - * @param method 回调请求方式 - * @param header 回调头,注意 Content-Type Key 字段需为:{@link Auth#HTTP_HEADER_KEY_CONTENT_TYPE},大小写敏感 - * @param body 回调请求体。原始请求体,不要解析后再封装成新的请求体--可能导致签名不一致。 - **/ - public Request(String url, String method, Headers header, byte[] body) { - this.url = url; - this.method = method; - this.header = header; - this.body = body; - } - } } diff --git a/src/main/java/com/qiniu/util/Cache.java b/src/main/java/com/qiniu/util/Cache.java index bd76e5adc..66ce8c751 100644 --- a/src/main/java/com/qiniu/util/Cache.java +++ b/src/main/java/com/qiniu/util/Cache.java @@ -19,12 +19,10 @@ public class Cache { // 存储对象的类型 private final Class objectClass; - - // 内部 - private boolean isFlushing = false; - private final ConcurrentHashMap memCache = new ConcurrentHashMap<>(); private final FileRecorder diskCache; + // 内部 + private boolean isFlushing = false; private Cache(Class objectClass, String cacheDir, String version) { this.objectClass = objectClass; @@ -130,15 +128,13 @@ public void clearMemoryCache() { public static class Builder { + // 存储对象的类型 + private final Class objectClass; // 缓存被持久化为一个文件,此文件的文件名为 version,version 默认为:v1 private String version = "v1"; - // 存储路径 private String cacheDir = Constants.CACHE_DIR; - // 存储对象的类型 - private final Class objectClass; - public Builder(Class objectClass) { this.objectClass = objectClass; } diff --git a/src/main/java/com/qiniu/util/UrlUtils.java b/src/main/java/com/qiniu/util/UrlUtils.java index f39ac88f0..d644c97f1 100644 --- a/src/main/java/com/qiniu/util/UrlUtils.java +++ b/src/main/java/com/qiniu/util/UrlUtils.java @@ -216,7 +216,7 @@ public static String setHostScheme(String host, boolean useHttps) { return null; } - if (host.startsWith("http://") || host.startsWith("https://") ) { + if (host.startsWith("http://") || host.startsWith("https://")) { return host; } diff --git a/src/test/java/com/qiniu/audit/apis/ApiQueryLogTest.java b/src/test/java/com/qiniu/audit/apis/ApiQueryLogTest.java new file mode 100644 index 000000000..e9157dfed --- /dev/null +++ b/src/test/java/com/qiniu/audit/apis/ApiQueryLogTest.java @@ -0,0 +1,83 @@ +package com.qiniu.audit.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.storage.Api; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import test.com.qiniu.TestConfig; + +public class ApiQueryLogTest { + + static final String baseUrl = "api.qiniu.com"; + static final Api.Config config = new Api.Config.Builder() + .setAuth(TestConfig.testAuth) + .setRequestDebugLevel(Api.Config.DebugLevelDetail) + .setResponseDebugLevel(Api.Config.DebugLevelDetail) + .build(); + + @Test + @Tag("IntegrationTest") + public void testQuery() { + + try { + + String sTime = "2024-07-03T22:44:26Z"; + String eTime = "2024-09-10T22:44:26Z"; + String eventNames = "SSOLogin"; + String serviceName = "Account"; + String principalId = "1002013202061"; + String accessKeyId = ""; + ApiQueryLog.Request request = new ApiQueryLog.Request(baseUrl, sTime, eTime); + request.setLimit(1); + request.setEventNames(eventNames); + request.setServiceName(serviceName); + request.setPrincipalId(principalId); + request.setAccessKeyId(accessKeyId); + ApiQueryLog api = new ApiQueryLog(null, config); + + ApiQueryLog.Response response = api.request(request); + Assertions.assertNotNull(response, "1. 获取 log 失败:" + response); + Assertions.assertTrue(response.isOK(), "1.1 获取 log 失败:" + response); + Assertions.assertNotNull(response.getData(), "1.2 获取 log 失败:" + response); + Assertions.assertEquals(1, response.getData().getAuditLogInfos().length, "1.3 获取 log 失败:" + response); + Assertions.assertNotNull(response.getData().getNextMark(), "1.4 获取 log 失败:" + response); + + ApiQueryLog.Response.LogInfo logInfo = response.getData().getAuditLogInfos()[0]; + Assertions.assertNotNull(logInfo.getEventId(), "1.5 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getEventType(), "1.6 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getEventTime(), "1.7 获取 log 失败:" + response); + Assertions.assertEquals(logInfo.getEventName(), eventNames, "1.8 获取 log 失败:" + response); + Assertions.assertEquals(logInfo.getUserIdentity().getAccessKeyId(), accessKeyId, "1.9 获取 log 失败:" + response); + Assertions.assertEquals(logInfo.getUserIdentity().getPrincipalId(), principalId, "1.10 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getUserIdentity().getPrincipalType(), "1.11 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getUserIdentity().getAccountId(), "1.12 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getEventRw(), "1.13 获取 log 失败:" + response); + Assertions.assertEquals(logInfo.getServiceName(), serviceName, "1.14 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getSourceIp(), "1.15 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getUserAgent(), "1.16 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getResourceNames(), "1.17 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getRequestId(), "1.18 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getRequestUrl(), "1.19 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getRequestParams(), "1.20 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getResponseData(), "1.21 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getResponseCode(), "1.22 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getResponseMessage(), "1.23 获取 log 失败:" + response); + Assertions.assertNotNull(logInfo.getAdditionalEventData(), "1.24 获取 log 失败:" + response); + + + request.setNextMark(response.getData().getNextMark()); + + response = api.request(request); + Assertions.assertNotNull(response, "1.25 获取 log 失败:" + response); + Assertions.assertTrue(response.isOK(), "1.26 获取 log 失败:" + response); + Assertions.assertNotNull(response.getData(), "1.27 获取 log 失败:" + response); + Assertions.assertEquals(1, response.getData().getAuditLogInfos().length, "1.28 获取 log 失败:" + response); + Assertions.assertNotNull(response.getData().getNextMark(), "1.29 获取 log 失败:" + response); + + + } catch (QiniuException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/test/java/com/qiniu/common/AutoZoneTest.java b/src/test/java/com/qiniu/common/AutoZoneTest.java index c700a38b2..b3a6764cb 100644 --- a/src/test/java/com/qiniu/common/AutoZoneTest.java +++ b/src/test/java/com/qiniu/common/AutoZoneTest.java @@ -1,14 +1,10 @@ package com.qiniu.common; -import test.com.qiniu.TestConfig; - import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.fail; -import java.util.HashMap; -import java.util.Map; +import test.com.qiniu.TestConfig; + +import static org.junit.jupiter.api.Assertions.*; /** * Created by Simon on 6/22/16. @@ -18,24 +14,17 @@ public class AutoZoneTest { @Test @Tag("IntegrationTest") public void testHttp() { - Map cases = new HashMap(); - cases.put(TestConfig.testBucket_z0, - new String[] { "http://up.qiniu.com", "http://upload.qiniu.com", "https://up.qbox.me" }); - cases.put(TestConfig.testBucket_na0, - new String[] { "http://up-na0.qiniu.com", "http://upload-na0.qiniu.com", "https://up-na0.qbox.me" }); - for (Map.Entry entry : cases.entrySet()) { - String bucket = entry.getKey(); - String[] domains = entry.getValue(); - try { - AutoZone zone = AutoZone.instance; - AutoZone.ZoneInfo zoneInfo = zone.queryZoneInfo(TestConfig.testAccessKey, bucket); - assertEquals(zoneInfo.upHttp, domains[0]); - assertEquals(zoneInfo.upBackupHttp, domains[1]); - assertEquals(zoneInfo.upHttps, domains[2]); - } catch (QiniuException e) { - fail(e.response.toString()); - } + String bucket = TestConfig.testBucket_z0; + try { + AutoZone zone = AutoZone.instance; + AutoZone.ZoneInfo zoneInfo = zone.queryZoneInfo(TestConfig.testAccessKey, bucket); + assertTrue(zoneInfo.upHttp.contains("http://")); + assertTrue(zoneInfo.upBackupHttp.contains("http://")); + assertTrue(zoneInfo.upHttps.contains("https://")); + assertTrue(zoneInfo.upBackupHttps.contains("https://")); + } catch (QiniuException e) { + fail(e.response.toString()); } } diff --git a/src/test/java/com/qiniu/iam/apis/ApiTestConfig.java b/src/test/java/com/qiniu/iam/apis/ApiTestConfig.java new file mode 100644 index 000000000..03f294e26 --- /dev/null +++ b/src/test/java/com/qiniu/iam/apis/ApiTestConfig.java @@ -0,0 +1,21 @@ +package com.qiniu.iam.apis; + +import com.qiniu.storage.Api; +import test.com.qiniu.TestConfig; + +public class ApiTestConfig { + static final String policyAlias = "JavaTestPolicy"; + static final String groupAlias = "JavaTestGroup"; + static final String userAlias = "JavaTestUser"; + static final String userPWD = "JavaTestUserPWD"; + static final String baseUrl = "api.qiniu.com"; + static final Api.Config config = new Api.Config.Builder() + .setAuth(TestConfig.testAuth) + .setRequestDebugLevel(Api.Config.DebugLevelDetail) + .setResponseDebugLevel(Api.Config.DebugLevelDetail) + .build(); + + private ApiTestConfig() { + } + +} diff --git a/src/test/java/com/qiniu/iam/apis/GroupsApiTest.java b/src/test/java/com/qiniu/iam/apis/GroupsApiTest.java new file mode 100644 index 000000000..7ad28cc62 --- /dev/null +++ b/src/test/java/com/qiniu/iam/apis/GroupsApiTest.java @@ -0,0 +1,250 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.storage.Api; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class GroupsApiTest { + + String groupAlias = ApiTestConfig.groupAlias; + String userAlias = ApiTestConfig.userAlias; + String userPWD = ApiTestConfig.userPWD; + String baseUrl = ApiTestConfig.baseUrl; + Api.Config config = ApiTestConfig.config; + + + @Test + @Tag("IntegrationTest") + void testGroups() { + // 先删除,流程开始先清理历史数据 + try { + ApiDeleteUser.Request deleteUserRequest = new ApiDeleteUser.Request(baseUrl, userAlias); + ApiDeleteUser deleteUserApi = new ApiDeleteUser(null, config); + deleteUserApi.request(deleteUserRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + ApiDeleteGroup.Request deleteGroupRequest = new ApiDeleteGroup.Request(baseUrl, groupAlias); + ApiDeleteGroup deleteGroupApi = new ApiDeleteGroup(null, config); + deleteGroupApi.request(deleteGroupRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + ApiDeleteGroup.Request deleteGroupRequest = new ApiDeleteGroup.Request(baseUrl, groupAlias + "New"); + ApiDeleteGroup deleteGroupApi = new ApiDeleteGroup(null, config); + deleteGroupApi.request(deleteGroupRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + String groupDescription = "JavaTestGroupDescription"; + try { + + // 1. 创建分组 + ApiCreateGroup.Request.CreateGroupParam createGroupParam = new ApiCreateGroup.Request.CreateGroupParam(); + createGroupParam.setAlias(groupAlias); + createGroupParam.setDescription(groupDescription); + ApiCreateGroup.Request createGroupRequest = new ApiCreateGroup.Request(baseUrl, createGroupParam); + ApiCreateGroup createGroupApi = new ApiCreateGroup(null, config); + ApiCreateGroup.Response createGroupResponse = createGroupApi.request(createGroupRequest); + Assertions.assertNotNull(createGroupResponse, "1. 创建分组失败:" + createGroupResponse); + Assertions.assertTrue(createGroupResponse.isOK(), "1.1 创建分组失败:" + createGroupResponse); + ApiCreateGroup.Response.CreatedGroupData createGroupResponseData = createGroupResponse.getData().getData(); + Assertions.assertNotNull(createGroupResponseData.getId(), "1.2 创建分组失败:" + createGroupResponse); + Assertions.assertNotNull(createGroupResponseData.getRootUid(), "1.3 创建分组失败:" + createGroupResponse); + Assertions.assertNotNull(createGroupResponseData.getAlias(), "1.4 创建分组失败:" + createGroupResponse); + Assertions.assertEquals(createGroupResponseData.getDescription(), groupDescription, "1.5 创建分组失败:" + createGroupResponse); + Assertions.assertEquals(createGroupResponseData.getEnabled(), true, "1.6 创建分组失败:" + createGroupResponse); + Assertions.assertNotNull(createGroupResponseData.getCreatedAt(), "1.7 创建分组失败:" + createGroupResponse); + Assertions.assertNotNull(createGroupResponseData.getUpdatedAt(), "1.8 创建分组失败:" + createGroupResponse); + + // 2. 获取分组详情 + ApiGetGroup.Request getRequest = new ApiGetGroup.Request(baseUrl, groupAlias); + ApiGetGroup getApi = new ApiGetGroup(null, config); + ApiGetGroup.Response getResponse = getApi.request(getRequest); + Assertions.assertNotNull(getResponse, "2. 获取分组详情失败:" + getResponse); + Assertions.assertTrue(getResponse.isOK(), "2.1 获取分组详情失败:" + getResponse); + ApiGetGroup.Response.GetGroupData getResponseData = getResponse.getData().getData(); + Assertions.assertNotNull(getResponseData, "2.2 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getId(), createGroupResponseData.getId(), "2.3 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getRootUid(), createGroupResponseData.getRootUid(), "2.4 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getAlias(), createGroupResponseData.getAlias(), "2.5 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getDescription(), createGroupResponseData.getDescription(), "2.6 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getEnabled(), createGroupResponseData.getEnabled(), "2.7 获取分组详情失败:" + getResponse); + Assertions.assertNotNull(getResponseData.getCreatedAt(), "2.8 获取分组详情失败:" + getResponse); + Assertions.assertNotNull(getResponseData.getUpdatedAt(), "2.9 获取分组详情失败:" + getResponse); + + + // 3. 列举所有分组 + ApiGetGroups.Request getGroupsRequest = new ApiGetGroups.Request(baseUrl); + ApiGetGroups getGroupsApi = new ApiGetGroups(null, config); + ApiGetGroups.Response getGroupsResponse = getGroupsApi.request(getGroupsRequest); + Assertions.assertNotNull(getGroupsResponse, "3. 列举所有分组失败:" + getResponse); + Assertions.assertTrue(getGroupsResponse.isOK(), "3.1 列举所有分组详情失败:" + getResponse); + ApiGetGroups.Response.GetGroupsData getGroupsResponseData = getGroupsResponse.getData().getData(); + Assertions.assertNotNull(getGroupsResponseData, "3.2 列举所有分组失败:" + getResponse); + Assertions.assertTrue(getGroupsResponseData.getCount() > 0, "3.3 列举所有分组失败:" + getResponse); + Assertions.assertNotNull(getGroupsResponseData.getList(), "3.4 列举所有分组失败:" + getResponse); + ApiGetGroups.Response.GetGroup group = null; + for (ApiGetGroups.Response.GetGroup g : getGroupsResponseData.getList()) { + if (g.getId().equals(getResponseData.getId())) { + group = g; + } + } + Assertions.assertNotNull(group, "3.5 列举所有分组失败:" + getResponse); + Assertions.assertEquals(group.getId(), getResponseData.getId(), "3.6 列举所有分组失败:" + getResponse); + Assertions.assertEquals(group.getRootUid(), getResponseData.getRootUid(), "3.7 列举所有分组失败:" + getResponse); + Assertions.assertEquals(group.getAlias(), getResponseData.getAlias(), "3.8 列举所有分组失败:" + getResponse); + Assertions.assertEquals(group.getDescription(), getResponseData.getDescription(), "3.9 列举所有分组失败:" + getResponse); + Assertions.assertEquals(group.getEnabled(), getResponseData.getEnabled(), "3.10 列举所有分组失败:" + getResponse); + Assertions.assertNotNull(group.getCreatedAt(), "3.11 列举所有分组失败:" + getResponse); + Assertions.assertNotNull(group.getUpdatedAt(), "3.12 列举所有分组失败:" + getResponse); + + + // 4. 更新用户分组详情 + String newGroupAlias = groupAlias + "New"; + groupDescription = groupDescription + "New"; + ApiModifyGroup.Request.ModifyGroupParam modifyGroupParam = new ApiModifyGroup.Request.ModifyGroupParam(); + modifyGroupParam.setNewAlias(newGroupAlias); + modifyGroupParam.setDescription(groupDescription); + ApiModifyGroup.Request modifyGroupRequest = new ApiModifyGroup.Request(baseUrl, groupAlias, modifyGroupParam); + ApiModifyGroup modifyGroupApi = new ApiModifyGroup(null, config); + ApiModifyGroup.Response modifyGroupResponse = modifyGroupApi.request(modifyGroupRequest); + Assertions.assertNotNull(modifyGroupResponse, "4. 修改分组失败:" + modifyGroupResponse); + Assertions.assertTrue(modifyGroupResponse.isOK(), "4.1 修改分组失败:" + modifyGroupResponse); + ApiModifyGroup.Response.ModifyGroupData modifyGroupResponseData = modifyGroupResponse.getData().getData(); + Assertions.assertNotNull(modifyGroupResponseData.getId(), "4.2 修改分组失败:" + modifyGroupResponse); + Assertions.assertNotNull(modifyGroupResponseData.getRootUid(), "4.3 修改分组失败:" + modifyGroupResponse); + Assertions.assertNotNull(modifyGroupResponseData.getAlias(), "4.4 修改分组失败:" + modifyGroupResponse); + Assertions.assertEquals(modifyGroupResponseData.getDescription(), groupDescription, "4.5 修改分组失败:" + modifyGroupResponse); + Assertions.assertEquals(modifyGroupResponseData.getEnabled(), true, "4.6 修改分组失败:" + modifyGroupResponse); + Assertions.assertNotNull(modifyGroupResponseData.getCreatedAt(), "4.7 修改分组失败:" + modifyGroupResponse); + Assertions.assertNotNull(modifyGroupResponseData.getUpdatedAt(), "4.8 修改分组失败:" + modifyGroupResponse); + + groupAlias = newGroupAlias; + + // 5. 验证用户分组详情更新 + getRequest = new ApiGetGroup.Request(baseUrl, groupAlias); + getApi = new ApiGetGroup(null, config); + getResponse = getApi.request(getRequest); + Assertions.assertNotNull(getResponse, "5. 获取分组详情失败:" + getResponse); + Assertions.assertTrue(getResponse.isOK(), "5.1 获取分组详情失败:" + getResponse); + getResponseData = getResponse.getData().getData(); + Assertions.assertNotNull(getResponseData, "5.2 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getId(), createGroupResponseData.getId(), "5.3 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getRootUid(), createGroupResponseData.getRootUid(), "5.4 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getAlias(), groupAlias, "5.5 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getDescription(), groupDescription, "5.6 获取分组详情失败:" + getResponse); + Assertions.assertEquals(getResponseData.getEnabled(), createGroupResponseData.getEnabled(), "5.7 获取分组详情失败:" + getResponse); + Assertions.assertNotNull(getResponseData.getCreatedAt(), "5.8 获取分组详情失败:" + getResponse); + Assertions.assertNotNull(getResponseData.getUpdatedAt(), "5.9 获取分组详情失败:" + getResponse); + + // 用户相关 + // 6. 创建群组的用户 + ApiCreateUser.Request.CreateIamUserParam createUserParam = new ApiCreateUser.Request.CreateIamUserParam(); + createUserParam.setAlias(userAlias); + createUserParam.setPassword(userPWD); + ApiCreateUser.Request createUserRequest = new ApiCreateUser.Request(baseUrl, createUserParam); + ApiCreateUser createApi = new ApiCreateUser(null, config); + ApiCreateUser.Response createUserResponse = createApi.request(createUserRequest); + assertNotNull(createUserResponse, "6. 创建 User 失败:" + createUserResponse); + assertTrue(createUserResponse.isOK(), "6.1 创建 User 失败:" + createUserResponse); + ApiCreateUser.Response.CreatedIamUserData createUser = createUserResponse.getData().getData(); + + // 6.1 群组添加用户 + ApiModifyGroupUsers.Request.ModifiedGroupIamUsersParam modifyGroupUserParam = new ApiModifyGroupUsers.Request.ModifiedGroupIamUsersParam(); + modifyGroupUserParam.setUserAliases(new String[]{userAlias}); + ApiModifyGroupUsers.Request modifyGroupUserRequest = new ApiModifyGroupUsers.Request(baseUrl, groupAlias, modifyGroupUserParam); + ApiModifyGroupUsers modifyGroupUserApi = new ApiModifyGroupUsers(null, config); + ApiModifyGroupUsers.Response modifyGroupUserResponse = modifyGroupUserApi.request(modifyGroupUserRequest); + assertNotNull(modifyGroupUserResponse, "6.1 创建 User 失败:" + modifyGroupUserResponse); + assertTrue(modifyGroupUserResponse.isOK(), "6.1.1 创建 User 失败:" + modifyGroupUserResponse); + + // 7. 列举群组的用户,验证创建是否成功 + ApiGetGroupUsers.Request getGroupUsersRequest = new ApiGetGroupUsers.Request(baseUrl, groupAlias); + ApiGetGroupUsers getGroupUsersApi = new ApiGetGroupUsers(null, config); + ApiGetGroupUsers.Response getGroupUsersResponse = getGroupUsersApi.request(getGroupUsersRequest); + assertNotNull(getGroupUsersResponse, "7. 列举群组的用户失败:" + getGroupUsersResponse); + assertTrue(getGroupUsersResponse.isOK(), "7.1 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(1, (int) getGroupUsersResponse.getData().getData().getCount(), "7.2 列举群组的用户失败:" + getGroupUsersResponse); + ApiGetGroupUsers.Response.GroupIamUser groupUser = getGroupUsersResponse.getData().getData().getList()[0]; + assertEquals(groupUser.getId(), createUser.getId(), "7.3 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getRootUid(), createUser.getRootUid(), "7.4 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getIuid(), createUser.getIuid(), "7.5 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getAlias(), createUser.getAlias(), "7.6 列举群组的用户失败:" + getGroupUsersResponse); + assertNotNull(groupUser.getCreatedAt(), "7.7 列举群组的用户失败:" + getGroupUsersResponse); + assertNotNull(groupUser.getUpdatedAt(), "7.8 列举群组的用户失败:" + getGroupUsersResponse); + assertNotNull(groupUser.getLastLoginTime(), "7.9 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getEnabled(), createUser.getEnabled(), "7.10 列举群组的用户失败:" + getGroupUsersResponse); + + // 8. 删除群组的用户 + ApiDeleteGroupUsers.Request.DeletedGroupIamUsersParam deleteGroupUserParam = new ApiDeleteGroupUsers.Request.DeletedGroupIamUsersParam(); + deleteGroupUserParam.setUserAliases(new String[]{userAlias}); + ApiDeleteGroupUsers.Request deleteGroupUserRequest = new ApiDeleteGroupUsers.Request(baseUrl, groupAlias, deleteGroupUserParam); + ApiDeleteGroupUsers deleteGroupUserApi = new ApiDeleteGroupUsers(null, config); + ApiDeleteGroupUsers.Response deleteGroupUserResponse = deleteGroupUserApi.request(deleteGroupUserRequest); + assertNotNull(deleteGroupUserResponse, "8. 删除群组的用户失败:" + deleteGroupUserResponse); + assertTrue(deleteGroupUserResponse.isOK(), "8.1 删除群组的用户失败:" + deleteGroupUserResponse); + + // 9. 列举群组的用户,验证删除 + getGroupUsersRequest = new ApiGetGroupUsers.Request(baseUrl, groupAlias); + getGroupUsersApi = new ApiGetGroupUsers(null, config); + getGroupUsersResponse = getGroupUsersApi.request(getGroupUsersRequest); + assertNotNull(getGroupUsersResponse, "9. 列举群组的用户失败:" + getGroupUsersResponse); + assertTrue(getGroupUsersResponse.isOK(), "9.1 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(0, (int) getGroupUsersResponse.getData().getData().getCount(), "9.2 列举群组的用户失败:" + getGroupUsersResponse); + + // 10. 重新分配 User + ApiUpdateGroupUsers.Request.UpdatedGroupIamUsersParam updateGroupUsersRequestParam = new ApiUpdateGroupUsers.Request.UpdatedGroupIamUsersParam(); + updateGroupUsersRequestParam.setUserAliases(new String[]{userAlias}); + ApiUpdateGroupUsers.Request updateGroupUsersRequest = new ApiUpdateGroupUsers.Request(baseUrl, groupAlias, updateGroupUsersRequestParam); + ApiUpdateGroupUsers updateGroupUsersApi = new ApiUpdateGroupUsers(null, config); + ApiUpdateGroupUsers.Response updateGroupUsersResponse = updateGroupUsersApi.request(updateGroupUsersRequest); + assertNotNull(updateGroupUsersResponse, "10. 分组增加 User 失败:" + updateGroupUsersResponse); + assertTrue(updateGroupUsersResponse.isOK(), "10.1 分组增加 User 失败:" + updateGroupUsersResponse); + + // 11. 列举群组的用户,验证重置 + getGroupUsersRequest = new ApiGetGroupUsers.Request(baseUrl, groupAlias); + getGroupUsersApi = new ApiGetGroupUsers(null, config); + getGroupUsersResponse = getGroupUsersApi.request(getGroupUsersRequest); + assertNotNull(getGroupUsersResponse, "11. 列举群组的用户失败:" + getGroupUsersResponse); + assertTrue(getGroupUsersResponse.isOK(), "11.1 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(1, (int) getGroupUsersResponse.getData().getData().getCount(), "11.2 列举群组的用户失败:" + getGroupUsersResponse); + groupUser = getGroupUsersResponse.getData().getData().getList()[0]; + assertEquals(groupUser.getId(), createUser.getId(), "11.3 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getRootUid(), createUser.getRootUid(), "11.4 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getIuid(), createUser.getIuid(), "11.5 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getAlias(), createUser.getAlias(), "11.6 列举群组的用户失败:" + getGroupUsersResponse); + assertNotNull(groupUser.getCreatedAt(), "11.7 列举群组的用户失败:" + getGroupUsersResponse); + assertNotNull(groupUser.getUpdatedAt(), "11.8 列举群组的用户失败:" + getGroupUsersResponse); + assertNotNull(groupUser.getLastLoginTime(), "11.9 列举群组的用户失败:" + getGroupUsersResponse); + assertEquals(groupUser.getEnabled(), createUser.getEnabled(), "11.10 列举群组的用户失败:" + getGroupUsersResponse); + + // 12 列举用户组指定服务操作下的可访问资源 + String service = "cdn"; + String actionAlias = "DownloadCDNLog"; + ApiGetGroupServiceActionResources.Request getGroupServiceActionResourcesRequest = new ApiGetGroupServiceActionResources.Request(baseUrl, groupAlias, service, actionAlias); + ApiGetGroupServiceActionResources getGroupServiceActionResourcesApi = new ApiGetGroupServiceActionResources(null, config); + ApiGetGroupServiceActionResources.Response getGroupServiceActionResourcesResponse = getGroupServiceActionResourcesApi.request(getGroupServiceActionResourcesRequest); + assertNotNull(getGroupServiceActionResourcesResponse, "12 列举子用户指定服务操作下的可访问资源失败:" + getGroupServiceActionResourcesResponse); + assertTrue(getGroupServiceActionResourcesResponse.isOK(), "12.1 列举子用户指定服务操作下的可访问资源失败:" + getGroupServiceActionResourcesResponse); + + ApiGetGroupServiceActionResources.Response.GetGroupServiceActionResources getGroupServiceActionResources = getGroupServiceActionResourcesResponse.getData().getData(); + assertNotNull(getGroupServiceActionResources, "12.2 列举子用户指定服务操作下的可访问资源失败:" + getGroupServiceActionResources); + assertNotNull(getGroupServiceActionResources.getAllowedResources(), "12.3 列举子用户指定服务操作下的可访问资源失败:" + getGroupServiceActionResources); + assertNotNull(getGroupServiceActionResources.getDeniedResources(), "12.4 列举子用户指定服务操作下的可访问资源失败:" + getGroupServiceActionResources); + + } catch (QiniuException e) { + throw new RuntimeException(e); + } + + } +} diff --git a/src/test/java/com/qiniu/iam/apis/PolicyApiTest.java b/src/test/java/com/qiniu/iam/apis/PolicyApiTest.java new file mode 100644 index 000000000..b559c5b9f --- /dev/null +++ b/src/test/java/com/qiniu/iam/apis/PolicyApiTest.java @@ -0,0 +1,338 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.storage.Api; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.*; + +public class PolicyApiTest { + + String userAlias = ApiTestConfig.userAlias; + String userPWD = ApiTestConfig.userPWD; + String groupAlias = ApiTestConfig.groupAlias; + String policyAlias = ApiTestConfig.policyAlias; + String baseUrl = ApiTestConfig.baseUrl; + Api.Config config = ApiTestConfig.config; + + @Test + @Tag("IntegrationTest") + void testPolicyApi() { + // 清理 + try { + ApiDeletePolicy.Request deleteRequest = new ApiDeletePolicy.Request(baseUrl, policyAlias); + ApiDeletePolicy deleteApi = new ApiDeletePolicy(null, config); + deleteApi.request(deleteRequest); + } catch (QiniuException e) { + } + + try { + ApiDeletePolicy.Request deleteRequest = new ApiDeletePolicy.Request(baseUrl, policyAlias + "New"); + ApiDeletePolicy deleteApi = new ApiDeletePolicy(null, config); + deleteApi.request(deleteRequest); + } catch (QiniuException e) { + } + + try { + ApiDeleteUser.Request deleteUserRequest = new ApiDeleteUser.Request(baseUrl, userAlias); + ApiDeleteUser deleteUserApi = new ApiDeleteUser(null, config); + deleteUserApi.request(deleteUserRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + ApiDeleteGroup.Request deleteGroupRequest = new ApiDeleteGroup.Request(baseUrl, groupAlias); + ApiDeleteGroup deleteGroupApi = new ApiDeleteGroup(null, config); + deleteGroupApi.request(deleteGroupRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + String policyDesc = policyAlias + "Desc"; + String policyAction = "cdn/DownloadCDNLog"; + String policyEffect = "Allow"; + String policyResource = "qrn:product:::/a/b/c.txt"; + // 1. 创建 Policy + ApiCreatePolicy.Request.CreateStatement createStatement = new ApiCreatePolicy.Request.CreateStatement(); + createStatement.setActions(new String[]{policyAction}); + createStatement.setEffect(policyEffect); + createStatement.setResources(new String[]{policyResource}); + ApiCreatePolicy.Request.CreatePolicyParam createPolicyRequestParam = new ApiCreatePolicy.Request.CreatePolicyParam(); + createPolicyRequestParam.setEditType(1); + createPolicyRequestParam.setAlias(policyAlias); + createPolicyRequestParam.setDescription(policyDesc); + createPolicyRequestParam.setStatement(new ApiCreatePolicy.Request.CreateStatement[]{createStatement}); + ApiCreatePolicy.Request createPolicyRequest = new ApiCreatePolicy.Request(baseUrl, createPolicyRequestParam); + ApiCreatePolicy createPolicyApi = new ApiCreatePolicy(null, config); + ApiCreatePolicy.Response createPolicyResponse = createPolicyApi.request(createPolicyRequest); + assertNotNull(createPolicyResponse, "1. 创建 Policy 失败:" + createPolicyResponse); + assertTrue(createPolicyResponse.isOK(), "1.1 创建 Policy 失败:" + createPolicyResponse); + + ApiCreatePolicy.Response.CreatedPolicyData createPolicyResponseData = createPolicyResponse.getData().getData(); + assertNotNull(createPolicyResponseData.getId(), "1.2 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(createPolicyResponseData.getRootUid(), "1.3 创建 Policy 失败:" + createPolicyResponse); + assertEquals(createPolicyResponseData.getAlias(), policyAlias, "1.4 创建 Policy 失败:" + createPolicyResponse); + assertEquals(createPolicyResponseData.getDescription(), policyDesc, "1.5 创建 Policy 失败:" + createPolicyResponse); + assertEquals(createPolicyResponseData.getEnabled(), true, "1.6 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(createPolicyResponseData.getUpdatedAt(), "1.7 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(createPolicyResponseData.getCreatedAt(), "1.8 创建 Policy 失败:" + createPolicyResponse); + assertEquals(createPolicyResponseData.getStatement().length, 1, "1.9 创建 Policy 失败:" + createPolicyResponse); + ApiCreatePolicy.Response.CreatedStatement createResponseStatement = createPolicyResponseData.getStatement()[0]; + assertEquals(createResponseStatement.getEffect(), policyEffect, "1.10 创建 Policy 失败:" + createPolicyResponse); + assertEquals(createResponseStatement.getActions()[0], policyAction, "1.11 创建 Policy 失败:" + createPolicyResponse); + assertEquals(createResponseStatement.getResources()[0], policyResource, "1.12 创建 Policy 失败:" + createPolicyResponse); + + // 2. 获取 Policy(验证创建) + ApiGetPolicy.Request getPolicyRequest = new ApiGetPolicy.Request(baseUrl, policyAlias); + ApiGetPolicy getPolicyApi = new ApiGetPolicy(null, config); + ApiGetPolicy.Response getPolicyResponse = getPolicyApi.request(getPolicyRequest); + assertNotNull(getPolicyResponse, "2. 获取 Policy 失败:" + getPolicyResponse); + assertTrue(getPolicyResponse.isOK(), "2.1 获取 Policy 失败:" + getPolicyResponse); + + ApiGetPolicy.Response.GetPolicyData getPolicyResponseData = getPolicyResponse.getData().getData(); + assertNotNull(getPolicyResponseData.getId(), "2.2 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(getPolicyResponseData.getRootUid(), "2.3 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getAlias(), policyAlias, "2.4 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getDescription(), policyDesc, "2.5 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getEnabled(), true, "2.6 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(getPolicyResponseData.getUpdatedAt(), "2.7 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(getPolicyResponseData.getCreatedAt(), "2.8 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getStatement().length, 1, "2.9 创建 Policy 失败:" + createPolicyResponse); + ApiGetPolicy.Response.Statement getPolicyResponseStatement = getPolicyResponseData.getStatement()[0]; + assertEquals(getPolicyResponseStatement.getEffect(), policyEffect, "2.10 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseStatement.getActions()[0], policyAction, "2.11 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseStatement.getResources()[0], policyResource, "2.12 创建 Policy 失败:" + createPolicyResponse); + + // 3. 修改 Policy + String policyAliasNew = policyAlias + "New"; + String policyDescNew = policyDesc + "New"; + String policyActionNew = "certificate/GetCertificate"; + String policyEffectNew = "Deny"; + String policyResourceNew = policyResource + "New"; + ApiModifyPolicy.Request.ModifyStatement modifyPolicyStatement = new ApiModifyPolicy.Request.ModifyStatement(); + modifyPolicyStatement.setEffect(policyEffectNew); + modifyPolicyStatement.setActions(new String[]{policyActionNew}); + modifyPolicyStatement.setResources(new String[]{policyResourceNew}); + ApiModifyPolicy.Request.ModifyPolicyParam modifyPolicyRequestParam = new ApiModifyPolicy.Request.ModifyPolicyParam(); + modifyPolicyRequestParam.setNewAlias(policyAliasNew); + modifyPolicyRequestParam.setDescription(policyDescNew); + modifyPolicyRequestParam.setStatement(new ApiModifyPolicy.Request.ModifyStatement[]{modifyPolicyStatement}); + ApiModifyPolicy.Request modifyPolicyRequest = new ApiModifyPolicy.Request(baseUrl, policyAlias, modifyPolicyRequestParam); + ApiModifyPolicy modifyPolicyApi = new ApiModifyPolicy(null, config); + ApiModifyPolicy.Response modifyPolicyResponse = modifyPolicyApi.request(modifyPolicyRequest); + assertNotNull(modifyPolicyResponse, "3. 获取 Policy 失败:" + modifyPolicyResponse); + assertTrue(modifyPolicyResponse.isOK(), "3.1 获取 Policy 失败:" + modifyPolicyResponse); + + policyAlias = policyAliasNew; + policyDesc = policyDescNew; + policyAction = policyActionNew; + policyEffect = policyEffectNew; + policyResource = policyResourceNew; + ApiModifyPolicy.Response.ModifiedPolicyData modifyPolicyResponseData = modifyPolicyResponse.getData().getData(); + assertNotNull(modifyPolicyResponseData.getId(), "3.2 创建 Policy 失败:" + modifyPolicyResponse); + assertNotNull(modifyPolicyResponseData.getRootUid(), "3.3 创建 Policy 失败:" + modifyPolicyResponse); + assertEquals(modifyPolicyResponseData.getAlias(), policyAlias, "3.4 创建 Policy 失败:" + modifyPolicyResponse); + assertEquals(modifyPolicyResponseData.getDescription(), policyDesc, "3.5 创建 Policy 失败:" + modifyPolicyResponse); + assertEquals(modifyPolicyResponseData.getEnabled(), true, "3.6 创建 Policy 失败:" + modifyPolicyResponse); + assertNotNull(modifyPolicyResponseData.getUpdatedAt(), "3.7 创建 Policy 失败:" + modifyPolicyResponse); + assertNotNull(modifyPolicyResponseData.getCreatedAt(), "3.8 创建 Policy 失败:" + modifyPolicyResponse); + assertEquals(modifyPolicyResponseData.getStatement().length, 1, "3.9 创建 Policy 失败:" + modifyPolicyResponse); + ApiModifyPolicy.Response.ModifiedStatement modifyPolicyResponseStatement = modifyPolicyResponseData.getStatement()[0]; + assertEquals(modifyPolicyResponseStatement.getEffect(), policyEffect, "3.10 创建 Policy 失败:" + modifyPolicyResponse); + assertEquals(modifyPolicyResponseStatement.getActions()[0], policyAction, "3.11 创建 Policy 失败:" + modifyPolicyResponse); + assertEquals(modifyPolicyResponseStatement.getResources()[0], policyResource, "3.12 创建 Policy 失败:" + modifyPolicyResponse); + + // 4. 获取 Policy(验证修改) + getPolicyRequest = new ApiGetPolicy.Request(baseUrl, policyAlias); + getPolicyApi = new ApiGetPolicy(null, config); + getPolicyResponse = getPolicyApi.request(getPolicyRequest); + assertNotNull(getPolicyResponse, "4. 获取 Policy 失败:" + getPolicyResponse); + assertTrue(getPolicyResponse.isOK(), "4.1 获取 Policy 失败:" + getPolicyResponse); + + getPolicyResponseData = getPolicyResponse.getData().getData(); + assertNotNull(getPolicyResponseData.getId(), "4.2 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(getPolicyResponseData.getRootUid(), "4.3 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getAlias(), policyAlias, "4.4 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getDescription(), policyDesc, "4.5 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getEnabled(), true, "4.6 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(getPolicyResponseData.getUpdatedAt(), "4.7 创建 Policy 失败:" + createPolicyResponse); + assertNotNull(getPolicyResponseData.getCreatedAt(), "4.8 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseData.getStatement().length, 1, "4.9 创建 Policy 失败:" + createPolicyResponse); + getPolicyResponseStatement = getPolicyResponseData.getStatement()[0]; + assertEquals(getPolicyResponseStatement.getEffect(), policyEffect, "4.10 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseStatement.getActions()[0], policyAction, "4.11 创建 Policy 失败:" + createPolicyResponse); + assertEquals(getPolicyResponseStatement.getResources()[0], policyResource, "4.12 创建 Policy 失败:" + createPolicyResponse); + + // 5. 列举 Policy + ApiGetPolicies.Request getPoliciesRequest = new ApiGetPolicies.Request(baseUrl); + ApiGetPolicies getPoliciesApi = new ApiGetPolicies(null, config); + ApiGetPolicies.Response getPoliciesResponse = getPoliciesApi.request(getPoliciesRequest); + assertNotNull(getPoliciesResponse, "5. 获取所有 Policy 失败:" + getPoliciesResponse); + assertTrue(getPoliciesResponse.isOK(), "5.1 获取所有 Policy 失败:" + getPoliciesResponse); + + ApiGetPolicies.Response.Policy[] allPolicies = getPoliciesResponse.getData().getData().getList(); + ApiGetPolicies.Response.Policy listPolicy = null; + for (ApiGetPolicies.Response.Policy policy : allPolicies) { + if (Objects.equals(policy.getId(), getPolicyResponseData.getId())) { + listPolicy = policy; + break; + } + } + assertNotNull(listPolicy.getId(), "5.2 创建 Policy 失败:" + getPoliciesResponse); + assertNotNull(listPolicy.getRootUid(), "5.3 创建 Policy 失败:" + getPoliciesResponse); + assertEquals(listPolicy.getAlias(), policyAlias, "5.4 创建 Policy 失败:" + getPoliciesResponse); + assertEquals(listPolicy.getDescription(), policyDesc, "5.5 创建 Policy 失败:" + getPoliciesResponse); + assertEquals(listPolicy.getEnabled(), true, "5.6 创建 Policy 失败:" + getPoliciesResponse); + assertNotNull(listPolicy.getUpdatedAt(), "5.7 创建 Policy 失败:" + getPoliciesResponse); + assertNotNull(listPolicy.getCreatedAt(), "5.8 创建 Policy 失败:" + getPoliciesResponse); + assertEquals(listPolicy.getStatement().length, 1, "5.9 创建 Policy 失败:" + getPoliciesResponse); + ApiGetPolicies.Response.Statement listPolicyResponseStatement = listPolicy.getStatement()[0]; + assertEquals(listPolicyResponseStatement.getEffect(), policyEffect, "5.10 创建 Policy 失败:" + getPoliciesResponse); + assertEquals(listPolicyResponseStatement.getActions()[0], policyAction, "5.11 创建 Policy 失败:" + getPoliciesResponse); + assertEquals(listPolicyResponseStatement.getResources()[0], policyResource, "5.12 创建 Policy 失败:" + createPolicyResponse); + + // 6. 删除 Policy + ApiDeletePolicy.Request deletePolicyRequest = new ApiDeletePolicy.Request(baseUrl, policyAlias); + ApiDeletePolicy deletePolicyApi = new ApiDeletePolicy(null, config); + ApiDeletePolicy.Response deletePolicyResponse = deletePolicyApi.request(deletePolicyRequest); + assertNotNull(deletePolicyResponse, "6. 获取所有 Policy 失败:" + deletePolicyResponse); + assertTrue(deletePolicyResponse.isOK(), "6.1 获取所有 Policy 失败:" + deletePolicyResponse); + + // 7. 获取 Policy(验证删除) + getPoliciesRequest = new ApiGetPolicies.Request(baseUrl); + getPoliciesApi = new ApiGetPolicies(null, config); + getPoliciesResponse = getPoliciesApi.request(getPoliciesRequest); + assertNotNull(getPoliciesResponse, "7. 获取所有 Policy 失败:" + getPoliciesResponse); + assertTrue(getPoliciesResponse.isOK(), "7.1 获取所有 Policy 失败:" + getPoliciesResponse); + + allPolicies = getPoliciesResponse.getData().getData().getList(); + listPolicy = null; + for (ApiGetPolicies.Response.Policy policy : allPolicies) { + if (Objects.equals(policy.getId(), getPolicyResponseData.getId())) { + listPolicy = policy; + break; + } + } + assertNull(listPolicy, "7.2 获取所有 Policy 失败:" + deletePolicyResponse); + + // 8. 创建 Policy 用户 + ApiCreateUser.Request.CreateIamUserParam createUserParam = new ApiCreateUser.Request.CreateIamUserParam(); + createUserParam.setAlias(userAlias); + createUserParam.setPassword(userPWD); + ApiCreateUser.Request createRequest = new ApiCreateUser.Request(baseUrl, createUserParam); + ApiCreateUser createUserApi = new ApiCreateUser(null, config); + ApiCreateUser.Response createUserResponse = createUserApi.request(createRequest); + assertNotNull(createUserResponse, "8. 创建 Policy 用户失败:" + createUserResponse); + assertTrue(createUserResponse.isOK(), "8.1 创建 Policy 用户失败:" + createUserResponse); + ApiCreateUser.Response.CreatedIamUserData createdUserData = createUserResponse.getData().getData(); + + // 9. 创建 Policy + createStatement = new ApiCreatePolicy.Request.CreateStatement(); + createStatement.setActions(new String[]{policyAction}); + createStatement.setEffect(policyEffect); + createStatement.setResources(new String[]{policyResource}); + createPolicyRequestParam = new ApiCreatePolicy.Request.CreatePolicyParam(); + createPolicyRequestParam.setEditType(1); + createPolicyRequestParam.setAlias(policyAlias); + createPolicyRequestParam.setDescription(policyDesc); + createPolicyRequestParam.setStatement(new ApiCreatePolicy.Request.CreateStatement[]{createStatement}); + createPolicyRequest = new ApiCreatePolicy.Request(baseUrl, createPolicyRequestParam); + createPolicyApi = new ApiCreatePolicy(null, config); + createPolicyResponse = createPolicyApi.request(createPolicyRequest); + assertNotNull(createPolicyResponse, "9. 创建 Policy 失败:" + createPolicyResponse); + assertTrue(createPolicyResponse.isOK(), "9.1 创建 Policy 失败:" + createPolicyResponse); + + // 9.1 Policy 添加用户 + ApiUpdatePolicyUsers.Request.UpdatedPolicyIamUsersParam updatePolicyUsersRequestParam = new ApiUpdatePolicyUsers.Request.UpdatedPolicyIamUsersParam(); + updatePolicyUsersRequestParam.setUserAliases(new String[]{userAlias}); + ApiUpdatePolicyUsers.Request updatePolicyUsersRequest = new ApiUpdatePolicyUsers.Request(baseUrl, policyAlias, updatePolicyUsersRequestParam); + ApiUpdatePolicyUsers updatePolicyUsersApi = new ApiUpdatePolicyUsers(null, config); + ApiUpdatePolicyUsers.Response updatePolicyUsersResponse = updatePolicyUsersApi.request(updatePolicyUsersRequest); + assertNotNull(updatePolicyUsersResponse, "9.1 Policy 添加用户失败:" + updatePolicyUsersResponse); + assertTrue(updatePolicyUsersResponse.isOK(), "9.1.1 Policy 添加用户失败:" + updatePolicyUsersResponse); + + // 10. 获取 Policy 用户 + ApiGetPolicyUsers.Request getPolicyUsersRequest = new ApiGetPolicyUsers.Request(baseUrl, policyAlias); + ApiGetPolicyUsers getPolicyUsersApi = new ApiGetPolicyUsers(null, config); + ApiGetPolicyUsers.Response getPolicyUsersResponse = getPolicyUsersApi.request(getPolicyUsersRequest); + assertNotNull(getPolicyUsersResponse, "10. 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertTrue(getPolicyUsersResponse.isOK(), "10.1 获取 Policy 用户失败:" + getPolicyUsersResponse); + + ApiGetPolicyUsers.Response.PolicyIamUser[] allPolicyUsers = getPolicyUsersResponse.getData().getData().getList(); + assertTrue(allPolicyUsers.length > 0, "10.2 获取 Policy 用户失败:" + getPolicyUsersResponse); + + ApiGetPolicyUsers.Response.PolicyIamUser getPolicyResponseUser = null; + for (ApiGetPolicyUsers.Response.PolicyIamUser user : allPolicyUsers) { + if (user.getId().equals(createUserResponse.getData().getData().getId())) { + getPolicyResponseUser = user; + break; + } + } + assertEquals(getPolicyResponseUser.getAlias(), userAlias, "10.3 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getId(), "10.4 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getRootUid(), "10.5 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getIuid(), "10.6 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getAlias(), "10.7 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getCreatedAt(), "10.8 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getUpdatedAt(), "10.9 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getLastLoginTime(), "10.10 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertNotNull(getPolicyResponseUser.getEnabled(), "10.11 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertEquals(getPolicyResponseUser.getId(), createdUserData.getId(), "10.12 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertEquals(getPolicyResponseUser.getRootUid(), createdUserData.getRootUid(), "10.13 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertEquals(getPolicyResponseUser.getIuid(), createdUserData.getIuid(), "10.14 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertEquals(getPolicyResponseUser.getAlias(), createdUserData.getAlias(), "10.15 获取 Policy 用户失败:" + getPolicyUsersResponse); + assertEquals(getPolicyResponseUser.getEnabled(), createdUserData.getEnabled(), "10.16 获取 Policy 用户失败:" + getPolicyUsersResponse); + + // 11. 创建 Policy 群组 + ApiCreateGroup.Request.CreateGroupParam createGroupParam = new ApiCreateGroup.Request.CreateGroupParam(); + createGroupParam.setAlias(groupAlias); + ApiCreateGroup.Request createGroupRequest = new ApiCreateGroup.Request(baseUrl, createGroupParam); + ApiCreateGroup createGroupApi = new ApiCreateGroup(null, config); + ApiCreateGroup.Response createGroupResponse = createGroupApi.request(createGroupRequest); + Assertions.assertNotNull(createGroupResponse, "11. 创建 Policy 群组失败:" + createGroupResponse); + Assertions.assertTrue(createGroupResponse.isOK(), "11.1 创建 Policy 群组失败:" + createGroupResponse); + ApiCreateGroup.Response.CreatedGroupData createGroupResponseData = createGroupResponse.getData().getData(); + + // 12. Policy 添加群组 + ApiUpdatePolicyGroups.Request.UpdatedPolicyGroupsParam updatePolicyGroupsRequestParam = new ApiUpdatePolicyGroups.Request.UpdatedPolicyGroupsParam(); + updatePolicyGroupsRequestParam.setGroupAliases(new String[]{groupAlias}); + ApiUpdatePolicyGroups.Request updatePolicyGroupsRequest = new ApiUpdatePolicyGroups.Request(baseUrl, policyAlias, updatePolicyGroupsRequestParam); + ApiUpdatePolicyGroups updatePolicyGroupsApi = new ApiUpdatePolicyGroups(null, config); + ApiUpdatePolicyGroups.Response updatePolicyGroupsResponse = updatePolicyGroupsApi.request(updatePolicyGroupsRequest); + Assertions.assertNotNull(updatePolicyGroupsResponse, "12. Policy 添加群组失败:" + updatePolicyGroupsResponse); + Assertions.assertTrue(updatePolicyGroupsResponse.isOK(), "12.1 Policy 添加群组失败:" + updatePolicyGroupsResponse); + + // 13. 获取 Policy 群组 + ApiGetPolicyGroups.Request getPolicyGroupsRequest = new ApiGetPolicyGroups.Request(baseUrl, policyAlias); + ApiGetPolicyGroups getPolicyGroupsApi = new ApiGetPolicyGroups(null, config); + ApiGetPolicyGroups.Response getPolicyGroupsResponse = getPolicyGroupsApi.request(getPolicyGroupsRequest); + Assertions.assertNotNull(getPolicyGroupsResponse, "13. 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertTrue(getPolicyGroupsResponse.isOK(), "13.1 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertTrue(getPolicyGroupsResponse.getData().getData().getCount() > 0, "13.2 获取 Policy 群组失败:" + getPolicyGroupsResponse); + + ApiGetPolicyGroups.Response.GetPolicyGroup[] allPolicyGroups = getPolicyGroupsResponse.getData().getData().getList(); + Assertions.assertNotNull(allPolicyGroups, "13. 获取 Policy 群组失败:" + getPolicyGroupsResponse); + assertEquals(allPolicyGroups.length, (int) getPolicyGroupsResponse.getData().getData().getCount(), "13.1 获取 Policy 群组失败:" + getPolicyGroupsResponse); + + ApiGetPolicyGroups.Response.GetPolicyGroup policyGroup = allPolicyGroups[0]; + Assertions.assertEquals(policyGroup.getId(), createGroupResponseData.getId(), "13.2 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertEquals(policyGroup.getRootUid(), createGroupResponseData.getRootUid(), "13.3 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertEquals(policyGroup.getAlias(), createGroupResponseData.getAlias(), "13.4 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertEquals(policyGroup.getDescription(), createGroupResponseData.getDescription(), "13.5 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertEquals(policyGroup.getEnabled(), createGroupResponseData.getEnabled(), "13.6 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertNotNull(policyGroup.getCreatedAt(), "13.7 获取 Policy 群组失败:" + getPolicyGroupsResponse); + Assertions.assertNotNull(policyGroup.getUpdatedAt(), "13.8 获取 Policy 群组失败:" + getPolicyGroupsResponse); + + + } catch (QiniuException e) { + fail(); + throw new RuntimeException(e); + } + } +} diff --git a/src/test/java/com/qiniu/iam/apis/SystemApiTest.java b/src/test/java/com/qiniu/iam/apis/SystemApiTest.java new file mode 100644 index 000000000..51047b26f --- /dev/null +++ b/src/test/java/com/qiniu/iam/apis/SystemApiTest.java @@ -0,0 +1,90 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.storage.Api; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class SystemApiTest { + + String baseUrl = ApiTestConfig.baseUrl; + Api.Config config = ApiTestConfig.config; + + @Test + @Tag("IntegrationTest") + void testAction() { + try { + ApiGetActions.Request request = new ApiGetActions.Request(baseUrl); + ApiGetActions api = new ApiGetActions(null, config); + ApiGetActions.Response response = api.request(request); + assertNotNull(response, "1. 获取 Action 失败:" + response); + assertTrue(response.isOK(), "1.1 获取 Action 失败:" + response); + ApiGetActions.Response.GetActionsData responseData = response.getData().getData(); + assertTrue(responseData.getCount() > 0, "1.2 获取 Action 失败:" + response); + ApiGetActions.Response.GetAction action = responseData.getList()[0]; + assertNotNull(action.getId(), "1.3 获取 Action 失败:" + response); + assertNotNull(action.getName(), "1.4 获取 Action 失败:" + response); + assertNotNull(action.getAlias(), "1.5 获取 Action 失败:" + response); + assertNotNull(action.getService(), "1.6 获取 Action 失败:" + response); + assertNotNull(action.getScope(), "1.7 获取 Action 失败:" + response); + assertNotNull(action.getEnabled(), "1.8 获取 Action 失败:" + response); + assertNotNull(action.getCreatedAt(), "1.9 获取 Action 失败:" + response); + assertNotNull(action.getUpdatedAt(), "1.10 获取 Action 失败:" + response); + } catch (QiniuException e) { + fail(); + throw new RuntimeException(e); + } + } + + @Test + @Tag("IntegrationTest") + void testService() { + try { + ApiGetServices.Request request = new ApiGetServices.Request(baseUrl); + ApiGetServices api = new ApiGetServices(null, config); + ApiGetServices.Response response = api.request(request); + assertNotNull(response, "1. 获取 Services 失败:" + response); + assertTrue(response.isOK(), "1.1 获取 Services 失败:" + response); + ApiGetServices.Response.GetServicesResp responseData = response.getData(); + assertTrue(responseData.getData().length > 0, "1.2 获取 Services 失败:" + response); + } catch (QiniuException e) { + fail(); + throw new RuntimeException(e); + } + } + + @Test + @Tag("IntegrationTest") + void testAudits() { + try { + ApiGetAudits.Request request = new ApiGetAudits.Request(baseUrl); + ApiGetAudits api = new ApiGetAudits(null, config); + ApiGetAudits.Response response = api.request(request); + assertNotNull(response, "1. 获取 Audits 失败:" + response); + assertTrue(response.isOK(), "1.1 获取 Audits 失败:" + response); + ApiGetAudits.Response.GetAuditLogsData responseData = response.getData().getData(); + assertNotNull(responseData.getMarker(), "1.2 获取 Audits 失败:" + response); + if (responseData.getList().length > 0) { + ApiGetAudits.Response.GetAuditLog log = responseData.getList()[0]; + assertNotNull(log.getId(), "1.3 获取 Audits 失败:" + response); + assertNotNull(log.getRootUid(), "1.4 获取 Audits 失败:" + response); + assertNotNull(log.getIuid(), "1.5 获取 Audits 失败:" + response); + assertNotNull(log.getService(), "1.6 获取 Audits 失败:" + response); + assertNotNull(log.getAction(), "1.7 获取 Audits 失败:" + response); + assertNotNull(log.getCreatedAt(), "1.8 获取 Audits 失败:" + response); + assertNotNull(log.getEventTime(), "1.9 获取 Audits 失败:" + response); + assertNotNull(log.getDurationMs(), "1.10 获取 Audits 失败:" + response); + assertNotNull(log.getSourceIp(), "1.11 获取 Audits 失败:" + response); + assertNotNull(log.getUserEvent(), "1.12 获取 Audits 失败:" + response); + assertNotNull(log.getErrorCode(), "1.13 获取 Audits 失败:" + response); + assertNotNull(log.getErrorMessage(), "1.14 获取 Audits 失败:" + response); + } + } catch (QiniuException e) { + fail(); + throw new RuntimeException(e); + } + + } +} diff --git a/src/test/java/com/qiniu/iam/apis/UserApiTest.java b/src/test/java/com/qiniu/iam/apis/UserApiTest.java new file mode 100644 index 000000000..5112db207 --- /dev/null +++ b/src/test/java/com/qiniu/iam/apis/UserApiTest.java @@ -0,0 +1,503 @@ +package com.qiniu.iam.apis; + +import com.qiniu.common.QiniuException; +import com.qiniu.storage.Api; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class UserApiTest { + + String userAlias = ApiTestConfig.userAlias; + String groupAlias = ApiTestConfig.groupAlias; + String policyAlias = ApiTestConfig.policyAlias; + String userPWD = ApiTestConfig.userPWD; + String baseUrl = ApiTestConfig.baseUrl; + Api.Config config = ApiTestConfig.config; + + @Test + @Tag("IntegrationTest") + void testUsers() { + // 先删除,流程开始先清理历史数据 + try { + ApiDeleteUser.Request deleteUserRequest = new ApiDeleteUser.Request(baseUrl, userAlias); + ApiDeleteUser deleteUserApi = new ApiDeleteUser(null, config); + deleteUserApi.request(deleteUserRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + e.printStackTrace(); + } + + try { + // 1. 创建 + ApiCreateUser.Request.CreateIamUserParam createParam = new ApiCreateUser.Request.CreateIamUserParam(); + createParam.setAlias(userAlias); + createParam.setPassword(userPWD); + ApiCreateUser.Request createRequest = new ApiCreateUser.Request(baseUrl, createParam); + ApiCreateUser createApi = new ApiCreateUser(null, config); + ApiCreateUser.Response createResponse = createApi.request(createRequest); + assertNotNull(createResponse, "1. 创建 User 失败:" + createResponse); + assertTrue(createResponse.isOK(), "1.1 创建 User 失败:" + createResponse); + ApiCreateUser.Response.CreatedIamUserData createdUserData = createResponse.getData().getData(); + assertEquals(createdUserData.getAlias(), userAlias, "1.2 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getId(), "1.3 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getRootUid(), "1.4 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getIuid(), "1.5 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getAlias(), "1.6 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getCreatedAt(), "1.7 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getUpdatedAt(), "1.8 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getLastLoginTime(), "1.9 创建 User 失败:" + createResponse); + assertNotNull(createdUserData.getEnabled(), "1.10 创建 User 失败:" + createResponse); + + // 2. 获取某个 + ApiGetUser.Request getRequest = new ApiGetUser.Request(baseUrl, userAlias); + ApiGetUser getApi = new ApiGetUser(null, config); + ApiGetUser.Response getResponse = getApi.request(getRequest); + assertNotNull(getResponse, "2. 获取 User 失败:" + getResponse); + assertEquals(createResponse.getResponse().statusCode, 200, "2.1 获取 User 失败:" + getResponse); + ApiGetUser.Response.GetIamUserData getUserData = getResponse.getData().getData(); + assertEquals(getUserData.getAlias(), userAlias, "2.2 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getId(), "2.3 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getRootUid(), "2.4 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getIuid(), "2.5 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getAlias(), "2.6 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getCreatedAt(), "2.7 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getUpdatedAt(), "2.8 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getLastLoginTime(), "2.9 获取 User 失败:" + getResponse); + assertNotNull(getUserData.getEnabled(), "2.10 获取 User 失败:" + getResponse); + assertEquals(getUserData.getId(), createdUserData.getId(), "2.11 获取 User 失败:" + getResponse); + assertEquals(getUserData.getRootUid(), createdUserData.getRootUid(), "2.12 获取 User 失败:" + getResponse); + assertEquals(getUserData.getIuid(), createdUserData.getIuid(), "2.13 获取 User 失败:" + getResponse); + assertEquals(getUserData.getAlias(), createdUserData.getAlias(), "2.14 获取 User 失败:" + getResponse); + assertEquals(getUserData.getEnabled(), createdUserData.getEnabled(), "2.15 获取 User 失败:" + getResponse); + + // 3. 修改 + ApiModifyUser.Request.ModifiedIamUserParam modifyParam = new ApiModifyUser.Request.ModifiedIamUserParam(); + modifyParam.setEnabled(false); + ApiModifyUser.Request modifyRequest = new ApiModifyUser.Request(baseUrl, userAlias, modifyParam); + ApiModifyUser modifyApi = new ApiModifyUser(null, config); + ApiModifyUser.Response modifyResponse = modifyApi.request(modifyRequest); + assertTrue(modifyResponse.isOK(), "3.1 修改 User 失败:" + getResponse); + ApiModifyUser.Response.ModifiedIamUserData modifyUserData = modifyResponse.getData().getData(); + assertEquals(modifyUserData.getId(), createdUserData.getId(), "3.2 修改 User 失败:" + getResponse); + assertEquals(modifyUserData.getRootUid(), createdUserData.getRootUid(), "3.3 修改 User 失败:" + getResponse); + assertEquals(modifyUserData.getIuid(), createdUserData.getIuid(), "3.4 修改 User 失败:" + getResponse); + assertEquals(modifyUserData.getAlias(), createdUserData.getAlias(), "3.5 修改 User 失败:" + getResponse); + assertNotNull(modifyUserData.getCreatedAt(), "3.6 修改 User 失败:" + getResponse); + assertNotNull(modifyUserData.getUpdatedAt(), "3.7 修改 User 失败:" + getResponse); + assertNotNull(modifyUserData.getLastLoginTime(), "3.8 修改 User 失败:" + getResponse); + assertEquals(modifyUserData.getEnabled(), false, "3.9 修改 User 失败:" + getResponse); + + // 4. 列举所有 + ApiGetUsers.Request getUsersRequest = new ApiGetUsers.Request(baseUrl) + .setAlias(userAlias); + ApiGetUsers getUsersApi = new ApiGetUsers(null, config); + ApiGetUsers.Response getUsersResponse = getUsersApi.request(getUsersRequest); + assertTrue(getUsersResponse.isOK(), "4.1 列举 User 失败:" + getResponse); + ApiGetUsers.Response.GetIamUsersData getUsersDataList = getUsersResponse.getData().getData(); + assertEquals(1, (int) getUsersDataList.getCount(), "4.2 列举 User 失败:" + getResponse); + ApiGetUsers.Response.GetIamUser getUsersData = getUsersDataList.getList()[0]; + assertEquals(getUsersData.getId(), modifyUserData.getId(), "4.3 修改 User 失败:" + getResponse); + assertEquals(getUsersData.getRootUid(), modifyUserData.getRootUid(), "4.4 修改 User 失败:" + getResponse); + assertEquals(getUsersData.getIuid(), modifyUserData.getIuid(), "4.5 修改 User 失败:" + getResponse); + assertEquals(getUsersData.getAlias(), modifyUserData.getAlias(), "4.6 修改 User 失败:" + getResponse); + assertNotNull(getUsersData.getCreatedAt(), "4.7 修改 User 失败:" + getResponse); + assertNotNull(getUsersData.getUpdatedAt(), "4.8 修改 User 失败:" + getResponse); + assertNotNull(getUsersData.getLastLoginTime(), "4.9 修改 User 失败:" + getResponse); + assertEquals(getUsersData.getEnabled(), modifyUserData.getEnabled(), "4.10 修改 User 失败:" + getResponse); + + // 5. 删除 + ApiDeleteUser.Request deleteUserRequest = new ApiDeleteUser.Request(baseUrl, userAlias); + ApiDeleteUser deleteUserApi = new ApiDeleteUser(null, config); + ApiDeleteUser.Response deleteUserResponse = deleteUserApi.request(deleteUserRequest); + assertTrue(deleteUserResponse.isOK(), "5.1 删除 User 失败:" + getResponse); + + } catch (QiniuException e) { + throw new RuntimeException(e); + } + } + + @Test + @Tag("IntegrationTest") + void testUsersKeyPairs() { + + // 先删除,流程开始先清理历史数据 + try { + ApiDeleteUser.Request deleteUserRequest = new ApiDeleteUser.Request(baseUrl, userAlias); + ApiDeleteUser deleteUserApi = new ApiDeleteUser(null, config); + deleteUserApi.request(deleteUserRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + e.printStackTrace(); + } + + try { + // 1. 创建用户 + // 创建后会自带一组 + ApiCreateUser.Request.CreateIamUserParam createUserParam = new ApiCreateUser.Request.CreateIamUserParam(); + createUserParam.setAlias(userAlias); + createUserParam.setPassword(userPWD); + ApiCreateUser.Request createUserRequest = new ApiCreateUser.Request(baseUrl, createUserParam); + ApiCreateUser createUserApi = new ApiCreateUser(null, config); + ApiCreateUser.Response createUserResponse = createUserApi.request(createUserRequest); + assertNotNull(createUserResponse, "1. 创建 User 失败:" + createUserResponse); + assertEquals(createUserResponse.isOK(), true, "1.1 创建 User 失败:" + createUserResponse); + ApiCreateUser.Response.CreatedIamUserData createUserResponseData = createUserResponse.getData().getData(); + + // 2. 创建秘钥 + ApiCreateUserKeypairs.Request createRequest = new ApiCreateUserKeypairs.Request(baseUrl, userAlias); + ApiCreateUserKeypairs createApi = new ApiCreateUserKeypairs(null, config); + ApiCreateUserKeypairs.Response createResponse = createApi.request(createRequest); + assertNotNull(createUserResponse, "2. 创建 User 秘钥失败:" + createUserResponse); + assertEquals(createUserResponse.isOK(), true, "2.1 创建 User 秘钥失败:" + createUserResponse); + ApiCreateUserKeypairs.Response.CreatedIamUserKeyPairData createResponseData = createResponse.getData().getData(); + assertNotNull(createResponseData.getId(), "2.3 创建 User 秘钥失败:" + createUserResponse); + assertNotNull(createResponseData.getAccessKey(), "2.4 创建 User 秘钥失败:" + createUserResponse); + assertNotNull(createResponseData.getSecretKey(), "2.5 创建 User 秘钥失败:" + createUserResponse); + assertEquals(createResponseData.getUserId(), createUserResponseData.getId(), "2.6 创建 User 秘钥失败:" + createUserResponse); + assertNotNull(createResponseData.getCreatedAt(), "2.7 创建 User 秘钥失败:" + createUserResponse); + assertEquals(createResponseData.getEnabled(), true, "2.8 创建 User 秘钥失败:" + createUserResponse); + + // 3. 获取秘钥 + ApiGetUserKeypairs.Request getRequest = new ApiGetUserKeypairs.Request(baseUrl, userAlias); + ApiGetUserKeypairs getApi = new ApiGetUserKeypairs(null, config); + ApiGetUserKeypairs.Response getResponse = getApi.request(getRequest); + assertNotNull(getResponse, "3. 获取 User 秘钥失败:" + createUserResponse); + assertEquals(getResponse.isOK(), true, "3.1 创建 User 秘钥失败:" + getResponse); + ApiGetUserKeypairs.Response.GetIamUserKeyPairsData getResponseData = getResponse.getData().getData(); + assertEquals(getResponseData.getCount().intValue(), 2, "3.2 创建 User 秘钥失败:" + getResponse); + ApiGetUserKeypairs.Response.GetIamUserKeyPair keyPair = null; + for (ApiGetUserKeypairs.Response.GetIamUserKeyPair kp : getResponseData.getList()) { + if (kp.getAccessKey().equals(createResponseData.getAccessKey())) { + keyPair = kp; + } + } + assertNotNull(keyPair, "3.3 创建 User 秘钥失败:" + getResponse); + assertNotNull(keyPair.getId(), "3.4 创建 User 秘钥失败:" + getResponse); + assertEquals(keyPair.getSecretKey(), createResponseData.getSecretKey(), "3.5 创建 User 秘钥失败:" + getResponse); + assertEquals(keyPair.getUserId(), createUserResponseData.getId(), "3.6 创建 User 秘钥失败:" + getResponse); + assertNotNull(keyPair.getCreatedAt(), "3.7 创建 User 秘钥失败:" + getResponse); + assertNotNull(keyPair.getEnabled(), "3.8 创建 User 秘钥失败:" + getResponse); + + // 4. 修改秘钥: Disable + ApiDisableUserKeypair.Request diableRequest = new ApiDisableUserKeypair.Request(baseUrl, userAlias, createResponseData.getAccessKey()); + ApiDisableUserKeypair disableApi = new ApiDisableUserKeypair(null, config); + ApiDisableUserKeypair.Response disableResponse = disableApi.request(diableRequest); + assertNotNull(disableResponse, "4. Disable User 秘钥失败:" + disableResponse); + assertEquals(disableResponse.isOK(), true, "4.1 Disable User 秘钥失败:" + disableResponse); + + // 5. 验证秘钥修改: Disable + getResponse = getApi.request(getRequest); + assertNotNull(getResponse, "5. 验证 User 秘钥失败:" + createUserResponse); + assertEquals(getResponse.isOK(), true, "5.1 验证 User 秘钥失败:" + getResponse); + getResponseData = getResponse.getData().getData(); + assertEquals(getResponseData.getCount().intValue(), 2, "5.2 验证 User 秘钥失败:" + getResponse); + for (ApiGetUserKeypairs.Response.GetIamUserKeyPair kp : getResponseData.getList()) { + if (kp.getAccessKey().equals(createResponseData.getAccessKey())) { + keyPair = kp; + } + } + assertEquals(keyPair.getEnabled(), false, "5.3 验证 User 秘钥失败:" + getResponse); + + // 6. 修改秘钥: Enable + ApiEnableUserKeypair.Request enableRequest = new ApiEnableUserKeypair.Request(baseUrl, userAlias, createResponseData.getAccessKey()); + ApiEnableUserKeypair enableApi = new ApiEnableUserKeypair(null, config); + ApiEnableUserKeypair.Response enableResponse = enableApi.request(enableRequest); + assertNotNull(enableResponse, "6. Enable User 秘钥失败:" + enableResponse); + assertEquals(enableResponse.isOK(), true, "6.1 Enable User 秘钥失败:" + enableResponse); + + // 7. 验证秘钥修改: Disable + getResponse = getApi.request(getRequest); + assertNotNull(getResponse, "7. 验证 User 秘钥失败:" + createUserResponse); + assertEquals(getResponse.isOK(), true, "7.1 验证 User 秘钥失败:" + getResponse); + getResponseData = getResponse.getData().getData(); + assertEquals(getResponseData.getCount().intValue(), 2, "7.2 验证 User 秘钥失败:" + getResponse); + for (ApiGetUserKeypairs.Response.GetIamUserKeyPair kp : getResponseData.getList()) { + if (kp.getAccessKey().equals(createResponseData.getAccessKey())) { + keyPair = kp; + } + } + assertEquals(keyPair.getEnabled(), true, "7.3 验证 User 秘钥失败:" + getResponse); + + // 8. 删除秘钥 + ApiDeleteUserKeypair.Request deleteRequest = new ApiDeleteUserKeypair.Request(baseUrl, userAlias, createResponseData.getAccessKey()); + ApiDeleteUserKeypair deleteApi = new ApiDeleteUserKeypair(null, config); + ApiDeleteUserKeypair.Response deleteResponse = deleteApi.request(deleteRequest); + assertNotNull(deleteResponse, "8. Delete User 秘钥失败:" + deleteResponse); + assertEquals(deleteResponse.isOK(), true, "8.1 Delete User 秘钥失败:" + deleteResponse); + + } catch (QiniuException e) { + throw new RuntimeException(e); + } + } + + @Test + @Tag("IntegrationTest") + void testUsersGroups() { + try { + ApiDeleteUser.Request deleteUserRequest = new ApiDeleteUser.Request(baseUrl, userAlias); + ApiDeleteUser deleteUserApi = new ApiDeleteUser(null, config); + deleteUserApi.request(deleteUserRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + ApiDeleteGroup.Request deleteGroupRequest = new ApiDeleteGroup.Request(baseUrl, groupAlias); + ApiDeleteGroup deleteGroupApi = new ApiDeleteGroup(null, config); + deleteGroupApi.request(deleteGroupRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + // 0 创建用户的 + ApiCreateUser.Request.CreateIamUserParam createUserParam = new ApiCreateUser.Request.CreateIamUserParam(); + createUserParam.setAlias(userAlias); + createUserParam.setPassword(userPWD); + ApiCreateUser.Request createUserRequest = new ApiCreateUser.Request(baseUrl, createUserParam); + ApiCreateUser createUserApi = new ApiCreateUser(null, config); + ApiCreateUser.Response createUserResponse = createUserApi.request(createUserRequest); + assertNotNull(createUserResponse, "0. 创建 User 失败:" + createUserResponse); + assertEquals(createUserResponse.isOK(), true, "0.1 创建 User 失败:" + createUserResponse); + + // 1 创建用户的 Group + ApiCreateGroup.Request.CreateGroupParam createGroupParam = new ApiCreateGroup.Request.CreateGroupParam(); + createGroupParam.setAlias(groupAlias); + ApiCreateGroup.Request createGroupRequest = new ApiCreateGroup.Request(baseUrl, createGroupParam); + ApiCreateGroup createGroupApi = new ApiCreateGroup(null, config); + ApiCreateGroup.Response createGroupResponse = createGroupApi.request(createGroupRequest); + Assertions.assertNotNull(createGroupResponse, "1. 创建分组失败:" + createGroupResponse); + Assertions.assertTrue(createGroupResponse.isOK(), "1.1 创建分组失败:" + createGroupResponse); + + // 2 用户添加至 Group + ApiUpdateUserGroups.Request.UpdatedIamUserGroupsParam updateUserGroupsRequestParam = new ApiUpdateUserGroups.Request.UpdatedIamUserGroupsParam(); + updateUserGroupsRequestParam.setGroupAliases(new String[]{groupAlias}); + ApiUpdateUserGroups.Request updateUserGroupsRequest = new ApiUpdateUserGroups.Request(baseUrl, userAlias, updateUserGroupsRequestParam); + ApiUpdateUserGroups updateUserGroupsApi = new ApiUpdateUserGroups(null, config); + ApiUpdateUserGroups.Response updateUserGroupsResponse = updateUserGroupsApi.request(updateUserGroupsRequest); + Assertions.assertNotNull(updateUserGroupsResponse, "2 用户添加至 Group 失败:" + updateUserGroupsResponse); + Assertions.assertTrue(updateUserGroupsResponse.isOK(), "2.1 用户添加至 Group 失败:" + updateUserGroupsResponse); + + // 3 获取用户的 Group(验证) + ApiGetUserGroups.Request getUserGroupsRequest = new ApiGetUserGroups.Request(baseUrl, userAlias); + getUserGroupsRequest.setPage(0); + ApiGetUserGroups getUserGroupsApi = new ApiGetUserGroups(null, config); + ApiGetUserGroups.Response getUserGroupsResponse = getUserGroupsApi.request(getUserGroupsRequest); + Assertions.assertNotNull(getUserGroupsResponse, "3 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertTrue(getUserGroupsResponse.isOK(), "3.1 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertTrue(getUserGroupsResponse.getData().getData().getCount() > 0, "3.2 获取用户的 Group 失败:" + getUserGroupsResponse); + + ApiGetUserGroups.Response.IamUserGroup userGroup = getUserGroupsResponse.getData().getData().getList()[0]; + Assertions.assertNotNull(userGroup.getId(), "3.3 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertNotNull(userGroup.getRootUid(), "3.4 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertEquals(userGroup.getAlias(), groupAlias, "3.5 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertNotNull(userGroup.getDescription(), "3.6 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertEquals(userGroup.getEnabled(), true, "3.7 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertNotNull(userGroup.getCreatedAt(), "3.8 获取用户的 Group 失败:" + getUserGroupsResponse); + Assertions.assertNotNull(userGroup.getUpdatedAt(), "3.9 获取用户的 Group 失败:" + getUserGroupsResponse); + + } catch (QiniuException e) { + fail(e); + } + } + + @Test + @Tag("IntegrationTest") + void testUsersPolicies() { + try { + ApiDeleteUser.Request deleteUserRequest = new ApiDeleteUser.Request(baseUrl, userAlias); + ApiDeleteUser deleteUserApi = new ApiDeleteUser(null, config); + deleteUserApi.request(deleteUserRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + ApiDeletePolicy.Request deleteRequest = new ApiDeletePolicy.Request(baseUrl, policyAlias); + ApiDeletePolicy deleteApi = new ApiDeletePolicy(null, config); + deleteApi.request(deleteRequest); + } catch (QiniuException e) { + } + + try { + ApiDeletePolicy.Request deleteRequest = new ApiDeletePolicy.Request(baseUrl, policyAlias + "New"); + ApiDeletePolicy deleteApi = new ApiDeletePolicy(null, config); + deleteApi.request(deleteRequest); + } catch (QiniuException e) { + } + + try { + ApiDeleteGroup.Request deleteGroupRequest = new ApiDeleteGroup.Request(baseUrl, groupAlias); + ApiDeleteGroup deleteGroupApi = new ApiDeleteGroup(null, config); + deleteGroupApi.request(deleteGroupRequest); + } catch (QiniuException e) { + // 删除失败时预期的 + } + + try { + // 0 创建用户 + ApiCreateUser.Request.CreateIamUserParam createUserParam = new ApiCreateUser.Request.CreateIamUserParam(); + createUserParam.setAlias(userAlias); + createUserParam.setPassword(userPWD); + ApiCreateUser.Request createUserRequest = new ApiCreateUser.Request(baseUrl, createUserParam); + ApiCreateUser createUserApi = new ApiCreateUser(null, config); + ApiCreateUser.Response createUserResponse = createUserApi.request(createUserRequest); + assertNotNull(createUserResponse, "0. 创建 User 失败:" + createUserResponse); + assertEquals(createUserResponse.isOK(), true, "0.1 创建 User 失败:" + createUserResponse); + + // 1 创建用户的 Policy + String policyDesc = policyAlias; + String policyAction = "cdn/DownloadCDNLog"; + String policyEffect = "Allow"; + String policyResource = "qrn:product:::/a/b/c.txt"; + ApiCreatePolicy.Request.CreateStatement createStatement = new ApiCreatePolicy.Request.CreateStatement(); + createStatement.setActions(new String[]{policyAction}); + createStatement.setEffect(policyEffect); + createStatement.setResources(new String[]{policyResource}); + ApiCreatePolicy.Request.CreatePolicyParam createPolicyRequestParam = new ApiCreatePolicy.Request.CreatePolicyParam(); + createPolicyRequestParam.setEditType(1); + createPolicyRequestParam.setAlias(policyAlias); + createPolicyRequestParam.setDescription(policyDesc); + createPolicyRequestParam.setStatement(new ApiCreatePolicy.Request.CreateStatement[]{createStatement}); + ApiCreatePolicy.Request createPolicyRequest = new ApiCreatePolicy.Request(baseUrl, createPolicyRequestParam); + ApiCreatePolicy createPolicyApi = new ApiCreatePolicy(null, config); + ApiCreatePolicy.Response createPolicyResponse = createPolicyApi.request(createPolicyRequest); + assertNotNull(createPolicyResponse, "1. 创建 Policy 失败:" + createPolicyResponse); + assertTrue(createPolicyResponse.isOK(), "1.1 创建 Policy 失败:" + createPolicyResponse); + + // 2 用户添加至 Policy + ApiModifyUserPolicies.Request.ModifiedIamUserPoliciesParam modifyUserPoliciesParam = new ApiModifyUserPolicies.Request.ModifiedIamUserPoliciesParam(); + modifyUserPoliciesParam.setPolicyAliases(new String[]{policyAlias}); + ApiModifyUserPolicies.Request modifyUserPoliciesRequest = new ApiModifyUserPolicies.Request(baseUrl, userAlias, modifyUserPoliciesParam); + ApiModifyUserPolicies modifyUserPoliciesApi = new ApiModifyUserPolicies(null, config); + ApiModifyUserPolicies.Response modifyUserPoliciesResponse = modifyUserPoliciesApi.request(modifyUserPoliciesRequest); + assertNotNull(modifyUserPoliciesResponse, "4. 更新用户添加的 Policy 失败:" + modifyUserPoliciesResponse); + assertTrue(modifyUserPoliciesResponse.isOK(), "4.1 更新用户添加的 Policy 失败:" + modifyUserPoliciesResponse); + + + // 3 获取用户 Policy + ApiGetUserPolicies.Request getUserPoliciesRequest = new ApiGetUserPolicies.Request(baseUrl, userAlias); + getUserPoliciesRequest.setPage(1); + getUserPoliciesRequest.setPageSize(1); + ApiGetUserPolicies getUserPoliciesApi = new ApiGetUserPolicies(null, config); + ApiGetUserPolicies.Response getUserPoliciesResponse = getUserPoliciesApi.request(getUserPoliciesRequest); + assertNotNull(getUserPoliciesResponse, "3 获取用户 Policy 失败:" + getUserPoliciesResponse); + assertTrue(getUserPoliciesResponse.isOK(), "3.1 获取用户 Policy 失败:" + getUserPoliciesResponse); + + ApiGetUserPolicies.Response.GetIamUserPolicy getUserPoliciesResponseData = getUserPoliciesResponse.getData().getData().getList()[0]; + assertNotNull(getUserPoliciesResponseData.getId(), "3.2 获取用户 Policy 失败:" + createPolicyResponse); + assertNotNull(getUserPoliciesResponseData.getRootUid(), "3.3 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getAlias(), policyAlias, "3.4 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getDescription(), policyDesc, "3.5 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getEnabled(), true, "3.6 获取用户 Policy 失败:" + createPolicyResponse); + assertNotNull(getUserPoliciesResponseData.getUpdatedAt(), "3.7 获取用户 Policy 失败:" + createPolicyResponse); + assertNotNull(getUserPoliciesResponseData.getCreatedAt(), "3.8 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getStatement().length, 1, "3.9 获取用户 Policy 失败:" + createPolicyResponse); + ApiGetUserPolicies.Response.Statement getUserPolicyResponseStatement = getUserPoliciesResponseData.getStatement()[0]; + assertEquals(getUserPolicyResponseStatement.getEffect(), policyEffect, "3.10 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPolicyResponseStatement.getActions()[0], policyAction, "3.11 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPolicyResponseStatement.getResources()[0], policyResource, "3.12 获取用户 Policy 失败:" + createPolicyResponse); + + // 4 创建 Policy + policyAlias = policyAlias + "New"; + policyDesc = policyDesc + "New"; + policyAction = "cdn/DownloadCDNLog"; + policyEffect = "Allow"; + policyResource = "qrn:product:::/a/b/c.txt"; + createStatement = new ApiCreatePolicy.Request.CreateStatement(); + createStatement.setActions(new String[]{policyAction}); + createStatement.setEffect(policyEffect); + createStatement.setResources(new String[]{policyResource}); + createPolicyRequestParam = new ApiCreatePolicy.Request.CreatePolicyParam(); + createPolicyRequestParam.setEditType(1); + createPolicyRequestParam.setAlias(policyAlias); + createPolicyRequestParam.setDescription(policyDesc); + createPolicyRequestParam.setStatement(new ApiCreatePolicy.Request.CreateStatement[]{createStatement}); + createPolicyRequest = new ApiCreatePolicy.Request(baseUrl, createPolicyRequestParam); + createPolicyApi = new ApiCreatePolicy(null, config); + createPolicyResponse = createPolicyApi.request(createPolicyRequest); + assertNotNull(createPolicyResponse, "1. 创建 Policy 失败:" + createPolicyResponse); + assertTrue(createPolicyResponse.isOK(), "1.1 创建 Policy 失败:" + createPolicyResponse); + + // 4 更新用户添加的 Policy + ApiUpdateUserPolicies.Request.UpdatedIamUserPoliciesParam updateUserPoliciesRequestParam = new ApiUpdateUserPolicies.Request.UpdatedIamUserPoliciesParam(); + updateUserPoliciesRequestParam.setPolicyAliases(new String[]{policyAlias}); + ApiUpdateUserPolicies.Request updateUserPoliciesRequest = new ApiUpdateUserPolicies.Request(baseUrl, userAlias, updateUserPoliciesRequestParam); + ApiUpdateUserPolicies updateUserPoliciesApi = new ApiUpdateUserPolicies(null, config); + ApiUpdateUserPolicies.Response updateUserPoliciesResponse = updateUserPoliciesApi.request(updateUserPoliciesRequest); + assertNotNull(updateUserPoliciesResponse, "2. 用户添加至 Policy 失败:" + updateUserPoliciesResponse); + assertTrue(updateUserPoliciesResponse.isOK(), "2.1 用户添加至 Policy 失败:" + updateUserPoliciesResponse); + + // 5 获取用户的 Policy(验证) + getUserPoliciesRequest = new ApiGetUserPolicies.Request(baseUrl, userAlias); + getUserPoliciesRequest.setPage(1); + getUserPoliciesRequest.setPageSize(1); + getUserPoliciesApi = new ApiGetUserPolicies(null, config); + getUserPoliciesResponse = getUserPoliciesApi.request(getUserPoliciesRequest); + assertNotNull(getUserPoliciesResponse, "5 获取用户 Policy 失败:" + getUserPoliciesResponse); + assertTrue(getUserPoliciesResponse.isOK(), "5.1 获取用户 Policy 失败:" + getUserPoliciesResponse); + + getUserPoliciesResponseData = getUserPoliciesResponse.getData().getData().getList()[0]; + assertNotNull(getUserPoliciesResponseData.getId(), "5.2 获取用户 Policy 失败:" + createPolicyResponse); + assertNotNull(getUserPoliciesResponseData.getRootUid(), "5.3 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getAlias(), policyAlias, "5.4 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getDescription(), policyDesc, "5.5 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getEnabled(), true, "5.6 获取用户 Policy 失败:" + createPolicyResponse); + assertNotNull(getUserPoliciesResponseData.getUpdatedAt(), "5.7 获取用户 Policy 失败:" + createPolicyResponse); + assertNotNull(getUserPoliciesResponseData.getCreatedAt(), "5.8 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPoliciesResponseData.getStatement().length, 1, "5.9 获取用户 Policy 失败:" + createPolicyResponse); + getUserPolicyResponseStatement = getUserPoliciesResponseData.getStatement()[0]; + assertEquals(getUserPolicyResponseStatement.getEffect(), policyEffect, "5.10 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPolicyResponseStatement.getActions()[0], policyAction, "5.11 获取用户 Policy 失败:" + createPolicyResponse); + assertEquals(getUserPolicyResponseStatement.getResources()[0], policyResource, "5.12 获取用户 Policy 失败:" + createPolicyResponse); + + // 6 删除用户的 Policy + ApiDeleteUserPolicy.Request.DeletedIamUserPoliciesParam deleteUserPolicyRequestParam = new ApiDeleteUserPolicy.Request.DeletedIamUserPoliciesParam(); + deleteUserPolicyRequestParam.setPolicyAliases(new String[]{policyAlias}); + ApiDeleteUserPolicy.Request deleteUserPolicyRequest = new ApiDeleteUserPolicy.Request(baseUrl, userAlias, deleteUserPolicyRequestParam); + ApiDeleteUserPolicy deleteUserPolicyApi = new ApiDeleteUserPolicy(null, config); + ApiDeleteUserPolicy.Response deleteUserPolicyResponse = deleteUserPolicyApi.request(deleteUserPolicyRequest); + assertNotNull(getUserPoliciesResponse, "6 获取用户 Policy 失败:" + getUserPoliciesResponse); + assertTrue(getUserPoliciesResponse.isOK(), "6.1 获取用户 Policy 失败:" + getUserPoliciesResponse); + + // 7 获取用户的 Policy(验证) + getUserPoliciesRequest = new ApiGetUserPolicies.Request(baseUrl, userAlias); + getUserPoliciesRequest.setPage(1); + getUserPoliciesRequest.setPageSize(1); + getUserPoliciesApi = new ApiGetUserPolicies(null, config); + getUserPoliciesResponse = getUserPoliciesApi.request(getUserPoliciesRequest); + assertNotNull(getUserPoliciesResponse, "7 获取用户 Policy 失败:" + getUserPoliciesResponse); + assertTrue(getUserPoliciesResponse.isOK(), "7.1 获取用户 Policy 失败:" + getUserPoliciesResponse); + assertEquals(0, (int) getUserPoliciesResponse.getData().getData().getCount(), "7.2 获取用户 Policy 失败:" + getUserPoliciesResponse); + + // 8 获取用户的 Service + ApiGetUserAvailableServices.Request getUserAvailableServicesRequest = new ApiGetUserAvailableServices.Request(baseUrl, userAlias); + ApiGetUserAvailableServices getUserAvailableServicesApi = new ApiGetUserAvailableServices(null, config); + ApiGetUserAvailableServices.Response getUserAvailableServicesResponse = getUserAvailableServicesApi.request(getUserAvailableServicesRequest); + assertNotNull(getUserAvailableServicesResponse, "8 获取用户的 Service 失败:" + getUserAvailableServicesResponse); + assertTrue(getUserAvailableServicesResponse.isOK(), "8.1 获取用户的 Service 失败:" + getUserAvailableServicesResponse); + assertNotNull(getUserAvailableServicesResponse.getData().getData(), "8.2 获取用户的 Service 失败:" + getUserPoliciesResponse); + + // 9 列举子用户指定服务操作下的可访问资源 + String service = "cdn"; + String actionAlias = "DownloadCDNLog"; + ApiGetUserServiceActionResources.Request getUserServiceActionResourcesRequest = new ApiGetUserServiceActionResources.Request(baseUrl, userAlias, service, actionAlias); + ApiGetUserServiceActionResources getUserServiceActionResourcesApi = new ApiGetUserServiceActionResources(null, config); + ApiGetUserServiceActionResources.Response getUserServiceActionResourcesResponse = getUserServiceActionResourcesApi.request(getUserServiceActionResourcesRequest); + assertNotNull(getUserServiceActionResourcesResponse, "9 列举子用户指定服务操作下的可访问资源失败:" + getUserServiceActionResourcesResponse); + assertTrue(getUserServiceActionResourcesResponse.isOK(), "9.1 列举子用户指定服务操作下的可访问资源失败:" + getUserServiceActionResourcesResponse); + + ApiGetUserServiceActionResources.Response.GetIamUserServiceActionResources getUserServiceActionResources = getUserServiceActionResourcesResponse.getData().getData(); + assertNotNull(getUserServiceActionResources, "9.2 列举子用户指定服务操作下的可访问资源失败:" + getUserServiceActionResourcesResponse); + assertNotNull(getUserServiceActionResources.getAllowedResources(), "9.3 列举子用户指定服务操作下的可访问资源失败:" + getUserServiceActionResourcesResponse); + assertNotNull(getUserServiceActionResources.getDeniedResources(), "9.4 列举子用户指定服务操作下的可访问资源失败:" + getUserServiceActionResourcesResponse); + + + } catch (QiniuException e) { + fail(e); + } + } +} diff --git a/src/test/java/com/qiniu/storage/FixBlockUploaderWithRecorderTest.java b/src/test/java/com/qiniu/storage/FixBlockUploaderWithRecorderTest.java index 55d12b312..754f364ba 100644 --- a/src/test/java/com/qiniu/storage/FixBlockUploaderWithRecorderTest.java +++ b/src/test/java/com/qiniu/storage/FixBlockUploaderWithRecorderTest.java @@ -8,19 +8,21 @@ import com.qiniu.util.EtagV2; import com.qiniu.util.StringMap; import com.qiniu.util.UrlSafeBase64; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import test.com.qiniu.TempFile; import test.com.qiniu.TestConfig; -import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.File; import java.io.IOException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; import java.nio.charset.Charset; import java.util.Date; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class FixBlockUploaderWithRecorderTest { int blockSize = 1024 * 1024 * 8; Configuration config; @@ -85,12 +87,12 @@ public void breakThenUpload6() throws IOException { } public void breakThenUpload(ExecutorService pool1, ExecutorService pool2, ExecutorService pool3, int upSecondsTime1, - int upSecondsTime2) throws IOException { + int upSecondsTime2) throws IOException { breakThenUpload(pool1, pool2, pool3, upSecondsTime1, upSecondsTime2, 8); } public void breakThenUpload(final ExecutorService pool1, final ExecutorService pool2, final ExecutorService pool3, - int upSecondsTime1, int upSecondsTime2, final int maxRunningBlock) throws IOException { + int upSecondsTime1, int upSecondsTime2, final int maxRunningBlock) throws IOException { final long size = 1024 * 53 + 1039; final String expectKey = "\r\n?&r=" + size + "k" + System.currentTimeMillis(); final File f = TempFile.createFileOld(size); @@ -124,7 +126,7 @@ public void run() { // 显示断点记录文件 Thread showRecord = new Thread() { public void run() { - for (;;) { + for (; ; ) { doSleep(1000); showRecord("normal: " + size + " :", recorder, recordKey); } @@ -233,7 +235,7 @@ public void run() { } private void upload(int idx, FixBlockUploader.FileBlockData fbd, String token, String expectKey, - final ExecutorService pool, int maxRunningBlock, final AtomicBoolean tFinished, String etag) { + final ExecutorService pool, int maxRunningBlock, final AtomicBoolean tFinished, String etag) { try { System.out.println("------ start " + idx + ", " + new Date()); Response r = up.upload(fbd, new FixBlockUploader.StaticToken(token), expectKey, null, pool, @@ -281,7 +283,7 @@ class UploadRecordHelper { String recordFileKey; UploadRecordHelper(Recorder recorder, String bucket, String base64Key, String contentUUID, - String uploaderSUID) { + String uploaderSUID) { if (recorder != null) { this.recorder = recorder; recordFileKey = recorder.recorderKeyGenerate(bucket, base64Key, contentUUID, uploaderSUID); diff --git a/src/test/java/com/qiniu/storage/RegionTest.java b/src/test/java/com/qiniu/storage/RegionTest.java index 7f288f2e9..d56007240 100644 --- a/src/test/java/com/qiniu/storage/RegionTest.java +++ b/src/test/java/com/qiniu/storage/RegionTest.java @@ -4,20 +4,16 @@ import com.qiniu.common.QiniuException; import com.qiniu.common.Zone; import com.qiniu.util.Auth; -import test.com.qiniu.ResCode; -import test.com.qiniu.TestConfig; - import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import test.com.qiniu.ResCode; +import test.com.qiniu.TestConfig; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import static org.junit.jupiter.api.Assertions.*; + public class RegionTest { @Test diff --git a/src/test/java/test/com/qiniu/CdnTest.java b/src/test/java/test/com/qiniu/CdnTest.java index b5dbc6f14..32e9d5244 100644 --- a/src/test/java/test/com/qiniu/CdnTest.java +++ b/src/test/java/test/com/qiniu/CdnTest.java @@ -8,12 +8,12 @@ import com.qiniu.util.StringMap; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; + import java.net.URL; import java.util.Calendar; +import static org.junit.jupiter.api.Assertions.*; + /** * Created by bailong on 16/09/21. Updated by panyuan on 19/03/07 */ @@ -61,7 +61,7 @@ public void testRefresh() { CdnManager c = new CdnManager(TestConfig.testAuth); CdnResult.RefreshResult r; try { - r = c.refreshUrls(new String[] { TestConfig.testUrl_z0 }); + r = c.refreshUrls(new String[]{TestConfig.testUrl_z0}); assertEquals(200, r.code, msg); } catch (QiniuException e) { e.printStackTrace(); @@ -78,7 +78,7 @@ public void testPrefetch() { CdnManager c = new CdnManager(TestConfig.testAuth); CdnResult.PrefetchResult r; try { - r = c.prefetchUrls(new String[] { TestConfig.testUrl_na0 }); + r = c.prefetchUrls(new String[]{TestConfig.testUrl_na0}); assertEquals(200, r.code); } catch (QiniuException e) { e.printStackTrace(); @@ -96,7 +96,7 @@ public void testGetBandwidth() { CdnManager c = new CdnManager(TestConfig.testAuth); CdnResult.BandwidthResult r = null; - String[] domains = { TestConfig.testDomain_z0 }; + String[] domains = {TestConfig.testDomain_z0}; String startDate = getDate(3); String endDate = getDate(1); String granularity = "day"; @@ -119,7 +119,7 @@ public void testGetFlux() { CdnManager c = new CdnManager(TestConfig.testAuth); CdnResult.FluxResult r = null; - String[] domains = { TestConfig.testDomain_z0 }; + String[] domains = {TestConfig.testDomain_z0}; String startDate = getDate(3); String endDate = getDate(1); String granularity = "day"; @@ -142,7 +142,7 @@ public void testGetCdnLogList() { CdnManager c = new CdnManager(TestConfig.testAuth); CdnResult.LogListResult r = null; - String[] domains = { TestConfig.testDomain_z0 }; + String[] domains = {TestConfig.testDomain_z0}; String logDate = getDate(2); try { diff --git a/src/test/java/test/com/qiniu/DnsTest.java b/src/test/java/test/com/qiniu/DnsTest.java index 8eb61e12b..864e74d83 100644 --- a/src/test/java/test/com/qiniu/DnsTest.java +++ b/src/test/java/test/com/qiniu/DnsTest.java @@ -4,20 +4,21 @@ import com.qiniu.http.Dns; import com.qiniu.storage.Configuration; import com.qiniu.storage.UploadManager; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import qiniu.happydns.DnsClient; import qiniu.happydns.Domain; import qiniu.happydns.IResolver; import qiniu.happydns.local.Resolver; import qiniu.happydns.local.SystemDnsServer; + import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; // example public class DnsTest { diff --git a/src/test/java/test/com/qiniu/HttpTest.java b/src/test/java/test/com/qiniu/HttpTest.java index b90f5585a..45703884b 100644 --- a/src/test/java/test/com/qiniu/HttpTest.java +++ b/src/test/java/test/com/qiniu/HttpTest.java @@ -9,15 +9,13 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; + import java.lang.reflect.Field; import java.util.Date; import java.util.concurrent.TimeUnit; +import static org.junit.jupiter.api.Assertions.*; + public class HttpTest { private Client httpManager = new Client(); diff --git a/src/test/java/test/com/qiniu/ResCode.java b/src/test/java/test/com/qiniu/ResCode.java index d364a3d5b..00b1bd7d5 100644 --- a/src/test/java/test/com/qiniu/ResCode.java +++ b/src/test/java/test/com/qiniu/ResCode.java @@ -1,9 +1,11 @@ package test.com.qiniu; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; + import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + public class ResCode { public static boolean find(int code, int... codes) { System.out.println("response code is: " + code + ", possible code is in: " + Arrays.toString(codes)); @@ -21,7 +23,7 @@ public static int[] getPossibleResCode(int... codes) { @Test public void testAddCode() { - assertArrayEquals(new int[] { 401 }, ResCode.getPossibleResCode(401)); + assertArrayEquals(new int[]{401}, ResCode.getPossibleResCode(401)); } } diff --git a/src/test/java/test/com/qiniu/linking/DeviceTest.java b/src/test/java/test/com/qiniu/linking/DeviceTest.java index 392c8282d..99e9f3c68 100644 --- a/src/test/java/test/com/qiniu/linking/DeviceTest.java +++ b/src/test/java/test/com/qiniu/linking/DeviceTest.java @@ -7,13 +7,15 @@ import com.qiniu.linking.model.*; import com.qiniu.util.Auth; import com.qiniu.util.StringMap; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import test.com.qiniu.TestConfig; + +import java.util.Date; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import java.util.Date; public class DeviceTest { @@ -61,7 +63,7 @@ public void testDevice() throws QiniuException { { // 修改设备字段 - PatchOperation[] operations = { new PatchOperation("replace", "segmentExpireDays", 9) }; + PatchOperation[] operations = {new PatchOperation("replace", "segmentExpireDays", 9)}; Device device = deviceManager.updateDevice(testAppid, testDeviceName1, operations); assertEquals(device.getSegmentExpireDays(), 9); } diff --git a/src/test/java/test/com/qiniu/processing/PfopTest.java b/src/test/java/test/com/qiniu/processing/PfopTest.java index bf75df024..914ef1861 100644 --- a/src/test/java/test/com/qiniu/processing/PfopTest.java +++ b/src/test/java/test/com/qiniu/processing/PfopTest.java @@ -8,6 +8,7 @@ import com.qiniu.storage.Configuration; import com.qiniu.storage.Region; import com.qiniu.util.Auth; +import com.qiniu.util.StringMap; import com.qiniu.util.StringUtils; import com.qiniu.util.UrlSafeBase64; import org.junit.jupiter.api.Tag; @@ -17,11 +18,7 @@ import java.util.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; public class PfopTest { @@ -60,7 +57,7 @@ public void testPfop() throws QiniuException { System.out.println(fops); try { - String jobid = operationManager.pfop(bucket, TestConfig.testMp4FileKey, fops, null, notifyURL, force); + String jobid = operationManager.pfop(bucket, TestConfig.testMp4FileKey, fops, "", notifyURL, force); assertNotNull(jobid); assertNotEquals("", jobid); ids.add(jobid); @@ -169,4 +166,39 @@ void testPfopWithType() { assertTrue(ResCode.find(ex.code(), ResCode.getPossibleResCode(612))); } } + + // @Test + // @Tag("IntegrationTest") + void testPfopWithTemplate() { + try { + Auth auth = TestConfig.testAuth; + Map bucketKeyMap = new HashMap(); + TestConfig.TestFile[] files = TestConfig.getTestFileArray(); + for (TestConfig.TestFile testFile : files) { + bucketKeyMap.put(testFile.getBucketName(), testFile.getRegion()); + } + + String templateId = "java-sdk-test-template"; + for (Map.Entry entry : bucketKeyMap.entrySet()) { + String bucket = entry.getKey(); + Region region = entry.getValue(); + + Configuration cfg = new Configuration(region); + OperationManager operationManager = new OperationManager(auth, cfg); + StringMap params = new StringMap(); + params.put("persistentWorkflowTemplateID", templateId); + String jobID = operationManager.pfop(bucket, TestConfig.testMp4FileKey, params); + + OperationStatus status = operationManager.prefop(bucket, jobID); + assertNotNull(status, "1. prefop type error"); + assertNotNull(status.creationDate, "1. prefop type error"); + assertTrue(status.code == 0 || status.code == 1 || status.code == 3, "2. prefop type error"); + assertNotNull(status.taskFrom, "34. prefop type error"); + } + + } catch (QiniuException ex) { + ex.printStackTrace(); + assertTrue(ResCode.find(ex.code(), ResCode.getPossibleResCode(612))); + } + } } diff --git a/src/test/java/test/com/qiniu/qvs/DeviceManagerTest.java b/src/test/java/test/com/qiniu/qvs/DeviceManagerTest.java index 9b3d5bd16..2ed77de9a 100644 --- a/src/test/java/test/com/qiniu/qvs/DeviceManagerTest.java +++ b/src/test/java/test/com/qiniu/qvs/DeviceManagerTest.java @@ -1,8 +1,5 @@ package test.com.qiniu.qvs; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - import com.qiniu.common.QiniuException; import com.qiniu.http.Response; import com.qiniu.qvs.DeviceManager; @@ -13,14 +10,17 @@ import org.junit.jupiter.api.Test; import test.com.qiniu.TestConfig; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class DeviceManagerTest { + private final String namespaceId = "3nm4x1e0xw855"; + private final String gbId = "31011500991320007536"; + private final String[] channels = {"31011500991320007536"}; Auth auth = TestConfig.testAuth; private DeviceManager deviceManager; private Response res = null; private Response res2 = null; - private final String namespaceId = "3nm4x1e0xw855"; - private final String gbId = "31011500991320007536"; - private final String[] channels = {"31011500991320007536"}; @BeforeEach public void setUp() throws Exception { diff --git a/src/test/java/test/com/qiniu/qvs/NameSpaceTest.java b/src/test/java/test/com/qiniu/qvs/NameSpaceTest.java index eb3284f32..cf5f536b6 100644 --- a/src/test/java/test/com/qiniu/qvs/NameSpaceTest.java +++ b/src/test/java/test/com/qiniu/qvs/NameSpaceTest.java @@ -5,18 +5,18 @@ import com.qiniu.qvs.NameSpaceManager; import com.qiniu.qvs.model.PatchOperation; import com.qiniu.util.Auth; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import test.com.qiniu.TestConfig; public class NameSpaceTest { + private final String namespaceId = "3nm4x1e0xw855"; + private final String name = "" + System.currentTimeMillis(); Auth auth = TestConfig.testAuth; private NameSpaceManager nameSpaceManager; private Response res = null; private Response res2 = null; - private final String namespaceId = "3nm4x1e0xw855"; - private final String name = "" + System.currentTimeMillis(); @BeforeEach public void setUp() throws Exception { @@ -62,7 +62,7 @@ public void testQueryNameSpace() { @Test @Tag("IntegrationTest") public void testUpdateNameSpace() { - PatchOperation[] patchOperation = { new PatchOperation("replace", "recordTemplateApplyAll", true) }; + PatchOperation[] patchOperation = {new PatchOperation("replace", "recordTemplateApplyAll", true)}; try { res = nameSpaceManager.updateNameSpace(namespaceId, patchOperation); System.out.println(res.bodyString()); diff --git a/src/test/java/test/com/qiniu/qvs/PTZTest.java b/src/test/java/test/com/qiniu/qvs/PTZTest.java index 16d139104..27b9e0432 100644 --- a/src/test/java/test/com/qiniu/qvs/PTZTest.java +++ b/src/test/java/test/com/qiniu/qvs/PTZTest.java @@ -3,16 +3,16 @@ import com.qiniu.http.Response; import com.qiniu.qvs.PTZManager; import com.qiniu.util.Auth; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.BeforeEach; +import test.com.qiniu.TestConfig; public class PTZTest { - Auth auth = TestConfig.testAuth; - private PTZManager ptzManager; - private Response res = null; private final String namespaceId = "3nm4x1e0xw855"; private final String gbId = "31011500991320007536"; private final String chId = ""; + Auth auth = TestConfig.testAuth; + private PTZManager ptzManager; + private Response res = null; private String name = "" + System.currentTimeMillis(); @BeforeEach diff --git a/src/test/java/test/com/qiniu/qvs/RecordTest.java b/src/test/java/test/com/qiniu/qvs/RecordTest.java index addf53318..fd514a9e9 100644 --- a/src/test/java/test/com/qiniu/qvs/RecordTest.java +++ b/src/test/java/test/com/qiniu/qvs/RecordTest.java @@ -3,19 +3,19 @@ import com.qiniu.http.Response; import com.qiniu.qvs.RecordManager; import com.qiniu.util.Auth; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.BeforeEach; +import test.com.qiniu.TestConfig; public class RecordTest { - Auth auth = TestConfig.testAuth; - private RecordManager recordManager; - private Response res = null; - private Response res2 = null; private final String namespaceId = "3nm4x1e0xw855"; private final String streamId = "31011500991320007536"; private final String format = "m3u8"; private final int start = 1640599830; private final int end = 1640600430; + Auth auth = TestConfig.testAuth; + private RecordManager recordManager; + private Response res = null; + private Response res2 = null; @BeforeEach public void setUp() throws Exception { diff --git a/src/test/java/test/com/qiniu/qvs/StatsTest.java b/src/test/java/test/com/qiniu/qvs/StatsTest.java index 7642875f0..e58008cd2 100644 --- a/src/test/java/test/com/qiniu/qvs/StatsTest.java +++ b/src/test/java/test/com/qiniu/qvs/StatsTest.java @@ -7,14 +7,14 @@ import test.com.qiniu.TestConfig; public class StatsTest { - Auth auth = TestConfig.testAuth; - private StatsManager statsManager; - private Response res = null; private final String namespaceId = ""; private final String streamId = ""; private final String tu = "5min"; private final int start = 20200901; private final int end = 20200902; + Auth auth = TestConfig.testAuth; + private StatsManager statsManager; + private Response res = null; @BeforeEach public void setUp() throws Exception { diff --git a/src/test/java/test/com/qiniu/qvs/StreamTest.java b/src/test/java/test/com/qiniu/qvs/StreamTest.java index 305370247..6687df738 100644 --- a/src/test/java/test/com/qiniu/qvs/StreamTest.java +++ b/src/test/java/test/com/qiniu/qvs/StreamTest.java @@ -4,19 +4,12 @@ import com.qiniu.qvs.StreamManager; import com.qiniu.qvs.model.Stream; import com.qiniu.util.Auth; - import org.junit.jupiter.api.BeforeEach; import test.com.qiniu.TestConfig; public class StreamTest { - Auth auth = TestConfig.testAuth; private final String streamid = "" + System.currentTimeMillis(); - Stream stream = new Stream("31011500991320007536"); - Stream createstream = new Stream(streamid); - private StreamManager streamManager; - private Response res = null; - private Response res2 = null; private final String namespaceId = "3nm4x1e0xw855"; private final int start = 1639379380; private final int end = 1639379981; @@ -25,6 +18,12 @@ public class StreamTest { private final int qtype = 0; private final String maker = ""; private final String format = ""; + Auth auth = TestConfig.testAuth; + Stream stream = new Stream("31011500991320007536"); + Stream createstream = new Stream(streamid); + private StreamManager streamManager; + private Response res = null; + private Response res2 = null; @BeforeEach public void setUp() throws Exception { diff --git a/src/test/java/test/com/qiniu/qvs/TemplateTest.java b/src/test/java/test/com/qiniu/qvs/TemplateTest.java index d3aa5b86e..2b0e083db 100644 --- a/src/test/java/test/com/qiniu/qvs/TemplateTest.java +++ b/src/test/java/test/com/qiniu/qvs/TemplateTest.java @@ -8,10 +8,10 @@ public class TemplateTest { + private final String templateId = "2xenzwlwgi7mf"; Auth auth = TestConfig.testAuth; private TemplateManager templateManager; private Response res = null; - private final String templateId = "2xenzwlwgi7mf"; private String templateName = "" + System.currentTimeMillis(); @BeforeEach diff --git a/src/test/java/test/com/qiniu/rtc/MergeServiceV4Test.java b/src/test/java/test/com/qiniu/rtc/MergeServiceV4Test.java index fbbe4a514..12da24b6e 100644 --- a/src/test/java/test/com/qiniu/rtc/MergeServiceV4Test.java +++ b/src/test/java/test/com/qiniu/rtc/MergeServiceV4Test.java @@ -2,7 +2,6 @@ import com.qiniu.rtc.QRTC; import com.qiniu.rtc.QRTCClient; - import org.junit.jupiter.api.BeforeAll; import test.com.qiniu.TestConfig; diff --git a/src/test/java/test/com/qiniu/rtc/RtcTest.java b/src/test/java/test/com/qiniu/rtc/RtcTest.java index 46325222c..1877c3338 100644 --- a/src/test/java/test/com/qiniu/rtc/RtcTest.java +++ b/src/test/java/test/com/qiniu/rtc/RtcTest.java @@ -29,6 +29,18 @@ public static void initQRTC() throws QiniuException { client = QRTC.init(TestConfig.testAccessKey, TestConfig.testSecretKey, result.getResult().getAppId()); } + /** + * 最后清除创建的app数据 + * + * @throws QiniuException + */ + @Disabled + @AfterAll + public static void deleteApp() throws QiniuException { + QRTCResult result = client.deleteApp(); + assert result.getCode() == 200; + } + @Disabled @Test public void testApp() throws QiniuException { @@ -161,17 +173,4 @@ public void testMerge() throws QiniuException { assert stopResult.getCode() == 200; } - - /** - * 最后清除创建的app数据 - * - * @throws QiniuException - */ - @Disabled - @AfterAll - public static void deleteApp() throws QiniuException { - QRTCResult result = client.deleteApp(); - assert result.getCode() == 200; - } - } diff --git a/src/test/java/test/com/qiniu/sms/SmsTest.java b/src/test/java/test/com/qiniu/sms/SmsTest.java index a41054c1e..0b2d44aaf 100644 --- a/src/test/java/test/com/qiniu/sms/SmsTest.java +++ b/src/test/java/test/com/qiniu/sms/SmsTest.java @@ -26,7 +26,7 @@ public class SmsTest { private SmsManager smsManager; private String mobile = ""; // 一国内手机号 - private String[] mobiles = new String[] { mobile }; + private String[] mobiles = new String[]{mobile}; /** * 初始化 @@ -133,7 +133,7 @@ public void testDescribeSignatureItems() { public void testCreateSignature() { try { Response response = smsManager.createSignature("signature", "app", - new String[] { "data:image/gif;base64,xxxxxxxxxx" }); + new String[]{"data:image/gif;base64,xxxxxxxxxx"}); assertNotNull(response); } catch (QiniuException e) { assertTrue(ResCode.find(e.code(), ResCode.getPossibleResCode(401))); diff --git a/src/test/java/test/com/qiniu/storage/ApiUploadV1Test.java b/src/test/java/test/com/qiniu/storage/ApiUploadV1Test.java index 9825ae539..012699c92 100644 --- a/src/test/java/test/com/qiniu/storage/ApiUploadV1Test.java +++ b/src/test/java/test/com/qiniu/storage/ApiUploadV1Test.java @@ -15,7 +15,10 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.junit.jupiter.api.Assertions.*; diff --git a/src/test/java/test/com/qiniu/storage/ApiUploadV2Test.java b/src/test/java/test/com/qiniu/storage/ApiUploadV2Test.java index dc336084b..13cb24136 100644 --- a/src/test/java/test/com/qiniu/storage/ApiUploadV2Test.java +++ b/src/test/java/test/com/qiniu/storage/ApiUploadV2Test.java @@ -5,10 +5,10 @@ import com.qiniu.storage.*; import com.qiniu.util.Md5; import com.qiniu.util.StringMap; -import test.com.qiniu.TempFile; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import test.com.qiniu.TempFile; +import test.com.qiniu.TestConfig; import java.io.ByteArrayInputStream; import java.io.File; diff --git a/src/test/java/test/com/qiniu/storage/BucketTest2.java b/src/test/java/test/com/qiniu/storage/BucketTest2.java index 8721b2837..4f97c5a88 100644 --- a/src/test/java/test/com/qiniu/storage/BucketTest2.java +++ b/src/test/java/test/com/qiniu/storage/BucketTest2.java @@ -18,19 +18,13 @@ import test.com.qiniu.ResCode; import test.com.qiniu.TestConfig; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.io.ByteArrayInputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.*; +import static org.junit.jupiter.api.Assertions.*; + public class BucketTest2 { List batchStatusCode = Arrays.asList(200, 298); diff --git a/src/test/java/test/com/qiniu/storage/DownloadUrlTest.java b/src/test/java/test/com/qiniu/storage/DownloadUrlTest.java index d3e310e75..99262de66 100644 --- a/src/test/java/test/com/qiniu/storage/DownloadUrlTest.java +++ b/src/test/java/test/com/qiniu/storage/DownloadUrlTest.java @@ -11,17 +11,13 @@ import org.junit.jupiter.api.Test; import test.com.qiniu.TestConfig; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.net.URLEncoder; import java.util.Date; import java.util.HashMap; import java.util.Map; +import static org.junit.jupiter.api.Assertions.*; + public class DownloadUrlTest { @Test diff --git a/src/test/java/test/com/qiniu/storage/FixBlockUploaderTest.java b/src/test/java/test/com/qiniu/storage/FixBlockUploaderTest.java index b02e4f1a9..c9bfc16b6 100644 --- a/src/test/java/test/com/qiniu/storage/FixBlockUploaderTest.java +++ b/src/test/java/test/com/qiniu/storage/FixBlockUploaderTest.java @@ -10,20 +10,19 @@ import com.qiniu.storage.Region; import com.qiniu.util.EtagV2; import com.qiniu.util.StringMap; -import test.com.qiniu.TempFile; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import test.com.qiniu.TempFile; import test.com.qiniu.TestConfig; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Date; +import static org.junit.jupiter.api.Assertions.*; + public class FixBlockUploaderTest { int blockSize = 1024 * 1021 * 7; Configuration config; diff --git a/src/test/java/test/com/qiniu/storage/FormUploadTest.java b/src/test/java/test/com/qiniu/storage/FormUploadTest.java index 86074ab2e..3e1e25d1f 100644 --- a/src/test/java/test/com/qiniu/storage/FormUploadTest.java +++ b/src/test/java/test/com/qiniu/storage/FormUploadTest.java @@ -5,18 +5,14 @@ import com.qiniu.processing.OperationManager; import com.qiniu.processing.OperationStatus; import com.qiniu.storage.Configuration; +import com.qiniu.storage.Region; import com.qiniu.storage.UpCompletionHandler; import com.qiniu.storage.UploadManager; import com.qiniu.util.StringMap; -import test.com.qiniu.TempFile; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import test.com.qiniu.TempFile; +import test.com.qiniu.TestConfig; import java.io.File; import java.io.FileInputStream; @@ -25,6 +21,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.junit.jupiter.api.Assertions.*; + public class FormUploadTest { UploadManager uploadManager = new UploadManager(new Configuration()); @@ -93,6 +91,56 @@ public void testSimple() { } } + @Test + @Tag("IntegrationTest") + public void testEmptyUploadHosts() { + Region region = new Region.Builder() + .srcUpHost(null) + .accUpHost(null) + .build(); + Configuration config = new Configuration(region); + UploadManager uploadManager = new UploadManager(config); + try { + String key = "empty_upload_hosts"; + String token = TestConfig.testAuth.uploadToken(TestConfig.testBucket_na0, key); + Response response = uploadManager.put("".getBytes(), key, token, null, "", true); + } catch (QiniuException e) { + e.printStackTrace(); + } catch (Exception e) { + fail(e); + } + + region = new Region.Builder() + .srcUpHost("aaa") + .build(); + config = new Configuration(region); + uploadManager = new UploadManager(config); + try { + String key = "empty_upload_hosts"; + String token = TestConfig.testAuth.uploadToken(TestConfig.testBucket_na0, key); + Response response = uploadManager.put("".getBytes(), key, token, null, "", true); + } catch (QiniuException e) { + e.printStackTrace(); + } catch (Exception e) { + fail(e); + } + + region = new Region.Builder() + .accUpHost("aaa") + .build(); + config = new Configuration(region); + uploadManager = new UploadManager(config); + try { + String key = "empty_upload_hosts"; + String token = TestConfig.testAuth.uploadToken(TestConfig.testBucket_na0, key); + Response response = uploadManager.put("".getBytes(), key, token, null, "", true); + } catch (QiniuException e) { + e.printStackTrace(); + } catch (Exception e) { + fail(e); + } + } + @Test @Tag("IntegrationTest") public void testSyncRetry() { diff --git a/src/test/java/test/com/qiniu/storage/RecordUploadTest.java b/src/test/java/test/com/qiniu/storage/RecordUploadTest.java index a38942b63..06c664ea4 100644 --- a/src/test/java/test/com/qiniu/storage/RecordUploadTest.java +++ b/src/test/java/test/com/qiniu/storage/RecordUploadTest.java @@ -9,12 +9,11 @@ import com.qiniu.storage.ResumeUploader; import com.qiniu.storage.persistent.FileRecorder; import com.qiniu.util.Etag; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import test.com.qiniu.TempFile; import test.com.qiniu.TestConfig; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; + import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -23,23 +22,20 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; /** * Created by Simon on 2015/3/30. */ public class RecordUploadTest { + private static boolean[][] testConfigList = { + // isResumeV2, isConcurrent + {true, false}, {true, true}, {false, false}, {false, true}}; final Random r = new Random(); - final Client client = new Client(); FileRecorder recorder = null; private Response response = null; - private static boolean[][] testConfigList = { - // isResumeV2, isConcurrent - { true, false }, { true, true }, { false, false }, { false, true } }; - /** * 断点续传 * @@ -294,6 +290,10 @@ public void testLastModify() throws IOException { assertTrue(m4 > m1); } + static class Complete { + AtomicBoolean isComplete = new AtomicBoolean(false); + } + class Up { private final File file; private final String key; @@ -358,8 +358,4 @@ public Response up(Region region) throws Exception { } } } - - static class Complete { - AtomicBoolean isComplete = new AtomicBoolean(false); - } } diff --git a/src/test/java/test/com/qiniu/storage/RegionGroupTest.java b/src/test/java/test/com/qiniu/storage/RegionGroupTest.java index 4f50d5120..769f4bf70 100644 --- a/src/test/java/test/com/qiniu/storage/RegionGroupTest.java +++ b/src/test/java/test/com/qiniu/storage/RegionGroupTest.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertNotSame; public class RegionGroupTest { diff --git a/src/test/java/test/com/qiniu/storage/RegionTest.java b/src/test/java/test/com/qiniu/storage/RegionTest.java index 9a63b3ef4..e6b7aa0c2 100644 --- a/src/test/java/test/com/qiniu/storage/RegionTest.java +++ b/src/test/java/test/com/qiniu/storage/RegionTest.java @@ -1,5 +1,6 @@ package test.com.qiniu.storage; +import com.qiniu.common.QiniuException; import com.qiniu.storage.Region; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -20,7 +21,7 @@ public void testCreateWithRegionId() throws Exception { Constructor regionReqInfoConstructor = regionReqInfoClass.getDeclaredConstructor(String.class, String.class); regionReqInfoConstructor.setAccessible(true); - Object info = regionReqInfoConstructor.newInstance("a", "b"); + Object info = regionReqInfoConstructor.newInstance("a", "b"); Region na0 = Region.createWithRegionId("na0"); // region id diff --git a/src/test/java/test/com/qiniu/storage/ResumeUploadTest.java b/src/test/java/test/com/qiniu/storage/ResumeUploadTest.java index 505539d1d..c6ebc223d 100644 --- a/src/test/java/test/com/qiniu/storage/ResumeUploadTest.java +++ b/src/test/java/test/com/qiniu/storage/ResumeUploadTest.java @@ -9,23 +9,19 @@ import com.qiniu.util.Etag; import com.qiniu.util.Md5; import com.qiniu.util.StringMap; - import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import test.com.qiniu.TempFile; import test.com.qiniu.TestConfig; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import java.util.Date; +import static org.junit.jupiter.api.Assertions.*; + public class ResumeUploadTest { // private static boolean[][] TestConfigList = { diff --git a/src/test/java/test/com/qiniu/storage/StreamUploadTest.java b/src/test/java/test/com/qiniu/storage/StreamUploadTest.java index b72b55d63..47a4bc560 100644 --- a/src/test/java/test/com/qiniu/storage/StreamUploadTest.java +++ b/src/test/java/test/com/qiniu/storage/StreamUploadTest.java @@ -9,21 +9,21 @@ import com.qiniu.storage.UploadManager; import com.qiniu.util.Etag; import com.qiniu.util.StringMap; -import test.com.qiniu.TempFile; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import test.com.qiniu.TempFile; import test.com.qiniu.TestConfig; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + /** * Created by long on 2016/11/4. */ diff --git a/src/test/java/test/com/qiniu/storage/SwitchRegionTest.java b/src/test/java/test/com/qiniu/storage/SwitchRegionTest.java index 1231c55a6..9eb338dee 100644 --- a/src/test/java/test/com/qiniu/storage/SwitchRegionTest.java +++ b/src/test/java/test/com/qiniu/storage/SwitchRegionTest.java @@ -10,22 +10,19 @@ import com.qiniu.util.Etag; import com.qiniu.util.Md5; import com.qiniu.util.StringMap; -import test.com.qiniu.TempFile; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import test.com.qiniu.TempFile; +import test.com.qiniu.TestConfig; import java.io.File; import java.io.IOException; import java.net.URLEncoder; import java.util.Date; +import static org.junit.jupiter.api.Assertions.*; + public class SwitchRegionTest { private static final int httpType = 0; diff --git a/src/test/java/test/com/qiniu/storage/ZoneTest.java b/src/test/java/test/com/qiniu/storage/ZoneTest.java index 94a9b0a30..594cf17a3 100644 --- a/src/test/java/test/com/qiniu/storage/ZoneTest.java +++ b/src/test/java/test/com/qiniu/storage/ZoneTest.java @@ -8,25 +8,25 @@ public class ZoneTest { - @Test - @Tag("UnitTest") - public void zone1() { - String ak = ""; - String sk = ""; - Auth auth = Auth.create(ak, sk); + @Test + @Tag("UnitTest") + public void zone1() { + String ak = ""; + String sk = ""; + Auth auth = Auth.create(ak, sk); - // Configuration.defaultApiHost = "apiserver-sdfrsd-s.qiniubbo.com"; - // Configuration.defaultRsHost = "rs-sdfrsd-s.qiniubbo.com"; - Zone zone = new Zone.Builder().upHttp("http://up-sdfrsd-s.qiniubbo.com") - .upBackupHttp("http://up-sdfrsd-s.qiniubbo.com") - .rsHttp("http://rs-sdfrsd-s.qiniubbo.com").rsfHttp("http://rsf-sdfrsd-s.qiniubbo.com") - .apiHttp("http://apiserver-sdfrsd-s.qiniubbo.com") - .iovipHttp("http://io-sdfrsd-s.qiniubbo.com").build(); + // Configuration.defaultApiHost = "apiserver-sdfrsd-s.qiniubbo.com"; + // Configuration.defaultRsHost = "rs-sdfrsd-s.qiniubbo.com"; + Zone zone = new Zone.Builder().upHttp("http://up-sdfrsd-s.qiniubbo.com") + .upBackupHttp("http://up-sdfrsd-s.qiniubbo.com") + .rsHttp("http://rs-sdfrsd-s.qiniubbo.com").rsfHttp("http://rsf-sdfrsd-s.qiniubbo.com") + .apiHttp("http://apiserver-sdfrsd-s.qiniubbo.com") + .iovipHttp("http://io-sdfrsd-s.qiniubbo.com").build(); - Zone zone2 = new Zone.Builder(zone).iovipHttp("http://io-sdfrsd-s.qiniubbo.com").build(); + Zone zone2 = new Zone.Builder(zone).iovipHttp("http://io-sdfrsd-s.qiniubbo.com").build(); - Configuration cfg = new Configuration(Zone.autoZone()); - cfg.zone = zone2; - } + Configuration cfg = new Configuration(Zone.autoZone()); + cfg.zone = zone2; + } } diff --git a/src/test/java/test/com/qiniu/streaming/StreamingTest.java b/src/test/java/test/com/qiniu/streaming/StreamingTest.java index 4aae60eb0..6fe751d04 100644 --- a/src/test/java/test/com/qiniu/streaming/StreamingTest.java +++ b/src/test/java/test/com/qiniu/streaming/StreamingTest.java @@ -1,14 +1,5 @@ package test.com.qiniu.streaming; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - import com.qiniu.common.QiniuException; import com.qiniu.streaming.StreamingManager; import com.qiniu.streaming.model.ActivityRecords; @@ -16,9 +7,12 @@ import com.qiniu.streaming.model.StreamListing; import com.qiniu.streaming.model.StreamStatus; import com.qiniu.util.Auth; - +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import test.com.qiniu.TestConfig; +import static org.junit.jupiter.api.Assertions.*; + /** * Created by bailong on 16/9/22 Updated by panyuan on 19/3/12 */ diff --git a/src/test/java/test/com/qiniu/streaming/UrlTest.java b/src/test/java/test/com/qiniu/streaming/UrlTest.java index 873b91c77..cb7fb3bc2 100644 --- a/src/test/java/test/com/qiniu/streaming/UrlTest.java +++ b/src/test/java/test/com/qiniu/streaming/UrlTest.java @@ -1,11 +1,12 @@ package test.com.qiniu.streaming; -import static org.junit.jupiter.api.Assertions.assertTrue; import com.qiniu.streaming.UrlFactory; -import test.com.qiniu.TestConfig; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import test.com.qiniu.TestConfig; + +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Created by bailong on 16/9/22. diff --git a/src/test/java/test/com/qiniu/util/Base64Test.java b/src/test/java/test/com/qiniu/util/Base64Test.java index e42d84c5c..2c0693ddc 100644 --- a/src/test/java/test/com/qiniu/util/Base64Test.java +++ b/src/test/java/test/com/qiniu/util/Base64Test.java @@ -1,11 +1,13 @@ package test.com.qiniu.util; import com.qiniu.util.UrlSafeBase64; -import static org.junit.jupiter.api.Assertions.assertEquals; -import java.io.UnsupportedEncodingException; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import java.io.UnsupportedEncodingException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + public class Base64Test { @Test @Tag("UnitTest") diff --git a/src/test/java/test/com/qiniu/util/CrcTest.java b/src/test/java/test/com/qiniu/util/CrcTest.java index b0cd03ddf..c0d0a9c0e 100644 --- a/src/test/java/test/com/qiniu/util/CrcTest.java +++ b/src/test/java/test/com/qiniu/util/CrcTest.java @@ -1,10 +1,11 @@ package test.com.qiniu.util; -import static org.junit.jupiter.api.Assertions.assertEquals; import com.qiniu.util.Crc32; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class CrcTest { @Test @Tag("UnitTest") diff --git a/src/test/java/test/com/qiniu/util/EtagTest.java b/src/test/java/test/com/qiniu/util/EtagTest.java index e4fd73b7e..45387e43e 100644 --- a/src/test/java/test/com/qiniu/util/EtagTest.java +++ b/src/test/java/test/com/qiniu/util/EtagTest.java @@ -5,46 +5,48 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import test.com.qiniu.TempFile; -import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.File; import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class EtagTest { - @Test - @Tag("UnitTest") - public void testData() { - String m = Etag.data(new byte[0]); - assertEquals("Fto5o-5ea0sNMlW_75VgGJCv2AcJ", m); - - String etag = Etag.data("etag".getBytes(Constants.UTF_8)); - assertEquals("FpLiADEaVoALPkdb8tJEJyRTXoe_", etag); - } - - @Test - @Tag("UnitTest") - public void testFile() throws IOException { - File f = TempFile.createFileOld(1024); - assertEquals("FqOV9T8l48x1u9dFEOROzwp4b0jr", Etag.file(f)); - TempFile.remove(f); - - f = TempFile.createFileOld(4 * 1024); - // System.out.println(Etag.file(f)); - assertEquals("FgtlGCfS97kgqopAxq0vvKRA5o_R", Etag.file(f)); - TempFile.remove(f); - - f = TempFile.createFileOld(5 * 1024); - // System.out.println(Etag.file(f)); - assertEquals("lvtM_iKNnZXkZR8U3Fvi_QQO2yyi", Etag.file(f)); - TempFile.remove(f); - - f = TempFile.createFileOld(8 * 1024); - // System.out.println(Etag.file(f)); - assertEquals("lhiIbcJgsRrl46LwMD9KHAQRLH2O", Etag.file(f)); - TempFile.remove(f); - - f = TempFile.createFileOld(9 * 1024); - // System.out.println(Etag.file(f)); - assertEquals("ll1xhlUFKQqynVgMMt_J1TuTrdB1", Etag.file(f)); - TempFile.remove(f); - } + @Test + @Tag("UnitTest") + public void testData() { + String m = Etag.data(new byte[0]); + assertEquals("Fto5o-5ea0sNMlW_75VgGJCv2AcJ", m); + + String etag = Etag.data("etag".getBytes(Constants.UTF_8)); + assertEquals("FpLiADEaVoALPkdb8tJEJyRTXoe_", etag); + } + + @Test + @Tag("UnitTest") + public void testFile() throws IOException { + File f = TempFile.createFileOld(1024); + assertEquals("FqOV9T8l48x1u9dFEOROzwp4b0jr", Etag.file(f)); + TempFile.remove(f); + + f = TempFile.createFileOld(4 * 1024); + // System.out.println(Etag.file(f)); + assertEquals("FgtlGCfS97kgqopAxq0vvKRA5o_R", Etag.file(f)); + TempFile.remove(f); + + f = TempFile.createFileOld(5 * 1024); + // System.out.println(Etag.file(f)); + assertEquals("lvtM_iKNnZXkZR8U3Fvi_QQO2yyi", Etag.file(f)); + TempFile.remove(f); + + f = TempFile.createFileOld(8 * 1024); + // System.out.println(Etag.file(f)); + assertEquals("lhiIbcJgsRrl46LwMD9KHAQRLH2O", Etag.file(f)); + TempFile.remove(f); + + f = TempFile.createFileOld(9 * 1024); + // System.out.println(Etag.file(f)); + assertEquals("ll1xhlUFKQqynVgMMt_J1TuTrdB1", Etag.file(f)); + TempFile.remove(f); + } } diff --git a/src/test/java/test/com/qiniu/util/JsonTest.java b/src/test/java/test/com/qiniu/util/JsonTest.java index ce5cad98f..4eb5f78d2 100644 --- a/src/test/java/test/com/qiniu/util/JsonTest.java +++ b/src/test/java/test/com/qiniu/util/JsonTest.java @@ -1,13 +1,14 @@ package test.com.qiniu.util; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.gson.Gson; import com.qiniu.util.Json; import com.qiniu.util.StringMap; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class JsonTest { @Test @Tag("UnitTest") diff --git a/src/test/java/test/com/qiniu/util/Md5Test.java b/src/test/java/test/com/qiniu/util/Md5Test.java index 38db458ca..04c0db01c 100644 --- a/src/test/java/test/com/qiniu/util/Md5Test.java +++ b/src/test/java/test/com/qiniu/util/Md5Test.java @@ -6,12 +6,14 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import test.com.qiniu.TempFile; -import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.NoSuchAlgorithmException; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class Md5Test { File f; diff --git a/src/test/java/test/com/qiniu/util/UrlComposerTest.java b/src/test/java/test/com/qiniu/util/UrlComposerTest.java index 1455fc260..980e21028 100644 --- a/src/test/java/test/com/qiniu/util/UrlComposerTest.java +++ b/src/test/java/test/com/qiniu/util/UrlComposerTest.java @@ -1,49 +1,47 @@ package test.com.qiniu.util; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import com.qiniu.util.StringMap; import com.qiniu.util.UrlUtils; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + public class UrlComposerTest { - @Test - @Tag("UnitTest") - public void testComposeUrlWithQueries() { - String testUrl = "http://sms.qiniuapi.com/v1/signature"; - StringMap queryMap = new StringMap().put("page", 1).put("page_size", 10); - String url = UrlUtils.composeUrlWithQueries(testUrl, queryMap); - assertTrue(url.equals("http://sms.qiniuapi.com/v1/signature?page=1&page_size=10") - || url.equals("http://sms.qiniuapi.com/v1/signature?page_size=10&page=1")); - } + @Test + @Tag("UnitTest") + public void testComposeUrlWithQueries() { + String testUrl = "http://sms.qiniuapi.com/v1/signature"; + StringMap queryMap = new StringMap().put("page", 1).put("page_size", 10); + String url = UrlUtils.composeUrlWithQueries(testUrl, queryMap); + assertTrue(url.equals("http://sms.qiniuapi.com/v1/signature?page=1&page_size=10") + || url.equals("http://sms.qiniuapi.com/v1/signature?page_size=10&page=1")); + } - @Test - @Tag("UnitTest") - public void testNonEncoding() { - String u = "http://asfd.clouddn.com/s共df/_-+./*/~/@/:/!/$/&/&/'/(/)/*/+/,/;\"/=/ /" - + "sdf/*/~/@/:/!/$/&/&/'/(/)/*/+/,/;\"/=/ /?sdfr=34sdf"; - String f = "http://asfd.clouddn.com/s%E5%85%B1df/_-+./%2A/~/@/:/%21/$/&/&/%27/%28/%29/%2A/+/,/;%22/=/%20/" - + "sdf/%2A/~/@/:/%21/$/&/&/%27/%28/%29/%2A/+/,/;%22/=/%20/?sdfr=34sdf"; - String c = UrlUtils.urlEncode(u, UrlUtils.PLUS_NON_ENCODING); // ~@:$&+,;=/? no !'()* - String cdefault = UrlUtils.urlEncode(u); // use UrlUtils.PLUS_NON_ENCODING - assertEquals(c, cdefault); - assertTrue(c.indexOf("%20") > -1 && c.indexOf(" ") == -1); - assertFalse(java.util.regex.Pattern.compile("[!'()*]").matcher(f).find()); - assertEquals(f, c); + @Test + @Tag("UnitTest") + public void testNonEncoding() { + String u = "http://asfd.clouddn.com/s共df/_-+./*/~/@/:/!/$/&/&/'/(/)/*/+/,/;\"/=/ /" + + "sdf/*/~/@/:/!/$/&/&/'/(/)/*/+/,/;\"/=/ /?sdfr=34sdf"; + String f = "http://asfd.clouddn.com/s%E5%85%B1df/_-+./%2A/~/@/:/%21/$/&/&/%27/%28/%29/%2A/+/,/;%22/=/%20/" + + "sdf/%2A/~/@/:/%21/$/&/&/%27/%28/%29/%2A/+/,/;%22/=/%20/?sdfr=34sdf"; + String c = UrlUtils.urlEncode(u, UrlUtils.PLUS_NON_ENCODING); // ~@:$&+,;=/? no !'()* + String cdefault = UrlUtils.urlEncode(u); // use UrlUtils.PLUS_NON_ENCODING + assertEquals(c, cdefault); + assertTrue(c.indexOf("%20") > -1 && c.indexOf(" ") == -1); + assertFalse(java.util.regex.Pattern.compile("[!'()*]").matcher(f).find()); + assertEquals(f, c); - String f2 = "http://asfd.clouddn.com/s%E5%85%B1df/_-+./*/~/@/:/!/$/&/&/'/(/)/*/+/,/;%22/=/%20/" - + "sdf/*/~/@/:/!/$/&/&/'/(/)/*/+/,/;%22/=/%20/?sdfr=34sdf"; - String c2 = UrlUtils.urlEncode(u, UrlUtils.PLUS_NON_ENCODING2); // ~@:!$&'()*+,;=/? - assertEquals(f2, c2); - assertTrue(java.util.regex.Pattern.compile("[!'()*]").matcher(f2).find()); + String f2 = "http://asfd.clouddn.com/s%E5%85%B1df/_-+./*/~/@/:/!/$/&/&/'/(/)/*/+/,/;%22/=/%20/" + + "sdf/*/~/@/:/!/$/&/&/'/(/)/*/+/,/;%22/=/%20/?sdfr=34sdf"; + String c2 = UrlUtils.urlEncode(u, UrlUtils.PLUS_NON_ENCODING2); // ~@:!$&'()*+,;=/? + assertEquals(f2, c2); + assertTrue(java.util.regex.Pattern.compile("[!'()*]").matcher(f2).find()); - assertNotEquals(c, c2); - String c3 = c.replaceAll("%21", "!").replaceAll("%27", "'").replaceAll("%28", "(") - .replaceAll("%29", ")").replaceAll("%2A", "*"); - assertEquals(c2, c3); - } + assertNotEquals(c, c2); + String c3 = c.replaceAll("%21", "!").replaceAll("%27", "'").replaceAll("%28", "(") + .replaceAll("%29", ")").replaceAll("%2A", "*"); + assertEquals(c2, c3); + } }