Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
GeoFlyApi
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
GeoFly
GeoFlyApi
Commits
24356261
Commit
24356261
authored
Jul 28, 2026
by
真的三个金的鑫
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
接入versityGW
parent
40c6a67b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
344 additions
and
8 deletions
+344
-8
cloud-sdk/src/main/java/com/dji/sdk/cloudapi/storage/OssTypeEnum.java
+13
-1
pom.xml
+21
-1
sample/src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java
+19
-0
sample/src/main/java/com/dji/sample/component/oss/service/impl/VersityGwAdminClient.java
+153
-0
sample/src/main/java/com/dji/sample/component/oss/service/impl/VersityGwServiceImpl.java
+0
-0
sample/src/main/java/com/dji/sample/component/redis/RedisConst.java
+4
-0
sample/src/main/java/com/dji/sample/storage/service/impl/StorageServiceImpl.java
+2
-2
sample/src/main/resources/application-dev.yml
+7
-2
sample/src/main/resources/application.yml
+7
-2
sample/src/test/java/com/dji/sample/component/oss/VersityGwAdminClientTest.java
+118
-0
No files found.
cloud-sdk/src/main/java/com/dji/sdk/cloudapi/storage/OssTypeEnum.java
View file @
24356261
...
@@ -15,7 +15,12 @@ public enum OssTypeEnum {
...
@@ -15,7 +15,12 @@ public enum OssTypeEnum {
AWS
(
"aws"
),
AWS
(
"aws"
),
MINIO
(
"minio"
);
MINIO
(
"minio"
),
/**
* VersityGW(S3 兼容)。下发给 Pilot/机场时请映射为 {@link #MINIO} 或 {@link #AWS}。
*/
VERSITYGW
(
"versity"
);
private
String
type
;
private
String
type
;
...
@@ -27,4 +32,11 @@ public enum OssTypeEnum {
...
@@ -27,4 +32,11 @@ public enum OssTypeEnum {
public
String
getType
()
{
public
String
getType
()
{
return
type
;
return
type
;
}
}
/**
* Pilot / 机场仅识别 ali / aws / minio,VersityGW 对外按 minio 上报。
*/
public
OssTypeEnum
toClientProvider
()
{
return
this
==
VERSITYGW
?
MINIO
:
this
;
}
}
}
pom.xml
View file @
24356261
...
@@ -23,6 +23,9 @@
...
@@ -23,6 +23,9 @@
<project.reporting.outputEncoding>
UTF-8
</project.reporting.outputEncoding>
<project.reporting.outputEncoding>
UTF-8
</project.reporting.outputEncoding>
<javax-activation.version>
1.1.1
</javax-activation.version>
<javax-activation.version>
1.1.1
</javax-activation.version>
<mqtt.version>
5.5.5
</mqtt.version>
<mqtt.version>
5.5.5
</mqtt.version>
<!-- OSS 配置 -->
<aws.sdk.version>
2.28.22
</aws.sdk.version>
<aws.crt.version>
0.31.3
</aws.crt.version>
</properties>
</properties>
<dependencyManagement>
<dependencyManagement>
...
@@ -67,7 +70,24 @@
...
@@ -67,7 +70,24 @@
<groupId>
com.fasterxml.jackson.datatype
</groupId>
<groupId>
com.fasterxml.jackson.datatype
</groupId>
<artifactId>
jackson-datatype-jsr310
</artifactId>
<artifactId>
jackson-datatype-jsr310
</artifactId>
</dependency>
</dependency>
<!-- AWS SDK for Java 2.x -->
<dependency>
<groupId>
software.amazon.awssdk
</groupId>
<artifactId>
s3
</artifactId>
<version>
${aws.sdk.version}
</version>
</dependency>
<!-- 使用AWS基于 CRT 的 S3 客户端 -->
<dependency>
<groupId>
software.amazon.awssdk.crt
</groupId>
<artifactId>
aws-crt
</artifactId>
<version>
${aws.crt.version}
</version>
</dependency>
<!-- 基于 AWS CRT 的 S3 客户端的性能增强的 S3 传输管理器 -->
<dependency>
<groupId>
software.amazon.awssdk
</groupId>
<artifactId>
s3-transfer-manager
</artifactId>
<version>
${aws.sdk.version}
</version>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
sample/src/main/java/com/dji/sample/component/oss/model/OssConfiguration.java
View file @
24356261
...
@@ -44,6 +44,17 @@ public class OssConfiguration {
...
@@ -44,6 +44,17 @@ public class OssConfiguration {
public
static
String
objectDirPrefix
;
public
static
String
objectDirPrefix
;
/**
* VersityGW STS 模式:temp=Admin 创建临时用户;static=直接下发长期 AK/SK。
*/
public
static
String
stsMode
=
"temp"
;
/**
* 临时用户角色:user / userplus / admin。
* 共享 bucket 且未改 ownership 时建议 admin(可访问全部 bucket)。
*/
public
static
String
stsUserRole
=
"admin"
;
public
void
setProvider
(
OssTypeEnum
provider
)
{
public
void
setProvider
(
OssTypeEnum
provider
)
{
OssConfiguration
.
provider
=
provider
;
OssConfiguration
.
provider
=
provider
;
}
}
...
@@ -87,6 +98,14 @@ public class OssConfiguration {
...
@@ -87,6 +98,14 @@ public class OssConfiguration {
public
void
setObjectDirPrefix
(
String
objectDirPrefix
)
{
public
void
setObjectDirPrefix
(
String
objectDirPrefix
)
{
OssConfiguration
.
objectDirPrefix
=
objectDirPrefix
;
OssConfiguration
.
objectDirPrefix
=
objectDirPrefix
;
}
}
public
void
setStsMode
(
String
stsMode
)
{
OssConfiguration
.
stsMode
=
stsMode
;
}
public
void
setStsUserRole
(
String
stsUserRole
)
{
OssConfiguration
.
stsUserRole
=
stsUserRole
;
}
}
}
...
...
sample/src/main/java/com/dji/sample/component/oss/service/impl/VersityGwAdminClient.java
0 → 100644
View file @
24356261
package
com
.
dji
.
sample
.
component
.
oss
.
service
.
impl
;
import
com.dji.sample.component.oss.model.OssConfiguration
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
software.amazon.awssdk.auth.credentials.AwsBasicCredentials
;
import
software.amazon.awssdk.auth.signer.AwsS3V4Signer
;
import
software.amazon.awssdk.auth.signer.params.AwsS3V4SignerParams
;
import
software.amazon.awssdk.http.SdkHttpFullRequest
;
import
software.amazon.awssdk.http.SdkHttpMethod
;
import
software.amazon.awssdk.regions.Region
;
import
java.io.ByteArrayInputStream
;
import
java.net.URI
;
import
java.net.http.HttpClient
;
import
java.net.http.HttpRequest
;
import
java.net.http.HttpResponse
;
import
java.nio.charset.StandardCharsets
;
import
java.time.Duration
;
import
java.util.List
;
import
java.util.Map
;
/**
* VersityGW Admin API 客户端(S3 SigV4)。
* 使用 {@link AwsS3V4Signer},会自动带上并签名 x-amz-content-sha256。
*/
@Slf4j
@Component
public
class
VersityGwAdminClient
{
private
static
final
String
SERVICE
=
"s3"
;
private
final
HttpClient
httpClient
=
HttpClient
.
newBuilder
()
.
connectTimeout
(
Duration
.
ofSeconds
(
10
))
.
build
();
private
final
AwsS3V4Signer
signer
=
AwsS3V4Signer
.
create
();
public
void
createUser
(
String
accessKey
,
String
secretKey
,
String
role
)
{
String
body
=
""
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+
"<Account>"
+
"<Access>"
+
xmlEscape
(
accessKey
)
+
"</Access>"
+
"<Secret>"
+
xmlEscape
(
secretKey
)
+
"</Secret>"
+
"<Role>"
+
xmlEscape
(
role
)
+
"</Role>"
+
"</Account>"
;
HttpResponse
<
String
>
response
=
execute
(
SdkHttpMethod
.
PATCH
,
"/create-user"
,
null
,
body
);
int
code
=
response
.
statusCode
();
if
(
code
!=
201
&&
code
!=
200
)
{
throw
new
IllegalStateException
(
"VersityGW create-user failed, status="
+
code
+
", body="
+
response
.
body
());
}
log
.
info
(
"VersityGW temp user created: access={}"
,
accessKey
);
}
public
void
deleteUser
(
String
accessKey
)
{
HttpResponse
<
String
>
response
=
execute
(
SdkHttpMethod
.
PATCH
,
"/delete-user"
,
Map
.
of
(
"access"
,
accessKey
),
null
);
int
code
=
response
.
statusCode
();
if
(
code
!=
204
&&
code
!=
200
&&
code
!=
404
)
{
throw
new
IllegalStateException
(
"VersityGW delete-user failed, status="
+
code
+
", body="
+
response
.
body
());
}
log
.
info
(
"VersityGW temp user deleted: access={}"
,
accessKey
);
}
public
String
listUsers
()
{
HttpResponse
<
String
>
response
=
execute
(
SdkHttpMethod
.
PATCH
,
"/list-users"
,
null
,
null
);
int
code
=
response
.
statusCode
();
if
(
code
!=
200
&&
code
!=
204
)
{
throw
new
IllegalStateException
(
"VersityGW list-users failed, status="
+
code
+
", body="
+
response
.
body
());
}
return
response
.
body
()
==
null
?
""
:
response
.
body
();
}
private
HttpResponse
<
String
>
execute
(
SdkHttpMethod
method
,
String
path
,
Map
<
String
,
String
>
query
,
String
body
)
{
try
{
byte
[]
payload
=
body
==
null
?
new
byte
[
0
]
:
body
.
getBytes
(
StandardCharsets
.
UTF_8
);
URI
endpoint
=
URI
.
create
(
trimTrailingSlash
(
OssConfiguration
.
endpoint
));
SdkHttpFullRequest
.
Builder
requestBuilder
=
SdkHttpFullRequest
.
builder
()
.
method
(
method
)
.
protocol
(
endpoint
.
getScheme
())
.
host
(
endpoint
.
getHost
())
.
port
(
resolvePort
(
endpoint
))
.
encodedPath
(
path
)
.
contentStreamProvider
(()
->
new
ByteArrayInputStream
(
payload
));
if
(
query
!=
null
)
{
query
.
forEach
(
requestBuilder:
:
putRawQueryParameter
);
}
if
(
body
!=
null
)
{
requestBuilder
.
putHeader
(
"Content-Type"
,
"application/xml"
);
}
SdkHttpFullRequest
signed
=
signer
.
sign
(
requestBuilder
.
build
(),
AwsS3V4SignerParams
.
builder
()
.
awsCredentials
(
AwsBasicCredentials
.
create
(
OssConfiguration
.
accessKey
,
OssConfiguration
.
secretKey
))
.
signingName
(
SERVICE
)
.
signingRegion
(
Region
.
of
(
OssConfiguration
.
region
))
.
build
());
HttpRequest
.
Builder
httpBuilder
=
HttpRequest
.
newBuilder
()
.
uri
(
signed
.
getUri
())
.
timeout
(
Duration
.
ofSeconds
(
30
))
.
method
(
method
.
name
(),
HttpRequest
.
BodyPublishers
.
ofByteArray
(
payload
));
boolean
hasContentSha256
=
false
;
for
(
Map
.
Entry
<
String
,
List
<
String
>>
header
:
signed
.
headers
().
entrySet
())
{
String
name
=
header
.
getKey
();
if
(
"Content-Length"
.
equalsIgnoreCase
(
name
)
||
"Host"
.
equalsIgnoreCase
(
name
))
{
continue
;
}
if
(
"x-amz-content-sha256"
.
equalsIgnoreCase
(
name
))
{
hasContentSha256
=
true
;
}
for
(
String
value
:
header
.
getValue
())
{
httpBuilder
.
header
(
name
,
value
);
}
}
if
(!
hasContentSha256
)
{
throw
new
IllegalStateException
(
"Signed request missing x-amz-content-sha256 header"
);
}
return
httpClient
.
send
(
httpBuilder
.
build
(),
HttpResponse
.
BodyHandlers
.
ofString
());
}
catch
(
IllegalStateException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
throw
new
IllegalStateException
(
"VersityGW admin API call failed: "
+
path
,
e
);
}
}
private
static
int
resolvePort
(
URI
endpoint
)
{
if
(
endpoint
.
getPort
()
!=
-
1
)
{
return
endpoint
.
getPort
();
}
return
"https"
.
equalsIgnoreCase
(
endpoint
.
getScheme
())
?
443
:
80
;
}
private
static
String
trimTrailingSlash
(
String
endpoint
)
{
if
(
endpoint
!=
null
&&
endpoint
.
endsWith
(
"/"
))
{
return
endpoint
.
substring
(
0
,
endpoint
.
length
()
-
1
);
}
return
endpoint
;
}
private
static
String
xmlEscape
(
String
value
)
{
return
value
.
replace
(
"&"
,
"&"
)
.
replace
(
"<"
,
"<"
)
.
replace
(
">"
,
">"
)
.
replace
(
"\""
,
"""
)
.
replace
(
"'"
,
"'"
);
}
}
sample/src/main/java/com/dji/sample/component/oss/service/impl/VersityGwServiceImpl.java
0 → 100644
View file @
24356261
This diff is collapsed.
Click to expand it.
sample/src/main/java/com/dji/sample/component/redis/RedisConst.java
View file @
24356261
...
@@ -101,4 +101,7 @@ public final class RedisConst {
...
@@ -101,4 +101,7 @@ public final class RedisConst {
*/
*/
public
static
final
String
DEVICE_TOTAL_FLIGHT_TIME_PREFIX
=
DEVICE_DETAIL_PREFIX
+
"total_flight_time"
+
DELIMITER
;
public
static
final
String
DEVICE_TOTAL_FLIGHT_TIME_PREFIX
=
DEVICE_DETAIL_PREFIX
+
"total_flight_time"
+
DELIMITER
;
/** VersityGW 临时 STS 用户:hash field=accessKey, value=expireEpochSec */
public
static
final
String
VGW_STS_USERS
=
"oss"
+
DELIMITER
+
"vgw_sts_users"
;
}
}
\ No newline at end of file
sample/src/main/java/com/dji/sample/storage/service/impl/StorageServiceImpl.java
View file @
24356261
...
@@ -46,7 +46,7 @@ public class StorageServiceImpl extends AbstractMediaService implements IStorage
...
@@ -46,7 +46,7 @@ public class StorageServiceImpl extends AbstractMediaService implements IStorage
.
setEndpoint
(
OssConfiguration
.
endpoint
)
.
setEndpoint
(
OssConfiguration
.
endpoint
)
.
setBucket
(
OssConfiguration
.
bucket
)
.
setBucket
(
OssConfiguration
.
bucket
)
.
setCredentials
(
ossService
.
getCredentials
())
.
setCredentials
(
ossService
.
getCredentials
())
.
setProvider
(
OssConfiguration
.
provider
)
.
setProvider
(
OssConfiguration
.
provider
.
toClientProvider
()
)
.
setObjectKeyPrefix
(
OssConfiguration
.
objectDirPrefix
)
.
setObjectKeyPrefix
(
OssConfiguration
.
objectDirPrefix
)
.
setRegion
(
OssConfiguration
.
region
);
.
setRegion
(
OssConfiguration
.
region
);
}
}
...
@@ -57,7 +57,7 @@ public class StorageServiceImpl extends AbstractMediaService implements IStorage
...
@@ -57,7 +57,7 @@ public class StorageServiceImpl extends AbstractMediaService implements IStorage
.
setEndpoint
(
OssConfiguration
.
endpoint
)
.
setEndpoint
(
OssConfiguration
.
endpoint
)
.
setBucket
(
OssConfiguration
.
bucket
)
.
setBucket
(
OssConfiguration
.
bucket
)
.
setCredentials
(
ossService
.
getCredentials
())
.
setCredentials
(
ossService
.
getCredentials
())
.
setProvider
(
OssConfiguration
.
provider
)
.
setProvider
(
OssConfiguration
.
provider
.
toClientProvider
()
)
.
setObjectKeyPrefix
(
OssConfiguration
.
objectDirPrefix
+
"/"
+
workspaceId
)
.
setObjectKeyPrefix
(
OssConfiguration
.
objectDirPrefix
+
"/"
+
workspaceId
)
.
setRegion
(
OssConfiguration
.
region
);
.
setRegion
(
OssConfiguration
.
region
);
}
}
...
...
sample/src/main/resources/application-dev.yml
View file @
24356261
...
@@ -161,12 +161,15 @@ url:
...
@@ -161,12 +161,15 @@ url:
# bucket: cloudapi-bucket
# bucket: cloudapi-bucket
# object-dir-prefix: wayline
# object-dir-prefix: wayline
# VersityGW:provider=versitygw(OssTypeEnum.VERSITYGW)。下发给 Pilot/机场时会映射为 minio。
# sts-mode=temp:Admin API 创建短期用户(需开启 VersityGW 多租户 IAM);static:直接下发长期 AK/SK。
# 若仍用 MinIO,改为 provider: minio 即可。
oss
:
oss
:
enable
:
true
enable
:
true
provider
:
minio
provider
:
versitygw
# 香港
# 香港
# endpoint: https://gt7-oss.geotwin.cc
# endpoint: https://gt7-oss.geotwin.cc
# 深圳
# 深圳
/ VersityGW
endpoint
:
https://gt-oss-dev.geotwin.cn
endpoint
:
https://gt-oss-dev.geotwin.cn
access-key
:
minioadmin
access-key
:
minioadmin
secret-key
:
minioadmin
secret-key
:
minioadmin
...
@@ -174,6 +177,8 @@ oss:
...
@@ -174,6 +177,8 @@ oss:
expire
:
86400
# 24 * 3600 24小时
expire
:
86400
# 24 * 3600 24小时
region
:
us-east-1
# us-east-1
region
:
us-east-1
# us-east-1
object-dir-prefix
:
wayline
object-dir-prefix
:
wayline
sts-mode
:
temp
sts-user-role
:
admin
logging
:
logging
:
level
:
level
:
...
...
sample/src/main/resources/application.yml
View file @
24356261
...
@@ -164,12 +164,15 @@ url:
...
@@ -164,12 +164,15 @@ url:
# bucket: cloudapi-bucket
# bucket: cloudapi-bucket
# object-dir-prefix: wayline
# object-dir-prefix: wayline
# VersityGW:provider=versitygw(OssTypeEnum.VERSITYGW)。下发给 Pilot/机场时会映射为 minio。
# sts-mode=temp:Admin API 创建短期用户(需开启 VersityGW 多租户 IAM);static:直接下发长期 AK/SK。
# 若仍用 MinIO,改为 provider: minio 即可。
oss
:
oss
:
enable
:
true
enable
:
true
provider
:
minio
provider
:
versitygw
# 香港
# 香港
# endpoint: https://gt7-oss.geotwin.cc
# endpoint: https://gt7-oss.geotwin.cc
# 深圳
# 深圳
/ VersityGW
endpoint
:
https://gt-oss-dev.geotwin.cn
endpoint
:
https://gt-oss-dev.geotwin.cn
access-key
:
minioadmin
access-key
:
minioadmin
secret-key
:
minioadmin
secret-key
:
minioadmin
...
@@ -177,6 +180,8 @@ oss:
...
@@ -177,6 +180,8 @@ oss:
expire
:
86400
# 24 * 3600 24小时
expire
:
86400
# 24 * 3600 24小时
region
:
us-east-1
# us-east-1
region
:
us-east-1
# us-east-1
object-dir-prefix
:
wayline
object-dir-prefix
:
wayline
sts-mode
:
temp
sts-user-role
:
admin
logging
:
logging
:
level
:
level
:
...
...
sample/src/test/java/com/dji/sample/component/oss/VersityGwAdminClientTest.java
0 → 100644
View file @
24356261
package
com
.
dji
.
sample
.
component
.
oss
;
import
com.dji.sample.component.oss.model.OssConfiguration
;
import
com.dji.sample.component.oss.service.impl.VersityGwAdminClient
;
import
software.amazon.awssdk.auth.credentials.AwsBasicCredentials
;
import
software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
;
import
software.amazon.awssdk.core.sync.RequestBody
;
import
software.amazon.awssdk.regions.Region
;
import
software.amazon.awssdk.services.s3.S3Client
;
import
software.amazon.awssdk.services.s3.S3Configuration
;
import
software.amazon.awssdk.services.s3.model.S3Exception
;
import
java.net.URI
;
import
java.nio.charset.StandardCharsets
;
import
java.util.UUID
;
/**
* VersityGW Admin 用户创建/删除冒烟测试(IDE 直接跑 main)。
* <p>
* 前提:网关已开启多租户 IAM(如 --iam-dir),否则 create-user 会失败。
*/
public
class
VersityGwAdminClientTest
{
private
static
final
String
ENDPOINT
=
"https://gt-oss-dev.geotwin.cn"
;
private
static
final
String
ADMIN_ACCESS
=
"minioadmin"
;
private
static
final
String
ADMIN_SECRET
=
"minioadmin"
;
private
static
final
String
REGION
=
"us-east-1"
;
private
static
final
String
BUCKET
=
"gtfly"
;
public
static
void
main
(
String
[]
args
)
{
initOssConfig
();
VersityGwAdminClient
admin
=
new
VersityGwAdminClient
();
String
tempAccess
=
"tmp"
+
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
).
substring
(
0
,
17
);
String
tempSecret
=
"Secret"
+
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
try
{
System
.
out
.
println
(
"=== 1. list-users (before) ==="
);
System
.
out
.
println
(
admin
.
listUsers
());
System
.
out
.
println
(
"=== 2. create-user access="
+
tempAccess
+
" role=admin ==="
);
admin
.
createUser
(
tempAccess
,
tempSecret
,
"admin"
);
System
.
out
.
println
(
" created OK"
);
System
.
out
.
println
(
"=== 3. list-users (after create) ==="
);
String
listed
=
admin
.
listUsers
();
System
.
out
.
println
(
listed
);
if
(!
listed
.
contains
(
tempAccess
))
{
System
.
err
.
println
(
" WARN: list-users 响应中未找到 "
+
tempAccess
);
}
System
.
out
.
println
(
"=== 4. temp user S3 put/delete ==="
);
try
(
S3Client
s3
=
buildS3
(
tempAccess
,
tempSecret
))
{
String
key
=
"wayline/_vgw_admin_test_"
+
System
.
currentTimeMillis
()
+
".txt"
;
s3
.
putObject
(
b
->
b
.
bucket
(
BUCKET
).
key
(
key
).
contentType
(
"text/plain"
),
RequestBody
.
fromBytes
((
"admin-user-test "
+
tempAccess
).
getBytes
(
StandardCharsets
.
UTF_8
)));
System
.
out
.
println
(
" put OK: "
+
key
);
s3
.
deleteObject
(
b
->
b
.
bucket
(
BUCKET
).
key
(
key
));
System
.
out
.
println
(
" delete object OK"
);
}
System
.
out
.
println
(
"=== 5. delete-user ==="
);
admin
.
deleteUser
(
tempAccess
);
System
.
out
.
println
(
" deleted OK"
);
System
.
out
.
println
(
"=== 6. list-users (after delete) ==="
);
String
afterDelete
=
admin
.
listUsers
();
System
.
out
.
println
(
afterDelete
);
if
(
afterDelete
.
contains
(
tempAccess
))
{
System
.
err
.
println
(
" WARN: 删除后 list-users 仍包含 "
+
tempAccess
);
}
System
.
out
.
println
(
"=== 7. deleted user should NOT access S3 ==="
);
try
(
S3Client
s3
=
buildS3
(
tempAccess
,
tempSecret
))
{
s3
.
listBuckets
();
System
.
err
.
println
(
" FAIL: 已删除用户仍能 listBuckets"
);
}
catch
(
S3Exception
e
)
{
System
.
out
.
println
(
" expected fail: "
+
e
.
statusCode
()
+
" "
+
e
.
awsErrorDetails
().
errorMessage
());
}
System
.
out
.
println
(
"=== 8. delete-user idempotent (404 ok) ==="
);
admin
.
deleteUser
(
tempAccess
);
System
.
out
.
println
(
" delete again OK"
);
System
.
out
.
println
(
"VersityGW Admin user lifecycle OK"
);
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"VersityGW Admin test FAILED: "
+
e
.
getMessage
());
e
.
printStackTrace
();
try
{
admin
.
deleteUser
(
tempAccess
);
}
catch
(
Exception
ignore
)
{
// best-effort cleanup
}
}
}
private
static
void
initOssConfig
()
{
OssConfiguration
.
endpoint
=
ENDPOINT
;
OssConfiguration
.
accessKey
=
ADMIN_ACCESS
;
OssConfiguration
.
secretKey
=
ADMIN_SECRET
;
OssConfiguration
.
region
=
REGION
;
OssConfiguration
.
bucket
=
BUCKET
;
OssConfiguration
.
enable
=
true
;
}
private
static
S3Client
buildS3
(
String
access
,
String
secret
)
{
return
S3Client
.
builder
()
.
endpointOverride
(
URI
.
create
(
ENDPOINT
))
.
region
(
Region
.
of
(
REGION
))
.
credentialsProvider
(
StaticCredentialsProvider
.
create
(
AwsBasicCredentials
.
create
(
access
,
secret
)))
.
serviceConfiguration
(
S3Configuration
.
builder
()
.
pathStyleAccessEnabled
(
true
)
.
chunkedEncodingEnabled
(
false
)
.
build
())
.
build
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment