Skip to content

[feature] add alibaba cloud oss support #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

arvi18
Copy link

@arvi18 arvi18 commented Apr 21, 2025

What's changed?

Checklist

  • I have read the Contributing Guide
  • I have written the necessary doc or comment.
  • I have added the necessary unit tests and all cases have passed.

Add or update API

  • I have added the necessary e2e tests and all cases have passed.

Summary by CodeRabbit

  • New Features

    • Added support for Alibaba Cloud OSS as a new object storage provider, alongside existing providers.
    • Users can now configure and select Alibaba Cloud OSS in the object storage settings UI.
    • File upload, download, and listing are supported for OSS.
  • Localization

    • Added English, Simplified Chinese, and Traditional Chinese translations for Alibaba Cloud OSS configuration fields and labels.
  • UI Enhancements

    • Updated the object storage settings form to accommodate Alibaba Cloud OSS-specific fields and placeholders.

@arvi18
Copy link
Author

arvi18 commented Apr 21, 2025

oss1
zhi'chi
oss2
支持阿里云oss

Copy link

coderabbitai bot commented Apr 21, 2025

Walkthrough

This change introduces support for Alibaba Cloud OSS (Object Storage Service) as an additional object storage provider in the system. The backend adds OSS-specific configuration handling, a new implementation for object storage operations using the Alibaba OSS SDK, and updates the object store DTO to include OSS configuration. The frontend is updated to allow users to select OSS, enter the relevant credentials, and view localized UI strings for OSS in English, Simplified Chinese, and Traditional Chinese. The build configuration is updated to include the Alibaba OSS SDK dependency.

Changes

File(s) Change Summary
manager/pom.xml Added Alibaba Cloud OSS SDK dependency and version property to the Maven build configuration.
manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/ObjectStoreDTO.java Extended Type enum to include OSS; introduced new static inner class OssConfig for Alibaba OSS configuration fields.
manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ObjectStoreConfigServiceImpl.java Added OSS initialization logic: parses OSS config, validates fields, creates OSS client, and registers new OSS object store service implementation. Updated handler method to support OSS alongside existing OBS logic.
manager/src/main/java/org/apache/hertzbeat/manager/service/impl/OssObjectStoreServiceImpl.java New class implementing ObjectStoreService for Alibaba Cloud OSS: supports file upload, download, and listing using the OSS client and configuration.
web-app/src/app/pojo/ObjectStore.ts Added OSS to ObjectStoreType enum; introduced OssConfig class mirroring existing OBS config structure with OSS-specific fields.
web-app/src/app/routes/setting/settings/object-store/object-store.component.html UI: Added OSS as selectable type; updated form to support OSS config fields and dynamic placeholders for OSS/OBS.
web-app/src/app/routes/setting/settings/object-store/object-store.component.ts Logic: Added OSS config initialization in type change handler; imported OssConfig.
web-app/src/assets/i18n/en-US.json Added English localization strings for Alibaba Cloud OSS configuration fields and labels.
web-app/src/assets/i18n/zh-CN.json Added Simplified Chinese localization strings for Alibaba Cloud OSS configuration fields and labels.
web-app/src/assets/i18n/zh-TW.json Added Traditional Chinese localization strings for Alibaba Cloud OSS configuration fields and labels.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Frontend
    participant Backend
    participant OSS_SDK

    User->>Frontend: Selects OSS as object store type, enters credentials
    Frontend->>Backend: Submits OSS configuration
    Backend->>Backend: Parses and validates OSS config
    Backend->>OSS_SDK: Initializes OSS client with credentials
    Backend->>Backend: Registers OssObjectStoreServiceImpl
    User->>Frontend: Uploads/downloads file
    Frontend->>Backend: Sends file operation request
    Backend->>OssObjectStoreServiceImpl: Handles upload/download/list
    OssObjectStoreServiceImpl->>OSS_SDK: Performs OSS operation
    OSS_SDK-->>OssObjectStoreServiceImpl: Returns result
    OssObjectStoreServiceImpl-->>Backend: Returns result
    Backend-->>Frontend: Responds with operation outcome
Loading

Poem

A hop to the cloud, a leap to the sky,
Now OSS joins in, as time hops by!
With buckets and keys, and endpoints anew,
The rabbit now stores in Alibaba too.
Multilingual greetings, the UI feels bright—
OSS is here, and all is right!
🐇☁️

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@visz11
Copy link
Collaborator

visz11 commented Apr 23, 2025

@coderabbitai full review

Copy link

coderabbitai bot commented Apr 23, 2025

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ObjectStoreConfigServiceImpl.java (1)

87-89: Consider using 'else if' instead of a separate 'if' condition.

The current implementation uses a separate if statement after the previous condition. While this works for enum values, using else if would be more explicit and prevent potential issues if the code evolves.

-            if (config.getType() == ObjectStoreDTO.Type.OSS) {
+            else if (config.getType() == ObjectStoreDTO.Type.OSS) {
                 initOss(config);
             }
web-app/src/app/routes/setting/settings/object-store/object-store.component.html (1)

38-137: UI labels are not updated for OSS.

While the placeholders are conditionally changed based on the selected storage type, the form labels still reference OBS-specific labels even when OSS is selected. Consider updating the form labels to be conditional as well.

For example, update line 80-81 from:

<nz-form-label [nzSpan]="6" nzFor="obs.bucketName" nzRequired="true">{{
  'settings.object-store.obs.bucketName' | i18n
}}</nz-form-label>

To:

<nz-form-label [nzSpan]="6" nzFor="obs.bucketName" nzRequired="true">{{
  config.type == ObjectStoreType.OBS
    ? ('settings.object-store.obs.bucketName' | i18n)
    : ('settings.object-store.oss.bucketName' | i18n)
}}</nz-form-label>

Apply similar changes to other form labels as well.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b02837b and d494c75.

📒 Files selected for processing (10)
  • manager/pom.xml (2 hunks)
  • manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/ObjectStoreDTO.java (2 hunks)
  • manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ObjectStoreConfigServiceImpl.java (2 hunks)
  • manager/src/main/java/org/apache/hertzbeat/manager/service/impl/OssObjectStoreServiceImpl.java (1 hunks)
  • web-app/src/app/pojo/ObjectStore.ts (2 hunks)
  • web-app/src/app/routes/setting/settings/object-store/object-store.component.html (5 hunks)
  • web-app/src/app/routes/setting/settings/object-store/object-store.component.ts (2 hunks)
  • web-app/src/assets/i18n/en-US.json (2 hunks)
  • web-app/src/assets/i18n/zh-CN.json (2 hunks)
  • web-app/src/assets/i18n/zh-TW.json (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
web-app/src/app/routes/setting/settings/object-store/object-store.component.ts (1)
web-app/src/app/pojo/ObjectStore.ts (1)
  • OssConfig (50-56)
manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/ObjectStoreDTO.java (1)
web-app/src/app/pojo/ObjectStore.ts (1)
  • OssConfig (50-56)
🔇 Additional comments (24)
manager/pom.xml (2)

40-40: Good addition of Alibaba OSS version property.

The version property for Alibaba OSS is correctly defined and follows the established project pattern for dependency management.


202-206:

❓ Verification inconclusive

LGTM on OSS dependency addition.

The Alibaba Cloud OSS SDK dependency is correctly added with proper groupId, artifactId, and version reference. This provides the necessary library to implement OSS object storage service.

However, I notice other cloud dependencies (like Huawei) have exclusions for conflicting dependencies. Might be worth checking if any exclusions are needed here too.


🏁 Script executed:

#!/bin/bash
# Check if there are any potential dependency conflicts
# Look for any bgmprovider exclusions (like the ones for Huawei SDK)

echo "Checking for potential dependency conflicts with Alibaba OSS SDK..."
mvn dependency:tree -Dincludes=com.aliyun.oss:aliyun-sdk-oss,org.openeuler:bgmprovider

# Also check if the latest version is significantly newer
echo -e "\nLatest Alibaba OSS SDK version:"
curl -s https://search.maven.org/solrsearch/select?q=g:com.aliyun.oss+AND+a:aliyun-sdk-oss&wt=json | jq -r '.response.docs[0].latestVersion'

Length of output: 1290


#!/bin/bash
# Locate the defined alibaba.oss.version property to compare against the latest (3.18.1)
rg -Hn "<alibaba.oss.version>" manager/pom.xml

LGTM on Alibaba Cloud OSS SDK addition; verify if exclusions are needed

The Alibaba Cloud OSS SDK dependency is correctly declared in manager/pom.xml (lines 202–206). To avoid potential transitive conflicts—similar to the exclusions applied for the Huawei SDK—please review the OSS SDK’s dependencies and add any necessary <exclusion> entries.

  • File: manager/pom.xml (lines 202–206)
    <dependency> com.aliyun.oss:aliyun-sdk-oss:${alibaba.oss.version} </dependency>
web-app/src/app/routes/setting/settings/object-store/object-store.component.ts (2)

25-25: Correctly imported the OSS config class.

The OssConfig class is properly imported with other object store related classes.


115-117: Well implemented OSS config initialization.

The implementation follows the existing pattern for handling object store type changes by initializing an appropriate configuration object when OSS is selected. This ensures consistency with how other storage types like OBS are handled.

web-app/src/assets/i18n/zh-CN.json (2)

555-555: Proper localization for Alibaba OSS type label.

The Chinese translation for "Alibaba Cloud OSS" is correctly added as "阿里云OSS".


566-575: Complete localization for OSS configuration fields.

All necessary OSS configuration field labels and placeholders are properly translated to Simplified Chinese, including AccessKey, SecretKey, Bucket, EndPoint, and save path. The translations provide useful guidance to users by clearly explaining what information is needed for each field.

web-app/src/assets/i18n/zh-TW.json (2)

552-552: Proper Traditional Chinese localization for Alibaba OSS type label.

The Traditional Chinese translation for "Alibaba Cloud OSS" is correctly added as "阿裏雲OSS".


563-572: Complete Traditional Chinese localization for OSS configuration.

All necessary OSS configuration field labels and placeholders are properly translated to Traditional Chinese, including AccessKey, SecretKey, Bucket, EndPoint, and save path. The translations maintain consistency with the Simplified Chinese version while using appropriate Traditional Chinese characters.

web-app/src/app/pojo/ObjectStore.ts (2)

35-39: Addition of Alibaba Cloud OSS to the ObjectStoreType looks good.

The implementation correctly adds OSS as a new option in the ObjectStoreType enum with appropriate documentation linking to the Alibaba Cloud OSS console.


50-56: OssConfig class implementation is consistent with ObsConfig.

The new OssConfig class follows the same structure as the existing ObsConfig class, maintaining consistency across different storage providers. Both classes share the same property structure and default values.

manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/ObjectStoreDTO.java (2)

57-62: Addition of OSS enum value is consistent with the frontend implementation.

The OSS enum value is properly documented with a link to the Alibaba Cloud OSS console, matching the frontend implementation.


81-95: OssConfig class implementation is consistent with ObsConfig.

The new static OssConfig class follows the same structure as the existing ObsConfig class, providing a clean and consistent approach for handling different storage providers.

manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ObjectStoreConfigServiceImpl.java (2)

20-20: Import for OSSClientBuilder has been added correctly.

The required import for Alibaba Cloud OSS SDK has been added to support OSS client creation.


94-107:

✅ Verification successful

Implementation of initOss follows the same pattern as initObs.

The initOss method correctly follows the same pattern as initObs:

  1. Converting config to OssConfig
  2. Validating required parameters
  3. Creating an OSS client
  4. Registering a new OSS service implementation

One thing to verify is whether the OssObjectStoreServiceImpl class is properly implemented, as it's referenced here but not included in the files for review.


🏁 Script executed:

#!/bin/bash
# Check if OssObjectStoreServiceImpl is implemented
rg -A 5 "class OssObjectStoreServiceImpl"

Length of output: 791


🏁 Script executed:

#!/bin/bash
# Display the first 200 lines of OssObjectStoreServiceImpl to review method implementations
sed -n '1,200p' manager/src/main/java/org/apache/hertzbeat/manager/service/impl/OssObjectStoreServiceImpl.java

# Display the first 200 lines of the ObjectStoreService interface to compare required methods
sed -n '1,200p' manager/src/main/java/org/apache/hertzbeat/manager/service/ObjectStoreService.java

Length of output: 5021


OssObjectStoreServiceImpl correctly implements ObjectStoreService

The class OssObjectStoreServiceImpl is present and provides all required methods (upload, download, list, and type) as defined by ObjectStoreService. No further changes are needed.

web-app/src/app/routes/setting/settings/object-store/object-store.component.html (3)

35-35: OSS option has been added to the dropdown.

The Alibaba Cloud OSS option has been correctly added to the object store type selector dropdown.


38-38: Conditional rendering has been updated to include OSS type.

The form items have been correctly updated to display for both OBS and OSS types using the *ngIf directive.

Also applies to: 58-58, 78-78, 98-98, 118-118


46-49:

✅ Verification successful

Placeholder text conditionally changes based on selected store type.

The implementation correctly switches between OBS and OSS placeholders based on the selected storage type. Make sure that all the referenced translation keys exist in the localization files.

Also applies to: 65-69, 85-89, 105-109, 125-129


🏁 Script executed:

#!/bin/bash
# Check if the OSS-related translation keys exist in localization files
rg "settings.object-store.oss" web-app/src/assets/i18n/

Length of output: 3169


🏁 Script executed:

#!/bin/bash
# Check if the OBS-related translation keys exist in localization files
rg "settings.object-store.obs" web-app/src/assets/i18n/

Length of output: 3165


Approve conditional placeholder implementation

I confirm that the template correctly switches between OBS and OSS placeholders based on the selected store type, and all referenced i18n keys exist in zh‑CN, zh‑TW, and en‑US files. No further action is needed.

• Affected file:
web-app/src/app/routes/setting/settings/object-store/object-store.component.html
– Lines 46–49, 65–69, 85–89, 105–109, 125–129

web-app/src/assets/i18n/en-US.json (2)

554-554: LGTM! Good job adding support for Alibaba Cloud OSS.

The entry for Alibaba Cloud OSS in the file server provider dropdown menu is properly added and follows the same format as the existing Huawei Cloud OBS option.


565-574: LGTM! Configuration entries are complete and consistent.

The localization entries for OSS configuration fields (AccessKey, SecretKey, BucketName, EndPoint, and SavePath) are properly implemented with clear labels and helpful placeholder text. They follow the same pattern as the existing Huawei Cloud OBS entries, maintaining consistency in the UI.

manager/src/main/java/org/apache/hertzbeat/manager/service/impl/OssObjectStoreServiceImpl.java (5)

32-36: LGTM! Implementation class properly defined.

The class declaration appropriately implements the ObjectStoreService interface and uses @slf4j for logging.


43-51: LGTM! Constructor properly handles path normalization.

The constructor correctly initializes the required fields and normalizes the root path by removing a leading dash if present.


60-70: LGTM! Good error handling in download method.

The download method properly handles exceptions by catching them, logging a warning, and returning null.


81-84: LGTM! Type method correctly returns OSS enum value.

The type method properly returns the OSS enum value from ObjectStoreDTO.Type.


87-89: LGTM! Helper method properly constructs object key.

The getObjectKey helper method correctly concatenates the root path and file path with a dash separator.

Comment on lines +53 to +58
@Override
public boolean upload(String filePath, InputStream is) {
var objectKey = getObjectKey(filePath);
var response = ossClient.putObject(bucketName, objectKey, is);
return Objects.equals(response.getResponse().getStatusCode(), 200);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling to prevent uncaught exceptions.

The upload method doesn't have any exception handling, which could cause unexpected crashes if the OSS client throws an exception during upload.

@Override
public boolean upload(String filePath, InputStream is) {
-    var objectKey = getObjectKey(filePath);
-    var response = ossClient.putObject(bucketName, objectKey, is);
-    return Objects.equals(response.getResponse().getStatusCode(), 200);
+    try {
+        var objectKey = getObjectKey(filePath);
+        var response = ossClient.putObject(bucketName, objectKey, is);
+        return response.getResponse() != null && 
+               Objects.equals(response.getResponse().getStatusCode(), 200);
+    } catch (Exception ex) {
+        log.error("Failed to upload file to OSS: {}", filePath, ex);
+        return false;
+    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
public boolean upload(String filePath, InputStream is) {
var objectKey = getObjectKey(filePath);
var response = ossClient.putObject(bucketName, objectKey, is);
return Objects.equals(response.getResponse().getStatusCode(), 200);
}
@Override
public boolean upload(String filePath, InputStream is) {
try {
var objectKey = getObjectKey(filePath);
var response = ossClient.putObject(bucketName, objectKey, is);
return response.getResponse() != null &&
Objects.equals(response.getResponse().getStatusCode(), 200);
} catch (Exception ex) {
log.error("Failed to upload file to OSS: {}", filePath, ex);
return false;
}
}

Comment on lines +72 to +79
@Override
public List<FileDTO> list(String dir) {
var request = new ListObjectsRequest(bucketName);
request.setPrefix(getObjectKey(dir));
return ossClient.listObjects(request).getObjectSummaries().stream()
.map(OSSObjectSummary::getKey).toList().stream()
.map(k -> new FileDTO(k, ossClient.getObject(bucketName, k).getObjectContent())).toList();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling and performance in list method.

The list method has two issues:

  1. No exception handling, which could lead to unexpected crashes
  2. Each object is fetched individually with a separate API call, which can be inefficient for directories with many files
@Override
public List<FileDTO> list(String dir) {
+    try {
        var request = new ListObjectsRequest(bucketName);
        request.setPrefix(getObjectKey(dir));
-        return ossClient.listObjects(request).getObjectSummaries().stream()
-                .map(OSSObjectSummary::getKey).toList().stream()
-                .map(k -> new FileDTO(k, ossClient.getObject(bucketName, k).getObjectContent())).toList();
+        var summaries = ossClient.listObjects(request).getObjectSummaries();
+        return summaries.stream()
+                .map(summary -> {
+                    try {
+                        String key = summary.getKey();
+                        var object = ossClient.getObject(bucketName, key);
+                        return new FileDTO(key, object.getObjectContent());
+                    } catch (Exception e) {
+                        log.warn("Failed to get object content for key: {}", summary.getKey(), e);
+                        return null;
+                    }
+                })
+                .filter(Objects::nonNull)
+                .toList();
+    } catch (Exception ex) {
+        log.error("Failed to list files from OSS directory: {}", dir, ex);
+        return List.of();
+    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
public List<FileDTO> list(String dir) {
var request = new ListObjectsRequest(bucketName);
request.setPrefix(getObjectKey(dir));
return ossClient.listObjects(request).getObjectSummaries().stream()
.map(OSSObjectSummary::getKey).toList().stream()
.map(k -> new FileDTO(k, ossClient.getObject(bucketName, k).getObjectContent())).toList();
}
@Override
public List<FileDTO> list(String dir) {
try {
var request = new ListObjectsRequest(bucketName);
request.setPrefix(getObjectKey(dir));
var summaries = ossClient.listObjects(request).getObjectSummaries();
return summaries.stream()
.map(summary -> {
try {
String key = summary.getKey();
var object = ossClient.getObject(bucketName, key);
return new FileDTO(key, object.getObjectContent());
} catch (Exception e) {
log.warn("Failed to get object content for key: {}", summary.getKey(), e);
return null;
}
})
.filter(Objects::nonNull)
.toList();
} catch (Exception ex) {
log.error("Failed to list files from OSS directory: {}", dir, ex);
return List.of();
}
}

@arvi18
Copy link
Author

arvi18 commented Apr 29, 2025

/codehelper review

this.rootPath = rootPath;
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Consider adding a close() method to properly shut down the OSS client when it's no longer needed. The Alibaba OSS client resources should be released when done to prevent resource leaks.

var objectKey = getObjectKey(filePath);
var response = ossClient.putObject(bucketName, objectKey, is);
return Objects.equals(response.getResponse().getStatusCode(), 200);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: The response check may not be reliable. The OSS client's putObject method can return a response with null response field in some cases. Consider checking for exceptions instead of status code.

var request = new ListObjectsRequest(bucketName);
request.setPrefix(getObjectKey(dir));
return ossClient.listObjects(request).getObjectSummaries().stream()
.map(OSSObjectSummary::getKey).toList().stream()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance concern: This implementation loads all objects in memory at once. For directories with many files, this could lead to memory issues. Consider implementing pagination or streaming the results.

request.setPrefix(getObjectKey(dir));
return ossClient.listObjects(request).getObjectSummaries().stream()
.map(OSSObjectSummary::getKey).toList().stream()
.map(k -> new FileDTO(k, ossClient.getObject(bucketName, k).getObjectContent())).toList();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential resource leak: The OSS objects retrieved in the list method aren't being closed. Each getObject() call opens a stream that should be properly closed to avoid resource leaks.

Assert.hasText(ossConfig.getEndpoint(), "cannot find oss endpoint");
Assert.hasText(ossConfig.getBucketName(), "cannot find oss bucket name");

var ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKey(), ossConfig.getSecretKey());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing validation: Unlike the initOss method, there's no validation for the OSS client initialization. Consider adding error handling to check if the OSS client was successfully created.

@@ -83,10 +84,28 @@ public void handler(ObjectStoreDTO<T> config) {
initObs(config);
// case other object store service
}
if (config.getType() == ObjectStoreDTO.Type.OSS) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code structure: Consider using a switch statement instead of multiple if conditions for handling different object store types, which would be more maintainable as more store types are added.

/**
* <a href="https://oss.console.aliyun.com/services/tools">Alibaba Cloud OSS</a>
*/
OSS = 'OSS'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Consider adding a trailing comma after the OSS enum value for consistency with other enum values and to make future additions cleaner in git diffs.

@@ -66,14 +75,18 @@
/>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DRY principle: There's significant duplication in the HTML template for handling OBS and OSS configurations. Consider refactoring to use a common template or component for both cloud storage types to improve maintainability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants