diff --git a/plugin.xml b/plugin.xml
index 29af249..20e7f27 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -5,12 +5,13 @@
com.fanruan.fs
yes
no
- 1.3.5
+ 1.3.6
10.0~10.0
2021-03-11
richie
[2022-09-22]第三方组件升级。
[2022-07-25]修复http无法连接,而https和缺省的时候正常
[2022-06-30]新增enablePathStyleAccess、signerOverride后台配置
diff --git a/src/main/java/com/fanruan/fs/s3/repository/core/S3ResourceRepository.java b/src/main/java/com/fanruan/fs/s3/repository/core/S3ResourceRepository.java
index a99b34a..66f907e 100644
--- a/src/main/java/com/fanruan/fs/s3/repository/core/S3ResourceRepository.java
+++ b/src/main/java/com/fanruan/fs/s3/repository/core/S3ResourceRepository.java
@@ -87,6 +87,15 @@ public class S3ResourceRepository extends BaseResourceRepository {
ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucket)
.withPrefix(dir).withDelimiter(DELIMITER);
ObjectListing objectListing = s3.listObjects(listObjectsRequest);
+ collectFileEntry(result, objectListing);
+ while (objectListing.isTruncated()) {
+ objectListing = s3.listNextBatchOfObjects(objectListing);
+ collectFileEntry(result, objectListing);
+ }
+ return result.toArray(new FineFileEntry[0]);
+ }
+
+ private void collectFileEntry(List result, ObjectListing objectListing) {
for (S3ObjectSummary summary : objectListing.getObjectSummaries()) {
String key = summary.getKey();
if (!key.endsWith(DELIMITER)) {
@@ -98,8 +107,6 @@ public class S3ResourceRepository extends BaseResourceRepository {
entry.setDirectory(true);
result.add(entry);
}
-
- return result.toArray(new FineFileEntry[0]);
}
@Override
@@ -119,17 +126,6 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public void write(String path, byte[] data) {
-
- List paths = getAllNecessaryPath(path);
- for (int i = paths.size() - 1; i > 0; i--) {
- String parent = paths.get(i);
- PutObjectRequest req = new PutObjectRequest(bucket, parent, new ByteArrayInputStream(new byte[0]), buildEmptyMetadata());
- try {
- s3.putObject(req);
- } catch (Exception e) {
- LogKit.error("[S3] Failed to create parent path {}", parent);
- }
- }
ObjectMetadata metadata;
try {
metadata = s3.getObjectMetadata(bucket, path);
@@ -150,16 +146,16 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public boolean createFile(String path) {
- List paths = getAllNecessaryPath(path);
- for (int i = paths.size() - 1; i >= 0; i--) {
- String parent = paths.get(i);
- PutObjectRequest req = new PutObjectRequest(bucket, parent, new ByteArrayInputStream(new byte[0]), buildEmptyMetadata());
- try {
- s3.putObject(req);
- } catch (Exception e) {
- LogKit.error("[S3] Failed to create parent path {}", parent);
- return false;
- }
+ String parent = path.substring(0, path.lastIndexOf(DELIMITER) + 1);
+ if (!dirExist(parent)) {
+ createDirectory(parent);
+ }
+ PutObjectRequest req = new PutObjectRequest(bucket, path, new ByteArrayInputStream(new byte[0]), buildEmptyMetadata());
+ try {
+ s3.putObject(req);
+ } catch (Exception e) {
+ LogKit.error("[S3] Failed to create file path {}", path);
+ return false;
}
return true;
}
@@ -170,17 +166,23 @@ public class S3ResourceRepository extends BaseResourceRepository {
if (!path.endsWith(DELIMITER)) {
path += DELIMITER;
}
- List paths = getAllNecessaryPath(path);
- for (int i = paths.size() - 1; i >= 0; i--) {
- String parent = paths.get(i);
- PutObjectRequest req = new PutObjectRequest(bucket, parent, new ByteArrayInputStream(new byte[0]), buildEmptyMetadata());
- try {
- s3.putObject(req);
- } catch (Exception e) {
- LogKit.error("[S3] Failed to create parent path {}", parent);
+ String temp = path.substring(0, path.length() - 1);
+ String parent = temp.substring(0, temp.lastIndexOf(DELIMITER) + 1);
+ if (StringUtils.isEmpty(parent)) {
+ return true;
+ }
+ if (!dirExist(parent)) {
+ if (!createDirectory(parent)) {
return false;
}
}
+ PutObjectRequest req = new PutObjectRequest(bucket, path, new ByteArrayInputStream(new byte[0]), buildEmptyMetadata());
+ try {
+ s3.putObject(req);
+ } catch (Exception e) {
+ LogKit.error("[S3] Failed to create parent path {}", path);
+ return false;
+ }
return true;
}
@@ -214,13 +216,49 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public boolean exist(String path) {
+ return fileExist(path) || (!path.endsWith(DELIMITER) && dirExist(path)) || isParentPathAbsent(path);
+ }
+
+ private boolean fileExist(String path) {
try {
- return s3.doesObjectExist(bucket, path) || s3.doesObjectExist(bucket, path + DELIMITER);
+ return s3.doesObjectExist(bucket, path);
} catch (Exception e) {
return false;
}
}
+ private boolean dirExist(String path) {
+ if (StringUtils.equals(path, DELIMITER)) {
+ return true;
+ }
+ if (!path.endsWith(DELIMITER)) {
+ path += DELIMITER;
+ }
+ return fileExist(path);
+ }
+
+ /**
+ * 如果存在文件创建了,但是其父目录没有创建的场景,为其递归创建对象,返回创建结果
+ */
+ private boolean isParentPathAbsent(String path) {
+ if (path.startsWith(DELIMITER)) {
+ path = path.substring(1);
+ }
+ if (path.endsWith(DELIMITER)) {
+ path = path.substring(0, path.length() - 1);
+ }
+ ObjectListing objectListing = s3.listObjects(
+ new ListObjectsRequest()
+ .withBucketName(bucket)
+ .withPrefix(path));
+ for (S3ObjectSummary summary : objectListing.getObjectSummaries()) {
+ if (summary.getKey().startsWith(path + DELIMITER)) {
+ return createDirectory(path);
+ }
+ }
+ return false;
+ }
+
@Override
public String[] list(String dir, final Filter filter) {
List result = new ArrayList<>();
diff --git a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3.properties b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3.properties
index 9eca906..68d23b5 100644
--- a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3.properties
+++ b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3.properties
@@ -4,4 +4,6 @@ Plugin-S3_Region=Region
Plugin-S3_Access_Key_Id=AccessKeyId
Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket
-Dec-Error_Start_With_Slash_Or_End_Without_Slash=The path cannot start with "/", but must end with "/"
\ No newline at end of file
+Dec-Error_Start_With_Slash_Or_End_Without_Slash=The path cannot start with "/", but must end with "/"
+Plugin-S3_Other_Config=
+Plugin-S3_EnablePathStyleAccess_Error_Tip=
\ No newline at end of file
diff --git a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en_US.properties b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en_US.properties
index 9e212ba..672a96a 100644
--- a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en_US.properties
+++ b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en_US.properties
@@ -4,4 +4,6 @@ Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket
Plugin-S3_End_Point=Endpoint
Plugin-S3_Input=Please input
-Plugin-S3_Region=Region
\ No newline at end of file
+Plugin-S3_Region=Region
+Plugin-S3_Other_Config=
+Plugin-S3_EnablePathStyleAccess_Error_Tip=
\ No newline at end of file
diff --git a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ja_JP.properties b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ja_JP.properties
index 0276339..7219376 100644
--- a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ja_JP.properties
+++ b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ja_JP.properties
@@ -4,4 +4,6 @@ Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket
Plugin-S3_End_Point=Endpoint
Plugin-S3_Input=\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
-Plugin-S3_Region=Region
\ No newline at end of file
+Plugin-S3_Region=Region
+Plugin-S3_Other_Config=
+Plugin-S3_EnablePathStyleAccess_Error_Tip=
\ No newline at end of file
diff --git a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ko_KR.properties b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ko_KR.properties
index 6380db9..6f1388f 100644
--- a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ko_KR.properties
+++ b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ko_KR.properties
@@ -4,4 +4,6 @@ Plugin-S3_Access_Key_Secret=
Plugin-S3_Bucket=
Plugin-S3_End_Point=
Plugin-S3_Input=
-Plugin-S3_Region=
\ No newline at end of file
+Plugin-S3_Region=
+Plugin-S3_Other_Config=
+Plugin-S3_EnablePathStyleAccess_Error_Tip=
\ No newline at end of file
diff --git a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_CN.properties b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_CN.properties
index 91b6745..bc49f24 100644
--- a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_CN.properties
+++ b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_CN.properties
@@ -4,4 +4,6 @@ Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket
Plugin-S3_End_Point=Endpoint
Plugin-S3_Input=\u8BF7\u8F93\u5165
-Plugin-S3_Region=Region
\ No newline at end of file
+Plugin-S3_Region=Region
+Plugin-S3_Other_Config=\u66f4\u591a\u8bbe\u7f6e
+Plugin-S3_EnablePathStyleAccess_Error_Tip=\u8bf7\u8f93\u5165true\u6216false
\ No newline at end of file
diff --git a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_TW.properties b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_TW.properties
index 019e745..876d58a 100644
--- a/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_TW.properties
+++ b/src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_TW.properties
@@ -4,4 +4,6 @@ Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket
Plugin-S3_End_Point=Endpoint
Plugin-S3_Input=\u8ACB\u8F38\u5165
-Plugin-S3_Region=Region
\ No newline at end of file
+Plugin-S3_Region=Region
+Plugin-S3_Other_Config=
+Plugin-S3_EnablePathStyleAccess_Error_Tip=
\ No newline at end of file
diff --git a/src/main/resources/com/fanruan/fs/s3/repository/web/js/bundle.js b/src/main/resources/com/fanruan/fs/s3/repository/web/js/bundle.js
index d47df6d..af8b1bd 100644
--- a/src/main/resources/com/fanruan/fs/s3/repository/web/js/bundle.js
+++ b/src/main/resources/com/fanruan/fs/s3/repository/web/js/bundle.js
@@ -137,11 +137,77 @@ BI.config("dec.constant.intelligence.cluster.file.server", function (items) {
ref: function (_ref) {
self.filePathRow = _ref;
},
- }],
+ }, {
+ type: "bi.vertical_adapt",
+ items: [{
+ type: "bi.icon_change_button",
+ iconCls: this.model.isOpen ? "expander-down-font" : "expander-right-font",
+ ref: (_ref) => {
+ this.OtherConfigButton = _ref;
+ },
+ handler: () => {
+ this.store.setIsOpen(!this.model.isOpen);
+ this.OtherConfigButton.setIcon(this.model.isOpen ? "expander-down-font" : "expander-right-font");
+ }
+ }, {
+ type: "bi.text_button",
+ text: BI.i18nText('Plugin-S3_Other_Config'),
+ handler: () => {
+ this.store.setIsOpen(!this.model.isOpen);
+ this.OtherConfigButton.setIcon(this.model.isOpen ? "expander-down-font" : "expander-right-font");
+ }
+ }]
+ }, {
+ type: 'bi.vertical',
+ invisible: () => !this.model.isOpen,
+ items: [{
+ type: "dec.label.editor.item",
+ textWidth: LABEL_WIDTH,
+ editorWidth: EDITOR_WIDTH,
+ watermark: BI.i18nText("Plugin-S3_Input"),
+ text: "PathStyleAccess",
+ value: this.model.enablePathStyleAccess,
+ ref: function (_ref) {
+ self.enablePathStyleAccessRow = _ref;
+ },
+ el: {
+ disabled: !o.editable,
+ },
+ listeners: [{
+ eventName: BI.Editor.EVENT_CHANGE,
+ action: function () {
+ self.store.setEnablePathStyleAccess(this.getValue());
+ }
+ }]
+ }, {
+ type: "dec.label.editor.item",
+ textWidth: LABEL_WIDTH,
+ editorWidth: EDITOR_WIDTH,
+ watermark: BI.i18nText("Plugin-S3_Input"),
+ text: "SignerOverride",
+ value: this.model.signerOverride,
+ el: {
+ disabled: !o.editable,
+ },
+ tgap: 15,
+ listeners: [{
+ eventName: BI.Editor.EVENT_CHANGE,
+ action: function () {
+ self.store.setSignerOverride(this.getValue());
+ }
+ }]
+ }],
+ }
+ ]
};
},
getValue: function () {
+ var enablePathStyleAccess = false;
+ if (this.model.enablePathStyleAccess === 'true') {
+ enablePathStyleAccess = true;
+ }
+
return {
endPoint: this.model.endPoint,
region: this.model.region,
@@ -149,6 +215,8 @@ BI.config("dec.constant.intelligence.cluster.file.server", function (items) {
password: this.passwordRow.getCipher(),
bucket: this.model.bucket,
workRoot: this.filePathRow.getValue(),
+ enablePathStyleAccess,
+ signerOverride: this.model.signerOverride,
};
},
@@ -167,6 +235,10 @@ BI.config("dec.constant.intelligence.cluster.file.server", function (items) {
this.filePathRow.showError(BI.i18nText("Dec-Error_Null"));
valid = false;
}
+ if (!(this.model.enablePathStyleAccess === 'false' || this.model.enablePathStyleAccess === 'true')) {
+ this.enablePathStyleAccessRow.showError(BI.i18nText("Plugin-S3_EnablePathStyleAccess_Error_Tip"));
+ valid = false;
+ }
return valid;
},
@@ -189,6 +261,9 @@ BI.config("dec.constant.intelligence.cluster.file.server", function (items) {
password: val.password,
bucket: val.bucket,
workRoot: val.workRoot,
+ isOpen: false,
+ enablePathStyleAccess: 'false',
+ signerOverride: "",
};
},
@@ -218,6 +293,18 @@ BI.config("dec.constant.intelligence.cluster.file.server", function (items) {
setBucket: function (v) {
this.model.bucket = v;
},
+
+ setEnablePathStyleAccess: function (v) {
+ this.model.enablePathStyleAccess = v;
+ },
+
+ setSignerOverride: function (v) {
+ this.model.signerOverride = v;
+ },
+
+ setIsOpen: function (v) {
+ this.model.isOpen = v;
+ },
},
});
BI.model("dec.model.intelligence.cluster.file.s3", Model);