Compare commits

...

195 Commits

Author SHA1 Message Date
superman 26510cffb8 Merge pull request #1467 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 1 week ago
LyKay-王积凯 5a967e3edb Pull request #1465: 11.0.32插件改动合并 1 week ago
Afly-储泓飞 ebb561fd36 Pull request #1450: REPORT-146048 fix: 测试连接及目录识别问题修改 2 weeks ago
Afly 65099c738d REPORT-146048 fix: 处理下每次只返回了部分对象的问题 2 weeks ago
Afly 17514e7efb Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 2 weeks ago
Afly 44a345b372 REPORT-146048 fix:测试连接及目录识别问题修改 2 weeks ago
superman d1ad81a9e8 Merge pull request #1367 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 2 months ago
LyKay-王积凯 0f5c47c6ff Pull request #1365: 11.0.31插件改动合并 2 months ago
Afly-储泓飞 f7ac7f6d31 Pull request #1340: 无jira任务 fix: 修改下preserveMetadata配置的效果 2 months ago
Afly fe89ed9439 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 2 months ago
Afly e7ef7f5871 无jira任务 fix: 修改下preserveMetadata配置的效果 2 months ago
inter 532f488a8a Pull request #1277: 无jira任务 国际化更新 3 months ago
Cici.Liu 9f4e97ad6e Translated using Weblate (Korean) 3 months ago
Afly-储泓飞 856f7c5131 Pull request #1215: REPORT-128310 fix: 配置的项的默认值和之前保持一致 4 months ago
Afly 01468c0949 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 4 months ago
Afly 51d1a38276 REPORT-128310 fix: 配置的项的默认值和之前保持一直 4 months ago
Afly-储泓飞 6cdfcab3bf Pull request #1114: REPORT-117434 && REPORT-128310 fix: 第三方依赖升级;虚拟目录识别变成一个配置项 6 months ago
Afly c28babacf8 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 6 months ago
Afly 53a4373973 REPORT-128310 fix: 虚拟目录识别变成一个配置项 6 months ago
Afly aed6673e94 REPORT-117434 fix: 第三方依赖升级 6 months ago
inter 19ff6ecf3f Pull request #987: 无jira任务 国际化更新 8 months ago
inter e30f6ba0ba Update src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ja_JP.properties 8 months ago
Caroline 8555366f91 Translated using Weblate (Japanese) 9 months ago
superman 14b2a65bda Merge pull request #908 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 10 months ago
LyKay-王积凯 b9e346241f Pull request #906: 11.0.26 插件改动合并 10 months ago
inter 8981a0fecf Pull request #881: 无jira任务 国际化更新 10 months ago
inter b1eee3977c Update plugin.xml 10 months ago
inter bbe4ba9c99 Update plugin.xml 10 months ago
inter 7a61b91bda Pull request #864: 无jira任务 国际化更新 10 months ago
Chauvet 450d70a096 Translated using Weblate (English) 10 months ago
Lauren.Wu ebdd5284bc Translated using Weblate (Chinese (Traditional)) 10 months ago
inter 2e022dfbe9 s3_en.properties edited online with Bitbucket 10 months ago
inter 46c7dce450 s3_zh.properties edited online with Bitbucket 10 months ago
inter 11da18fc2d Update src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_CN.properties 10 months ago
inter 395cbb7e64 Update src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en_US.properties 10 months ago
inter c5aa4f6d4e Update src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ko_KR.properties 10 months ago
inter fc73eda3f8 Update src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_TW.properties 10 months ago
inter afef09b0ca Update plugin.xml 10 months ago
superman d3e4aa839b Merge pull request #825 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 11 months ago
LyKay-王积凯 3b492bac70 Pull request #823: 11.0.25 版本 插件改动合并 11 months ago
Afly-储泓飞 b3caf72fb9 Pull request #804: REPORT-112857 fix: 改下isDir的写法 11 months ago
Afly f0809bb516 REPORT-112857 fix: 改下isDir的写法 11 months ago
Afly 2e2ffa713d Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 11 months ago
Afly 32d148cbb2 REPORT-112857 fix: 改下isDir的写法 11 months ago
Afly-储泓飞 a64686a904 Pull request #705: REPORT-112563 fix: 修改getEntry方法 1 year ago
Afly 1db7d2bc1d Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 1 year ago
Afly aa27d922ab REPORT-112563 fix: 修改getEntry方法 1 year ago
superman c4f8ba5179 Merge pull request #704 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 1 year ago
Lipei-李培 c557fa2045 Pull request #702: 11.0.24-0102版本插件改动合并 1 year ago
Afly-储泓飞 5557571834 Pull request #687: REPORT-110235 fix: 漏提交代码 1 year ago
Afly 347f02c22b REPORT-110235 fix: 漏提交代码 1 year ago
Afly-储泓飞 05785ebf85 Pull request #648: REPORT-110235 fix: 新增是否保留Metadata的配置 1 year ago
Afly af3030e1d4 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 1 year ago
Afly e697d57598 REPORT-110235 fix: 新增是否保留Metadata的配置 1 year ago
superman a0d5c1ebfb Merge pull request #645 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 1 year ago
Icey.Zhang-张洁 80f7e61d92 Pull request #642: 11.0.23版本插件代码合并 1 year ago
Afly-储泓飞 c6d22f38b6 Pull request #614: REPORT-109024 fix: 小文件不使用分片上传 1 year ago
Afly 550382e28e Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 1 year ago
Afly 07ab867c26 REPORT-109024 fix: 小文件不使用分片上传 1 year ago
superman fa3cdc7a71 Merge pull request #411 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 1 year ago
Icey.Zhang-张洁 f5a08831a9 Pull request #409: 11.0-插件紧急发布 1 year ago
Afly-储泓飞 3a89ec51f6 Pull request #408: 无jira任务 fix: 提升插件版本 1 year ago
AeolusZane 74c4068979 无jira任务,S3默认配置设置为false 1 year ago
Afly 687c1715aa Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 1 year ago
Afly e569e0e87a 无jira任务 fix: 提升插件版本 1 year ago
Afly-储泓飞 cfc791698d Pull request #401: REPORT-102146 && JSY-28624 fix: isDirectory方法某些场景判断不正确;优化下分片上传逻辑 1 year ago
Afly 8051a92c88 JSY-28624 fix: 优化下分片上传逻辑 1 year ago
Afly 0ae4e3674b REPORT-102146 fix: isDirectory方法某些场景判断不正确 1 year ago
Aeolus.Zhang-张敬峥 b502148359 打包 2 years ago
Aeolus.Zhang-张敬峥 ce9b12a50b Merge branch 'release/11.0' of ssh://code.fineres.com:7999/pg/plugin-repository-s3 into release/11.0 2 years ago
Aeolus.Zhang-张敬峥 d7357e83d9 REPORT-99625 fix:enablePathStyleAccess默认false 2 years ago
Aeolus.Zhang-张敬峥 3213faf55a REPORT-99625 fix:enablePathStyleAccess默认false 2 years ago
superman 3ad30598dc Merge pull request #378 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 2 years ago
Icey.Zhang-张洁 923dd4261a Pull request #376: 11.0.19版本插件代码合并 2 years ago
Afly-储泓飞 3cf593f1c9 Pull request #371: REPORT-100817 fix: s3插件对于分片上传的支持 2 years ago
Afly 42bc64567d Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 2 years ago
Afly d4e744b798 REPORT-100817 fix: s3插件对于分片上传的支持 2 years ago
Afly 047402bc02 REPORT-100817 fix: s3插件对于分片上传的支持 2 years ago
Aeolus.Zhang-张敬峥 68aaa757c2 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/pg/plugin-repository-s3 into release/11.0 2 years ago
Aeolus.Zhang-张敬峥 e6d47da394 REPORT-99625 fix:enablePathStyleAccess默认false 2 years ago
Afly-储泓飞 27e7887de1 Pull request #323: 无jira任务 chore: 提升版本 2 years ago
Afly a80537696d Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 2 years ago
Afly 9c5b9ffcc0 无jira任务 chore: 提升版本 2 years ago
Afly-储泓飞 020abae898 Pull request #289: REPORT-98184 fix: 测试连接后释放资源;list接口过滤自身目录 2 years ago
Afly 2bd592e352 无jira任务 fix: 测试连接后释放资源;list接口过滤自身目录 2 years ago
Aeolus.Zhang-张敬峥 526508dd27 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/pg/plugin-repository-s3 into release/11.0 2 years ago
Aeolus.Zhang-张敬峥 2c8bab646c 无jira任务 变量判断 2 years ago
Afly-储泓飞 79b214854e Pull request #276: REPORT-97765 feat: s3插件支持配置连接池大小 2 years ago
Afly 974c7e2b42 REPORT-97765 feat: s3插件支持配置连接池大小 2 years ago
Afly d5e6992dda REPORT-97765 feat: s3插件支持配置连接池大小 2 years ago
Aeolus.Zhang-张敬峥 729dadf90d enablePathStyleAccess验证问题 2 years ago
Aeolus.Zhang-张敬峥 983bb3bee4 console 2 years ago
Aeolus.Zhang-张敬峥 5693ab13b7 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/pg/plugin-repository-s3 into release/11.0 2 years ago
Aeolus.Zhang-张敬峥 8ad56d3eb3 REPORT-97243 fix:值显示undefined 2 years ago
superman 3fefcd51e3 Merge pull request #265 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 2 years ago
Icey.Zhang-张洁 4425926cd5 Pull request #263: 11.0.17版本插件代码合并 2 years ago
Aeolus.Zhang-张敬峥 706604a5af Merge branch 'release/11.0' of ssh://code.fineres.com:7999/pg/plugin-repository-s3 into release/11.0 2 years ago
Aeolus.Zhang-张敬峥 883e5c77a1 无jira任务,s3插件默认参数读取 2 years ago
Afly-储泓飞 62429affc9 Pull request #242: REPORT-96529 fix: list接口数量限制;删除接口性能优化 2 years ago
Afly 23d0b22f85 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 2 years ago
Afly 380c2dbe73 REPORT-96529 fix: list接口数量限制;删除接口性能优化 2 years ago
Aeolus.Zhang-张敬峥 dfdb4f73c5 无jira任务,s3插件默认参数读取 2 years ago
Ocean.Hu-胡浩 4709bb13c7 Pull request #210: 无jira任务,提升jartime和版本号 2 years ago
Ocean.Hu 66033cd226 Merge remote-tracking branch 'origin/release/11.0' into release/11.0 2 years ago
Ocean.Hu 1e383f96f0 无jira任务,提升jartime和版本号 2 years ago
Ocean.Hu-胡浩 69e19ba838 Pull request #206: REPORT-95454 bugfix:http配置根据endpoint进行设置 2 years ago
Ocean.Hu 9776c12c71 REPORT-95454 bugfix:http配置根据endpoint进行设置 2 years ago
Afly-储泓飞 70b124bab9 Pull request #120: REPORT-91781 fix: 三方组件升级 2 years ago
Afly 9905ff5db6 REPORT-91781 fix: 三方组件升级 2 years ago
superman 5ec30e6b98 Merge pull request #97 in PG/plugin-repository-s3 from persist/11.0 to release/11.0 2 years ago
Aeolus.Zhang-张敬峥 600f1ebd33 REPORT-91281 fix:插件加密方法修改 2 years ago
Icey.Zhang-张洁 ac42ffa4d1 Pull request #88: Release/11.0 2 years ago
Afly-储泓飞 b4efb4c951 Pull request #86: REPORT-88094 fix: 文件数量较多时,listEntry结果不全 2 years ago
Afly 9df410a237 REPORT-88094 fix: change-notes 2 years ago
Afly da7ee21d50 REPORT-88094 fix: 文件数量较多时,listEntry结果不全 2 years ago
Freddy-李飞宇 cbf0a67324 Pull request #84: REPORT-87924 fix:增加输入限制 2 years ago
Freddy 39f1bea676 REPORT-87924 fix:增加输入限制 2 years ago
Freddy-李飞宇 fc9189fc75 Pull request #83: REPORT-87924 feat:适配S3插件前台改动 2 years ago
Freddy c4cfbc8033 REPORT-87924 feat:适配S3插件前台改动 2 years ago
Afly-储泓飞 e0bb7ccb9b Pull request #82: 无jira任务 perf: 优化写文件性能 2 years ago
Afly 582fd2d3c0 无jira任务 perf: 优化写文件性能 2 years ago
tennyC-谭聪聪 27a8714b3f Pull request #78: Release/11.0 2 years ago
Afly-储泓飞 13332af770 Pull request #77: 无jira任务 feat: 提升版本号 2 years ago
Afly 9ecfeaed5c 无jira任务 feat: 提升版本号 2 years ago
Afly-储泓飞 1e89092317 Pull request #74: RREPORT-80581 fix: 第三方组件升级 2 years ago
Afly 8b110c2425 RREPORT-80581 fix: 第三方组件升级 2 years ago
Icey.Zhang f3b8700e52 Pull request #71: 11.0.7-0803迭代版本插件代码合并 3 years ago
Icey.Zhang 3c088feaad Pull request #68: REPORT-76271 忘记更新插件版本号信息了,补一下插件的版本号信息 3 years ago
Ocean c25ba7c870 Merge remote-tracking branch 'origin/release/11.0' into release/11.0 3 years ago
Ocean 2bfac99c98 REPORT-76271 忘记更新插件版本号信息了,补一下插件的版本号信息 3 years ago
Ocean.Hu 4f1873fbfc Pull request #67: REPORT-76271 修复智能运维->集群配置界面,S3文件仓库无法使用http连接的问题 3 years ago
Ocean 2d554e9a25 REPORT-76271 修复智能运维->集群配置界面,S3文件仓库无法使用http连接的问题 3 years ago
Icey.Zhang de64b3a6cf Pull request #63: 11.0.6.1-0715维护版本插件代码合并 3 years ago
Afly 77ee1d9227 Pull request #61: REPORT-74814 feat: 新增两个后台配置项 3 years ago
Afly a3901cd06e REPORT-74814 feat: 新增两个后台配置项 3 years ago
Icey.Zhang a4b800248b Pull request #57: 11.0.6-0630迭代版本插件代码合并 3 years ago
Afly 6563376e98 Pull request #54: REPORT-72615 feat: 下个版本再内置,先回退 3 years ago
Afly c98a45e637 Merge branch 'release/11.0' of ssh://code.fineres.com:7999/~afly/plugin-repository-s3 into release/11.0 3 years ago
Afly 9580221e24 REPORT-72615 feat: 下个版本再内置,先回退 3 years ago
Afly 1dd2dcbe67 Pull request #52: REPORT-73356 && REPORT-72615 fix: 第三方组件升级,插件默认自动安装 3 years ago
Afly 0516aa2837 REPORT-73356 && REPORT-72615 fix: 第三方组件升级,插件默认自动安装 3 years ago
Icey.Zhang ecfe0eec98 Pull request #40: 11.0.3.1-0328维护版本插件代码合并 3 years ago
Afly 96077f1bbf Pull request #39: REPORT-67291 fix: 第三方组件升级 3 years ago
Afly ecd2da9775 REPORT-67291 fix: 第三方组件升级 3 years ago
Icey.Zhang 3ace1f233f Pull request #37: 11.0.2-0110迭代版本插件代码合并 3 years ago
lidongy 51c5478b2d Pull request #36: REPORT-64272 fix: fr-plugin-s3-repository插件中url更改 3 years ago
lidongy b8c38aaa18 Merge branch 'release/11.0' of https://code.fineres.com/scm/~lidongy/plugin-repository-s3 into release/11.0 3 years ago
lidongy 7b3ee6b47a REPORT-64272 fix: fr-plugin-s3-repository插件中url更改 3 years ago
lidongy d7c7630d03 Pull request #35: DEC-20707 chore: 提一下版本号 3 years ago
lidongy 4c5cb1a7d6 DEC-20707 chore: 提一下版本号 3 years ago
Icey.Zhang 102dc533e4 Pull request #34: 11.0-发布版本-1027版本插件代码合并 3 years ago
lidongy 6d75e6924c Pull request #33: 无jira任务 chore: 要发布了,修改change-note 3 years ago
lidongy 0bb59dd318 无jira任务 chore: 要发布了,修改change-note 3 years ago
lidongy 2537e05725 Pull request #31: DEC-20707 fix: s3直接通过判断名称 + "/"是否存在,来判断是否为文件夹 3 years ago
lidongy 0e76c422b6 DEC-20707 fix: s3直接通过判断名称 + "/"是否存在,来判断是否为文件夹 3 years ago
Dylan.Liu 2c042df4bd Pull request #26: init release/11.0 3 years ago
Dylan.Liu b84845ee29 init release/11.0 3 years ago
ju|剧浩宇 19dc9ba92e Pull request #24: INO-9768 跑FR 10.0.18国际化脚本+插件脚本 4 years ago
Joe.Jiang 8911690304 INO-9768 跑FR 10.0.18国际化脚本+插件脚本 4 years ago
Roger.Chen 41d0c61f78 Pull request #23: DEC-19779 fix: 添加一下国际化文件给国际组翻译 4 years ago
Roger.Chen 533df83872 DEC-19775 fix: 添加一下国际化文件给国际组翻译 4 years ago
Feng b6d9f00336 Pull request #21: DEC-18310 fix:文件服务器插件接口未兼容 4 years ago
Feng 4623bd97c8 DEC-18310 fix:文件服务器插件接口未兼容 4 years ago
Feng 8834f03f2b Pull request #20: QFX-5554 fix: 【冒烟】测试环境大数据量excel上传后点击保存无法保存成功 4 years ago
Feng cc8efcd603 QFX-5554 fix: 【冒烟】测试环境大数据量excel上传后点击保存无法保存成功 4 years ago
Feng 39b51beaf8 QFX-5554 fix: 【冒烟】测试环境大数据量excel上传后点击保存无法保存成功 4 years ago
Feng 3ddfba09e2 Pull request #17: 无jira 限制插件jartime 4 years ago
Feng 222b8c93e2 无jira 限制插件jartime 4 years ago
Frank.Qiu f5146deee0 Pull request #16: DEC-17106 fix: 【迭代】【S3插件】前端协议框与配置项框没有对齐 4 years ago
Frank.Qiu afbeeb7da0 DEC-17106 fix: 【迭代】【S3插件】前端协议框与配置项框没有对齐 4 years ago
Feng 7d2a958e8a Pull request #15: DEC-17012 fix: 【S3插件】备份文件删除后,实际文件服务器上文件未删除 4 years ago
Feng 3c1eb94de7 Merge remote-tracking branch 'origin/release/10.0' into release/10.0 4 years ago
Feng 4a0f1369d1 DEC-17012 fix: 【S3插件】备份文件删除后,实际文件服务器上文件未删除 4 years ago
Feng a56cdef22c Pull request #14: DEC-17013 fix: 【S3插件】备份模板很慢,有生成多余文件,后台很多警告 4 years ago
Feng 41d31de6e6 DEC-16997 fix: 【S3插件】定时调度的结果文件预览失败 4 years ago
Feng 9395670690 Merge remote-tracking branch 'origin/release/10.0' into release/10.0 4 years ago
Feng 893bbae5b4 DEC-17013 fix: 【S3插件】备份模板很慢,有生成多余文件,后台很多警告 4 years ago
Dylan.Liu 06689bd208 Pull request #12: DEC-16834 feat: 集群组件出错优化 4 years ago
Dylan.Liu 0402aa3a9e Merge branch 'release/10.0' of https://code.fineres.com/scm/~dylan.liu/plugin-repository-s3 into release/10.0 4 years ago
Dylan.Liu ac8ee784fe DEC-16834 feat: 集群组件出错优化 4 years ago
Feng 0506f22a5d Pull request #11: DEC-16997 fix: 【S3插件】定时调度的结果文件预览失败 4 years ago
Feng b3beded0f2 Merge remote-tracking branch 'origin/release/10.0' into release/10.0 4 years ago
Feng f16a557bf0 DEC-16997 fix: 【S3插件】定时调度的结果文件预览失败 4 years ago
Feng 2c5773904b DEC-16997 fix: 【S3插件】定时调度的结果文件预览失败 4 years ago
Feng 19a499536b Pull request #10: DEC-17006 fix: 【S3插件】配置输入不存在的路径也可以连接成功 4 years ago
Feng 39e97de37f DEC-17006 fix: 【S3插件】配置输入不存在的路径也可以连接成功 4 years ago
Feng d797433f1a Pull request #9: DEC-16411 feat: S3插件变为官方插件 国际化 4 years ago
Feng 1c342df1e0 DEC-16411 feat: S3插件变为官方插件 国际化 4 years ago
Feng 5724103649 DEC-16411 feat: S3插件变为官方插件 4 years ago
Feng dee24ab76e Pull request #8: DEC-16411 feat: S3插件变为官方插件 4 years ago
Feng 4bf15d218c DEC-16411 feat: S3插件变为官方插件 4 years ago
Feng b0a6e35c7c DEC-16411 feat: S3插件变为官方插件 4 years ago
Feng bba598df12 Pull request #6: DEC-16411 feat: S3插件作为官方插件维护 4 years ago
Feng ad2da13ab2 DEC-16411 S3仓库打包脚本 4 years ago
Feng ab60e1c61f DEC-16411 S3插件维护 4 years ago
  1. 2
      .gitignore
  2. 123
      build.xml
  3. 309
      front/bundle.js
  4. 10
      front/gulpfile.js
  5. 13
      front/package.json
  6. BIN
      lib/aws-java-sdk-core-1.11.801.jar
  7. BIN
      lib/aws-java-sdk-core-1.12.435.jar
  8. BIN
      lib/aws-java-sdk-kms-1.11.801.jar
  9. BIN
      lib/aws-java-sdk-kms-1.12.435.jar
  10. BIN
      lib/aws-java-sdk-s3-1.11.801.jar
  11. BIN
      lib/aws-java-sdk-s3-1.12.435.jar
  12. BIN
      lib/httpclient-4.5.13.jar
  13. BIN
      lib/ion-java-1.0.2.jar
  14. BIN
      lib/ion-java-1.11.9.jar
  15. BIN
      lib/jackson-annotations-2.17.2.jar
  16. BIN
      lib/jackson-annotations-2.6.0.jar
  17. BIN
      lib/jackson-core-2.17.2.jar
  18. BIN
      lib/jackson-core-2.6.7.jar
  19. BIN
      lib/jackson-databind-2.17.2.jar
  20. BIN
      lib/jackson-databind-2.6.7.3.jar
  21. BIN
      lib/jackson-dataformat-cbor-2.17.2.jar
  22. BIN
      lib/jackson-dataformat-cbor-2.6.7.jar
  23. BIN
      lib/jmespath-java-1.11.801.jar
  24. BIN
      lib/jmespath-java-1.12.762.jar
  25. 36
      plugin.xml
  26. 7
      readme.md
  27. 4
      src/main/java/com/fanruan/fs/s3/repository/S3FileServerResource.java
  28. 100
      src/main/java/com/fanruan/fs/s3/repository/core/S3Config.java
  29. 36
      src/main/java/com/fanruan/fs/s3/repository/core/S3RepositoryFactory.java
  30. 401
      src/main/java/com/fanruan/fs/s3/repository/core/S3ResourceRepository.java
  31. 3
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3.properties
  32. 12
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en.properties
  33. 6
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en_US.properties
  34. 12
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ja_JP.properties
  35. 12
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ko_KR.properties
  36. 12
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh.properties
  37. 6
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_CN.properties
  38. 12
      src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_TW.properties
  39. 192
      src/main/resources/com/fanruan/fs/s3/repository/web/js/bundle.js

2
.gitignore vendored

@ -8,3 +8,5 @@ build
local.properties
classes/
transform-classes/
node_modules/
*.lock

123
build.xml

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="jar" name="plugin-repository-s3">
<!-- JDK路径,根据自己机器上实际位置修改-->
<property name="jdk.home" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home"/>
<property name="libs" value="${basedir}/lib"/>
<property name="publicLibs" value=""/>
<property name="destLoc" value="."/>
<property name="classes" value="classes"/>
<xmlproperty file="${basedir}/plugin.xml"/>
<property name="current-version" value="${plugin.version}"/>
<!-- 插件版本-->
<property name="plugin-version" value="${current-version}"/>
<!-- 插件名字-->
<property name="plugin-name" value="s3-repository"/>
<property name="plugin-jar" value="fr-plugin-${plugin-name}-${plugin-version}.jar"/>
<target name="prepare">
<delete dir="${classes}"/>
<delete dir="fr-plugin-${plugin-name}-${plugin-version}"/>
<xmlproperty file="${basedir}/plugin.xml"/>
<delete dir="${destLoc}/${plugin.name}"/>
</target>
<path id="compile.classpath">
<fileset dir="${libs}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${publicLibs}">
<include name="**/*.jar"/>
</fileset>
</path>
<patternset id="resources4Jar">
<exclude name="**/.settings/**"/>
<exclude name=".classpath"/>
<exclude name=".project"/>
<exclude name="**/*.java"/>
<exclude name="**/*.db"/>
<exclude name="**/*.g"/>
<exclude name="**/package.html"/>
</patternset>
<target name="copy_resources">
<echo message="从${resources_from}拷贝图片,JS,CSS等资源文件"/>
<delete dir="tmp"/>
<copy todir="tmp">
<fileset dir="${resources_from}/src/main/resources">
<patternset refid="resources4Jar"/>
</fileset>
</copy>
<copy todir="${classes}">
<fileset dir="tmp"/>
</copy>
<delete dir="tmp"/>
</target>
<target name="compile_javas">
<echo message="编译${compile_files}下的Java文件"/>
<javac destdir="${classes}" debug="false" optimize="on" source="${source_jdk_version}"
target="${target_jdk_version}"
fork="true" memoryMaximumSize="512m" listfiles="false" srcdir="${basedir}"
executable="${compile_jdk_version}/bin/javac">
<src path="${basedir}/src/main/java"/>
<exclude name="**/.svn/**"/>
<compilerarg line="-encoding UTF8 "/>
<classpath refid="compile.classpath"/>
</javac>
</target>
<target name="jar_classes">
<echo message="打Jar包:${jar_name}"/>
<delete file="${basedir}/${jar_name}"/>
<jar jarfile="${basedir}/${jar_name}">
<fileset dir="${classes}">
</fileset>
</jar>
</target>
<target name="super_jar" depends="prepare">
<antcall target="copy_resources">
<param name="resources_from" value="${basedir}"/>
</antcall>
<antcall target="compile_javas">
<param name="source_jdk_version" value="1.8"/>
<param name="target_jdk_version" value="1.8"/>
<param name="compile_jdk_version" value="${jdk.home}"/>
<param name="compile_files" value="${basedir}/src"/>
</antcall>
<echo message="compile plugin success!"/>
<antcall target="jar_classes">
<param name="jar_name" value="${plugin-jar}"/>
</antcall>
<delete dir="${classes}"/>
</target>
<target name="jar" depends="super_jar">
<antcall target="zip"/>
</target>
<target name="zip">
<property name="plugin-folder" value="fr-plugin-${plugin-name}-${plugin-version}"/>
<echo message="----------zip files----------"/>
<mkdir dir="${plugin-folder}"/>
<copy todir="${plugin-folder}">
<fileset dir=".">
<include name="${plugin-jar}"/>
<include name="plugin.xml"/>
</fileset>
<fileset dir="${libs}">
<include name="*.jar"/>
<include name="*.dll"/>
</fileset>
</copy>
<zip destfile="${basedir}/${plugin-folder}.zip" basedir=".">
<include name="${plugin-folder}/*.jar"/>
<include name="${plugin-folder}/*.dll"/>
<include name="${plugin-folder}/plugin.xml"/>
</zip>
<xmlproperty file="${basedir}/plugin.xml"/>
<move file="${plugin-folder}.zip" todir="${destLoc}/${plugin.name}"/>
<delete dir="${plugin-folder}"/>
</target>
</project>

309
front/bundle.js

@ -0,0 +1,309 @@
BI.config("dec.constant.intelligence.cluster.file.server", function (items) {
items.push({
value: "S3", // 地址栏显示的hash值
id: "decision-intelligence-cluster-file-s3", // id
text: "S3", // 文字
cardType: "dec.intelligence.cluster.file.s3",
workRoot: false,
});
return items;
});
!(function () {
var LABEL_WIDTH = 107, EDITOR_WIDTH = 393;
var S3 = BI.inherit(BI.Widget, {
props: {
baseCls: "dec-cluster-ftp",
value: {},
},
_store: function () {
return BI.Models.getModel("dec.model.intelligence.cluster.file.s3", {
value: this.options.value,
});
},
render: function () {
var self = this, o = this.options;
return {
type: "bi.vertical",
tgap: 15,
items: [
{
type: "dec.label.editor.item",
textWidth: LABEL_WIDTH,
editorWidth: EDITOR_WIDTH,
watermark: BI.i18nText("Plugin-S3_Input"),
text: BI.i18nText("Plugin-S3_End_Point"),
value: this.model.endPoint,
el: {
disabled: !o.editable,
},
ref: function (_ref) {
self.endPointRow = _ref;
},
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action: function () {
self.store.setEndPoint(this.getValue());
},
}],
}, {
type: "dec.label.editor.item",
textWidth: LABEL_WIDTH,
editorWidth: EDITOR_WIDTH,
watermark: BI.i18nText("Plugin-S3_Input"),
text: BI.i18nText("Plugin-S3_Region"),
value: this.model.region,
el: {
disabled: !o.editable,
},
ref: function (_ref) {
self.regionRow = _ref;
},
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action: function () {
self.store.setRegion(this.getValue());
},
}],
}, {
type: "dec.label.editor.item",
textWidth: LABEL_WIDTH,
editorWidth: EDITOR_WIDTH,
watermark: BI.i18nText("Plugin-S3_Input"),
text: BI.i18nText("Plugin-S3_Access_Key_Id"),
value: this.model.accessKeyId,
el: {
disabled: !o.editable,
},
ref: function (_ref) {
self.portRow = _ref;
},
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action: function () {
self.store.setAccessKeyId(this.getValue());
},
}],
},
{
type: "dec.common.cipher.editor",
textWidth: LABEL_WIDTH,
editorWidth: EDITOR_WIDTH,
watermark: BI.i18nText("Plugin-S3_Access_Key_Secret"),
text: BI.i18nText("Plugin-S3_Access_Key_Secret"),
value: this.model.password,
el: {
disabled: !o.editable,
},
ref: function (_ref) {
self.passwordRow = _ref;
},
},
{
type: "dec.label.editor.item",
textWidth: LABEL_WIDTH,
editorWidth: EDITOR_WIDTH,
watermark: BI.i18nText("Plugin-S3_Bucket"),
text: BI.i18nText("Plugin-S3_Bucket"),
value: this.model.bucket,
el: {
disabled: !o.editable,
},
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action: function () {
self.store.setBucket(this.getValue());
},
}],
},
{
type: "dec.label.editor.item",
el: {
disabled: !o.editable,
},
textWidth: LABEL_WIDTH,
editorWidth: EDITOR_WIDTH,
watermark: BI.i18nText("Dec-Please_Input"),
text: BI.i18nText("Dec-Basic_Path"),
value: this.model.workRoot,
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,
accessKeyId: this.model.accessKeyId,
password: this.passwordRow.getCompleteCipher(),
bucket: this.model.bucket,
workRoot: this.filePathRow.getValue(),
enablePathStyleAccess,
signerOverride: this.model.signerOverride,
};
},
validation: function () {
var valid = true;
var path = this.filePathRow.getValue();
if (Dec.Utils.strLength(path) > DecCst.STRING_SHORT_TEXT_LENGTH) {
this.filePathRow.showError(BI.i18nText("Dec-Error_Length_Greater_Than_Short_Text"));
valid = false;
}
if (BI.startWith(path, "/") || !BI.endWith(path, "/")) {
this.filePathRow.showError(BI.i18nText("Dec-Error_Start_With_Slash_Or_End_Without_Slash"));
valid = false;
}
if (!BI.isKey(path)) {
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;
},
});
BI.shortcut("dec.intelligence.cluster.file.s3", S3);
}());
!(function () {
var Model = BI.inherit(Fix.Model, {
state: function () {
var val = this.options.value;
return {
endPoint: val.endPoint,
region: val.region,
accessKeyId: val.accessKeyId,
password: val.password,
bucket: val.bucket,
workRoot: val.workRoot,
isOpen: false,
enablePathStyleAccess: String(Boolean(val.enablePathStyleAccess)),
signerOverride: val.signerOverride,
};
},
computed: {
encodingArray: function () {
return BI.map(DecCst.EncodeConstants.ENCODING_ARRAY, function (i, v) {
return {
value: v,
};
});
},
},
actions: {
setEndPoint: function (v) {
this.model.endPoint = v;
},
setRegion: function (v) {
this.model.region = v;
},
setAccessKeyId: function (v) {
this.model.accessKeyId = v;
},
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);
}());

10
front/gulpfile.js

@ -0,0 +1,10 @@
const gulp = require('gulp');
const uglify = require('gulp-uglify');
function build() {
return gulp.src('./bundle.js')
.pipe(uglify())
.pipe(gulp.dest('../src/main/resources/com/fanruan/fs/s3/repository/web/js'));
}
exports.default = build;

13
front/package.json

@ -0,0 +1,13 @@
{
"name": "front",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "gulp"
},
"dependencies": {
"gulp": "^4.0.2",
"gulp-uglify": "^3.0.2"
}
}

BIN
lib/aws-java-sdk-core-1.11.801.jar

Binary file not shown.

BIN
lib/aws-java-sdk-core-1.12.435.jar

Binary file not shown.

BIN
lib/aws-java-sdk-kms-1.11.801.jar

Binary file not shown.

BIN
lib/aws-java-sdk-kms-1.12.435.jar

Binary file not shown.

BIN
lib/aws-java-sdk-s3-1.11.801.jar

Binary file not shown.

BIN
lib/aws-java-sdk-s3-1.12.435.jar

Binary file not shown.

BIN
lib/httpclient-4.5.9.jar → lib/httpclient-4.5.13.jar

Binary file not shown.

BIN
lib/ion-java-1.0.2.jar

Binary file not shown.

BIN
lib/ion-java-1.11.9.jar

Binary file not shown.

BIN
lib/jackson-annotations-2.17.2.jar

Binary file not shown.

BIN
lib/jackson-annotations-2.6.0.jar

Binary file not shown.

BIN
lib/jackson-core-2.17.2.jar

Binary file not shown.

BIN
lib/jackson-core-2.6.7.jar

Binary file not shown.

BIN
lib/jackson-databind-2.17.2.jar

Binary file not shown.

BIN
lib/jackson-databind-2.6.7.3.jar

Binary file not shown.

BIN
lib/jackson-dataformat-cbor-2.17.2.jar

Binary file not shown.

BIN
lib/jackson-dataformat-cbor-2.6.7.jar

Binary file not shown.

BIN
lib/jmespath-java-1.11.801.jar

Binary file not shown.

BIN
lib/jmespath-java-1.12.762.jar

Binary file not shown.

36
plugin.xml

@ -1,16 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fanruan.fs.s3.repository</id>
<id>com.fanruan.fs.s3.repository.v11</id>
<name><![CDATA[S3资源仓库]]></name>
<main-package>com.fanruan.fs</main-package>
<active>yes</active>
<hidden>no</hidden>
<version>1.2.2</version>
<env-version>10.0</env-version>
<jartime>2020-01-27</jartime>
<version>1.4.6</version>
<env-version>11.0~11.0</env-version>
<jartime>2023-03-14</jartime>
<vendor>richie</vendor>
<description><![CDATA[使用支持S3协议的云存储文件系统作为文件服务器。]]></description>
<change-notes><![CDATA[
[2025-01-04]测试连接逻辑修改、判断虚拟目录问题修复。 <br/>
[2024-07-25]第三方组件升级。 <br/>
[2024-03-13]国际化更新 <br/>
[2024-03-13]国际化更新 <br/>
[2023-11-21]小文件不使用分片上传, 新增preserveMetadata后台配置。 <br/>
[2023-08-08]分片上传逻辑优化,模板保存问题修复。 <br/>
[2023-07-24]支持大文件分片上传。 <br/>
[2023-06-30]修复默认配置获取错误的问题,过滤有问题的路径。 <br/>
[2023-03-28]第三方组件升级。 <br/>
[2023-01-03]优化写文件性能; 修复文件太多显示不全的问题。<br/>
[2022-09-22]第三方组件升级。 <br/>
[2022-07-25]修复http无法连接,而https和缺省的时候正常<br/>
[2022-06-30]新增enablePathStyleAccess、signerOverride后台配置<br/>
[2022-06-13]第三方组件升级<br/>
[2022-03-10]第三方组件升级<br/>
[2021-12-29]插件引用的url更改<br/>
[2021-10-08]修复文件夹误判问题。<br/>
[2021-07-16]提供韩文、日文、繁体等国际化文件。 <br/>
[2021-04-23]copyFile接口兼容。 <br/>
[2021-03-30]修复copy文件耗时问题。<br/>
[2021-01-28]修复备份还原S3报警告问题。<br/>
[2021-01-24]修复定时调度结果文件预览失败。<br/>
[2021-01-20]正式作为官方插件维护。<br/>
[2020-12-16]修复远程设计新增、修改模板问题。<br/>
[2020-10-29]修复连接不释放问题。<br/>
[2020-08-17]修复key不存在时报错的问题。<br/>
@ -36,4 +59,9 @@
</extra-core>
<!--功能记录点类-->
<function-recorder class="com.fanruan.fs.s3.repository.S3FactoryProvider"/>
<plugin-xml-i18n resource="fr-plugin-s3-repository-*.jar" location="com.fanruan.fs.s3.repository.locale">
<name key="Plugin-Xml-I18n-S3repository_Name"/>
<description key="Plugin-Xml-I18n-S3repository_Description"/>
<change-notes key="Plugin-Xml-I18n-S3repository_Change_Notes"/>
</plugin-xml-i18n>
</plugin>

7
readme.md

@ -3,3 +3,10 @@
能够使用支持S3协议的云存储,作为文件服务器,安装好插件后在决策平台的智能运维->集群配置->文件一致性设置选项下,按下图设置即可:
![ui](screenshots/s3.png)
# 前台gulp打包:
进入front文件夹:`cd front`
安装依赖:`yarn install`
打包:`yarn build`

4
src/main/java/com/fanruan/fs/s3/repository/S3FileServerResource.java

@ -1,7 +1,7 @@
package com.fanruan.fs.s3.repository;
import com.fr.decision.fun.impl.AbstractWebResourceProvider;
import com.fr.decision.web.MainComponent;
import com.fr.decision.web.CommonComponent;
import com.fanruan.fs.s3.repository.web.S3FileServerComponent;
import com.fr.web.struct.Atom;
@ -14,7 +14,7 @@ public class S3FileServerResource extends AbstractWebResourceProvider {
@Override
public Atom attach() {
return MainComponent.KEY;
return CommonComponent.KEY;
}
@Override

100
src/main/java/com/fanruan/fs/s3/repository/core/S3Config.java

@ -1,8 +1,8 @@
package com.fanruan.fs.s3.repository.core;
import com.fanruan.api.conf.HolderKit;
import com.fr.config.Identifier;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
import com.fr.io.config.CommonRepoConfig;
import com.fr.io.context.ResourceModuleContext;
import com.fr.io.context.info.GetConfig;
@ -21,19 +21,31 @@ public class S3Config extends CommonRepoConfig {
}
@Identifier("endPoint")
private Conf<String> endPoint = Holders.simple(StringUtils.EMPTY);
private Conf<String> endPoint = HolderKit.simple(StringUtils.EMPTY);
@Identifier("region")
private Conf<String> region = Holders.simple(StringUtils.EMPTY);
private Conf<String> region = HolderKit.simple(StringUtils.EMPTY);
@Identifier("accessKeyId")
private Conf<String> accessKeyId = Holders.simple(StringUtils.EMPTY);
@Identifier("accessKeySecret")
private Conf<String> accessKeySecret = Holders.simple(StringUtils.EMPTY);
private Conf<String> accessKeyId = HolderKit.simple(StringUtils.EMPTY);
@Identifier("bucket")
private Conf<String> bucket = Holders.simple(StringUtils.EMPTY);
private Conf<String> bucket = HolderKit.simple(StringUtils.EMPTY);
@Identifier("enablePathStyleAccess")
private Conf<Boolean> enablePathStyleAccess = HolderKit.simple(false);
@Identifier("signerOverride")
private Conf<String> signerOverride = HolderKit.simple(StringUtils.EMPTY);
@Identifier("maxConnections")
private Conf<Integer> maxConnections = HolderKit.simple(200);
@Identifier("preserveMetadata")
private Conf<Boolean> preserveMetadata = HolderKit.simple(true);
@Identifier("openVirtualDirectory")
private Conf<Boolean> openVirtualDirectory = HolderKit.simple(true);
@GetConfig("endPoint")
public String getEndPoint() {
@ -65,16 +77,6 @@ public class S3Config extends CommonRepoConfig {
this.accessKeyId.set(accessKeyId);
}
@GetConfig("accessKeySecret")
public String getAccessKeySecret() {
return accessKeySecret.get();
}
@SetConfig("accessKeySecret")
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret.set(accessKeySecret);
}
@GetConfig("bucket")
public String getBucket() {
return bucket.get();
@ -85,6 +87,56 @@ public class S3Config extends CommonRepoConfig {
this.bucket.set(bucket);
}
@GetConfig("enablePathStyleAccess")
public boolean isEnablePathStyleAccess() {
return enablePathStyleAccess.get();
}
@SetConfig("enablePathStyleAccess")
public void setEnablePathStyleAccess(boolean enablePathStyleAccess) {
this.enablePathStyleAccess.set(enablePathStyleAccess);
}
@GetConfig("signerOverride")
public String getSignerOverride() {
return signerOverride.get();
}
@SetConfig("signerOverride")
public void setSignerOverride(String signerOverride) {
this.signerOverride.set(signerOverride);
}
@GetConfig("maxConnections")
public int getMaxConnections() {
return maxConnections.get();
}
@SetConfig("maxConnections")
public void setMaxConnections(int maxConnections) {
this.maxConnections.set(maxConnections);
}
@GetConfig("preserveMetadata")
public boolean isPreserveMetadata() {
return preserveMetadata.get();
}
@SetConfig("preserveMetadata")
public void setPreserveMetadata(boolean preserveMetadata) {
this.preserveMetadata.set(preserveMetadata);
}
@GetConfig("openVirtualDirectory")
public boolean isOpenVirtualDirectory() {
return openVirtualDirectory.get();
}
@SetConfig("openVirtualDirectory")
public void setOpenVirtualDirectory(boolean openVirtualDirectory) {
this.openVirtualDirectory.set(openVirtualDirectory);
}
@Override
public void update(String key) {
super.update(key);
@ -93,8 +145,12 @@ public class S3Config extends CommonRepoConfig {
this.setEndPoint(newConfig.getEndPoint());
this.setRegion(newConfig.getRegion());
this.setAccessKeyId(newConfig.getAccessKeyId());
this.setAccessKeySecret(newConfig.getAccessKeySecret());
this.setBucket(newConfig.getBucket());
this.setEnablePathStyleAccess(newConfig.isEnablePathStyleAccess());
this.setSignerOverride(newConfig.getSignerOverride());
this.setMaxConnections(newConfig.getMaxConnections());
this.setPreserveMetadata(newConfig.isPreserveMetadata());
this.setOpenVirtualDirectory(newConfig.isOpenVirtualDirectory());
}
}
@ -104,8 +160,12 @@ public class S3Config extends CommonRepoConfig {
cloned.endPoint = (Conf<String>) endPoint.clone();
cloned.region = (Conf<String>) region.clone();
cloned.accessKeyId = (Conf<String>) accessKeyId.clone();
cloned.accessKeySecret = (Conf<String>) accessKeySecret.clone();
cloned.bucket = (Conf<String>) bucket.clone();
cloned.enablePathStyleAccess = (Conf<Boolean>) enablePathStyleAccess.clone();
cloned.signerOverride = (Conf<String>) signerOverride.clone();
cloned.maxConnections = (Conf<Integer>) maxConnections.clone();
cloned.preserveMetadata = (Conf<Boolean>) preserveMetadata.clone();
cloned.openVirtualDirectory = (Conf<Boolean>) openVirtualDirectory.clone();
return cloned;
}
}

36
src/main/java/com/fanruan/fs/s3/repository/core/S3RepositoryFactory.java

@ -1,5 +1,7 @@
package com.fanruan.fs.s3.repository.core;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
@ -9,6 +11,11 @@ import com.fanruan.api.log.LogKit;
import com.fr.io.base.provider.impl.ConfigRepositoryFactory;
import com.fr.io.context.info.RepositoryProfile;
import com.fr.io.repository.ResourceRepository;
import com.fr.stable.StringUtils;
import java.util.UUID;
import static com.fanruan.fs.s3.repository.core.S3ResourceRepository.HTTP;
/**
* @author richie
@ -35,15 +42,36 @@ public class S3RepositoryFactory extends ConfigRepositoryFactory<S3Config> {
@Override
public boolean verifyConfig(S3Config config) {
AmazonS3 s3 = null;
try {
BasicAWSCredentials credentials = new BasicAWSCredentials(config.getAccessKeyId(), config.getAccessKeySecret());
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
BasicAWSCredentials credentials = new BasicAWSCredentials(config.getAccessKeyId(), config.getPassword());
AmazonS3ClientBuilder amazonS3ClientBuilder = AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(config.getEndPoint(), config.getRegion()))
.withCredentials(new AWSStaticCredentialsProvider(credentials)).build();
s3.listObjects(config.getBucket());
.withCredentials(new AWSStaticCredentialsProvider(credentials)).disableChunkedEncoding();
if (config.isEnablePathStyleAccess()) {
amazonS3ClientBuilder = amazonS3ClientBuilder.enablePathStyleAccess();
}
ClientConfiguration clientConfiguration = new ClientConfiguration();
if (StringUtils.isNotEmpty(config.getSignerOverride())) {
clientConfiguration.setSignerOverride(config.getSignerOverride());
}
LogKit.debug("[S3] endpoint is {}", config.getEndPoint());
if (config.getEndPoint().startsWith(HTTP)) {
clientConfiguration.setProtocol(Protocol.HTTP);
}
amazonS3ClientBuilder = amazonS3ClientBuilder.withClientConfiguration(clientConfiguration);
s3 = amazonS3ClientBuilder.build();
String bucket = config.getBucket();
String testObject = "test_object_" + UUID.randomUUID();
s3.putObject(bucket, testObject, StringUtils.EMPTY);
s3.deleteObject(bucket, testObject);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return false;
} finally {
if (s3 != null) {
s3.shutdown();
}
}
return true;
}

401
src/main/java/com/fanruan/fs/s3/repository/core/S3ResourceRepository.java

@ -1,27 +1,39 @@
package com.fanruan.fs.s3.repository.core;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.CompleteMultipartUploadRequest;
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest;
import com.amazonaws.services.s3.model.InitiateMultipartUploadResult;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PartETag;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.s3.model.UploadPartRequest;
import com.amazonaws.services.s3.model.UploadPartResult;
import com.amazonaws.util.IOUtils;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.util.StringKit;
import com.fr.io.repository.FineFileEntry;
import com.fr.io.repository.base.BaseResourceRepository;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.stable.Filter;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.io.output.NullOutputStream;
import com.fr.workspace.resource.ResourceIOException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
@ -35,19 +47,49 @@ import java.util.List;
*/
public class S3ResourceRepository extends BaseResourceRepository {
private static final int PAGE_SIZE = 1000;
private static final int PART_SIZE = 5 * 1024 * 1024;
private static final int MULTIPART_UPLOAD_LIMIT = 20 * PART_SIZE;
private static final String DELIMITER = "/";
public static final String HTTP = "http:";
private final boolean preserveMetadata;
// 是否将创建a/b/c.txt时的a/b/识别成一个存在的目录
private final boolean openVirtualDirectory;
private final AmazonS3 s3;
private final String bucket;
public S3ResourceRepository(String repoName, String workRoot, S3Config config) {
super(repoName, workRoot);
BasicAWSCredentials credentials = new BasicAWSCredentials(config.getAccessKeyId(), config.getAccessKeySecret());
this.s3 = AmazonS3ClientBuilder.standard()
BasicAWSCredentials credentials = new BasicAWSCredentials(config.getAccessKeyId(), config.getPassword());
AmazonS3ClientBuilder amazonS3ClientBuilder = AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(config.getEndPoint(), config.getRegion()))
.withCredentials(new AWSStaticCredentialsProvider(credentials)).build();
.withCredentials(new AWSStaticCredentialsProvider(credentials)).disableChunkedEncoding();
if (config.isEnablePathStyleAccess()) {
amazonS3ClientBuilder = amazonS3ClientBuilder.enablePathStyleAccess();
}
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setMaxConnections(config.getMaxConnections());
LogKit.info("Max connections is {}!", clientConfiguration.getMaxConnections());
if (StringUtils.isNotEmpty(config.getSignerOverride())) {
clientConfiguration.setSignerOverride(config.getSignerOverride());
}
LogKit.debug("[S3] endpoint is {}", config.getEndPoint());
if (config.getEndPoint().startsWith(HTTP)) {
clientConfiguration.setProtocol(Protocol.HTTP);
}
amazonS3ClientBuilder = amazonS3ClientBuilder.withClientConfiguration(clientConfiguration);
this.s3 = amazonS3ClientBuilder.build();
this.bucket = config.getBucket();
this.preserveMetadata = config.isPreserveMetadata();
this.openVirtualDirectory = config.isOpenVirtualDirectory();
}
@Override
@ -57,18 +99,17 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public FineFileEntry getEntry(String path) {
GetObjectRequest request = new GetObjectRequest(bucket, path);
try {
S3Object s3Object = s3.getObject(request);
try {
return s3Object2FileEntry(s3Object, path);
} finally {
s3Object.close();
}
ObjectMetadata metadata = s3.getObjectMetadata(bucket, path);
return s3Object2FileEntry(metadata, path);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
LogKit.info("{} not exist!", path);
}
if (!path.endsWith(DELIMITER)) {
path = path + DELIMITER;
return getEntry(path);
}
return null;
}
@ -81,6 +122,15 @@ public class S3ResourceRepository extends BaseResourceRepository {
ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucket)
.withPrefix(dir).withDelimiter(DELIMITER);
ObjectListing objectListing = s3.listObjects(listObjectsRequest);
collectFileEntry(dir, result, objectListing);
while (objectListing.isTruncated()) {
objectListing = s3.listNextBatchOfObjects(objectListing);
collectFileEntry(dir, result, objectListing);
}
return result.toArray(new FineFileEntry[0]);
}
private void collectFileEntry(String dir, List<FineFileEntry> result, ObjectListing objectListing) {
for (S3ObjectSummary summary : objectListing.getObjectSummaries()) {
String key = summary.getKey();
if (!key.endsWith(DELIMITER)) {
@ -88,28 +138,12 @@ public class S3ResourceRepository extends BaseResourceRepository {
}
}
for (String prefix : objectListing.getCommonPrefixes()) {
if (StringUtils.isNotEmpty(prefix.substring(dir.length()).replaceAll(DELIMITER, StringUtils.EMPTY))) {
FineFileEntry entry = new FineFileEntry(prefix);
entry.setDirectory(true);
result.add(entry);
}
return result.toArray(new FineFileEntry[0]);
}
private FineFileEntry s3Object2FileEntry(S3ObjectSummary s3Object, String path) {
FineFileEntry entry = new FineFileEntry(path);
entry.setDirectory(s3Object.getKey().endsWith("/"));
entry.setSize(s3Object.getSize());
entry.setTimestamp(s3Object.getLastModified().getTime());
return entry;
}
private FineFileEntry s3Object2FileEntry(S3Object s3Object, String path) {
FineFileEntry entry = new FineFileEntry(path);
entry.setDirectory(s3Object.getKey().endsWith("/"));
entry.setSize(s3Object.getObjectMetadata().getContentLength());
entry.setTimestamp(s3Object.getObjectMetadata().getLastModified().getTime());
return entry;
}
@Override
@ -123,33 +157,106 @@ public class S3ResourceRepository extends BaseResourceRepository {
try {
return s3.getObject(request).getObjectContent();
} catch (Exception e) {
LogKit.error("[S3] Failed to read file {}", filePath);
LogKit.error(e.getMessage(), e);
return new ByteArrayInputStream(new byte[0]);
}
}
@Override
public void write(String path, byte[] data) {
ObjectMetadata metadata;
int length = data.length;
if (length > MULTIPART_UPLOAD_LIMIT) {
multipartUpload(path, new ByteArrayInputStream(data));
} else {
ObjectMetadata metadata = null;
if (preserveMetadata) {
try {
metadata = s3.getObjectMetadata(bucket, path);
} catch (Exception e) {
} catch (Exception ignore) {
}
if (metadata == null) {
metadata = new ObjectMetadata();
String mimeType = URLConnection.guessContentTypeFromName(path);
if (mimeType != null) {
metadata.setContentType(mimeType);
}
metadata.setContentLength(data.length);
}
metadata.setContentLength(length);
}
s3.putObject(bucket, path, new ByteArrayInputStream(data), metadata);
}
}
@Override
public void write(String path, InputStream inputStream) throws ResourceIOException {
long dataLength = 0;
try {
dataLength = inputStream.available();
} catch (IOException e) {
LogKit.error(e.getMessage(), e);
}
//超过一定大小才使用分片上传,小文件来说,网络传输时间可能较短,且上传失败的风险相对较低。
//在网络稳定的情况下,使用分片上传可能没有太多的优势,反而增加了额外开销和复杂性
if (dataLength > MULTIPART_UPLOAD_LIMIT) {
multipartUpload(path, inputStream);
} else {
super.write(path, inputStream);
}
}
private void multipartUpload(String path, InputStream inputStream) {
try {
// Step 1: 初始化分片上传
InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucket, path);
InitiateMultipartUploadResult initResponse = s3.initiateMultipartUpload(initRequest);
String uploadId = initResponse.getUploadId();
// Step 2: 分片上传文件
List<PartETag> partETags = new ArrayList<>();
byte[] buffer = new byte[PART_SIZE];
int bytesRead;
int partNumber = 1;
while ((bytesRead = inputStream.read(buffer)) > 0) {
// 创建上传请求
UploadPartRequest uploadRequest = new UploadPartRequest()
.withBucketName(bucket)
.withKey(path)
.withUploadId(uploadId)
.withPartNumber(partNumber)
.withInputStream(new ByteArrayInputStream(buffer, 0, bytesRead))
.withPartSize(bytesRead);
// 上传分片
UploadPartResult uploadResult = s3.uploadPart(uploadRequest);
partETags.add(uploadResult.getPartETag());
partNumber++;
}
// Step 3: 完成分片上传
CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucket, path, uploadId, partETags);
s3.completeMultipartUpload(compRequest);
} catch (IOException e) {
throw new ResourceIOException(e);
} finally {
ResourceIOUtils.close(inputStream);
}
}
@Override
public boolean createFile(String path) {
PutObjectRequest request = new PutObjectRequest(bucket, path, new ByteArrayInputStream(new byte[0]), new ObjectMetadata());
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(request);
s3.putObject(req);
} catch (Exception e) {
LogKit.error("[S3] Failed to create file path {}", path);
return false;
}
return true;
@ -157,10 +264,29 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public boolean createDirectory(String path) {
PutObjectRequest request = new PutObjectRequest(bucket, path + "/", new ByteArrayInputStream(new byte[0]), new ObjectMetadata());
if (!path.endsWith(DELIMITER)) {
path += DELIMITER;
}
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;
}
}
return createDirectoryInternal(path);
}
private boolean createDirectoryInternal(String path) {
PutObjectRequest req = new PutObjectRequest(bucket, path, new ByteArrayInputStream(new byte[0]), buildEmptyMetadata());
try {
s3.putObject(request);
s3.putObject(req);
} catch (Exception e) {
LogKit.error("[S3] Failed to create path {}", path);
return false;
}
return true;
@ -169,16 +295,63 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public boolean delete(String path) {
try {
s3.deleteObject(bucket, path);
if (isDirectory(path)) {
if (!path.endsWith(DELIMITER)) {
path += DELIMITER;
}
deleteDirectory(path);
} else {
deleteFile(path);
}
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
LogKit.error("[S3] delete {} failed, error message: {}", path, e.getMessage());
return false;
}
return true;
}
private void deleteFile(String path) throws Exception {
s3.deleteObject(bucket, path);
}
private void deleteDirectory(String path) throws Exception {
List<String> files = new ArrayList<>();
for (FineFileEntry fineFileEntry : listEntry(path)) {
if (fineFileEntry.isDirectory()) {
deleteDirectory(fineFileEntry.getPath());
} else {
files.add(fineFileEntry.getPath());
}
}
deleteFiles(files);
deleteFile(path);
}
private void deleteFiles(List<String> paths) throws Exception {
//最多只能同时指定1000个key
for (int i = 0; i < paths.size(); i = i + PAGE_SIZE) {
int toIndex = Math.min(i + PAGE_SIZE, paths.size());
DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucket)
.withKeys(paths.subList(i, toIndex).toArray(new String[0]));
s3.deleteObjects(deleteObjectsRequest);
}
}
@Override
public boolean exist(String path) {
if (fileExist(path)) {
return true;
}
if ((!path.endsWith(DELIMITER) && dirExist(path))) {
return true;
}
if (openVirtualDirectory) {
return isVirtualDirectory(path);
}
return false;
}
private boolean fileExist(String path) {
try {
return s3.doesObjectExist(bucket, path);
} catch (Exception e) {
@ -186,6 +359,48 @@ public class S3ResourceRepository extends BaseResourceRepository {
}
}
private boolean dirExist(String path) {
if (StringUtils.equals(path, DELIMITER)) {
return true;
}
if (!path.endsWith(DELIMITER)) {
path += DELIMITER;
}
return fileExist(path);
}
/**
* 是否将创建对象的前缀比如a/b/c.txt时的a/b/识别成一个存在的目录.
*/
private boolean isVirtualDirectory(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)
.withDelimiter(DELIMITER));
String targetDir = path + DELIMITER;
boolean firstSearch = true;
do {
if (!firstSearch) {
objectListing = s3.listNextBatchOfObjects(objectListing);
}
firstSearch = false;
if (objectListing.getCommonPrefixes().stream().anyMatch(s -> s.startsWith(targetDir)) ||
objectListing.getObjectSummaries().stream().anyMatch(s -> s.getKey().startsWith(targetDir))) {
createDirectoryInternal(targetDir);
return true;
}
} while (objectListing.isTruncated());
return false;
}
@Override
public String[] list(String dir, final Filter<String> filter) {
List<String> result = new ArrayList<>();
@ -195,45 +410,46 @@ public class S3ResourceRepository extends BaseResourceRepository {
ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucket)
.withPrefix(dir).withDelimiter(DELIMITER);
ObjectListing objectListing = s3.listObjects(listObjectsRequest);
for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
String[] arr = objectSummary.getKey().split(DELIMITER);
String name = arr[arr.length - 1];
if (filter == null) {
result.add(name);
} else {
if (filter.accept(name)) {
result.add(name);
collectFileName(dir, result, objectListing);
while (objectListing.isTruncated()) {
objectListing = s3.listNextBatchOfObjects(objectListing);
collectFileName(dir, result, objectListing);
}
if (filter != null) {
return result.stream().filter(filter::accept).toArray(String[]::new);
}
return result.toArray(new String[0]);
}
private void collectFileName(String dir, List<String> result, ObjectListing objectListing) {
for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
String key = objectSummary.getKey();
if (StringKit.equals(key, dir)) {
continue;
}
result.add(key.substring(key.lastIndexOf(DELIMITER) + 1));
}
for (String prefix : objectListing.getCommonPrefixes()) {
if (StringUtils.isNotEmpty(prefix.substring(dir.length()).replaceAll(DELIMITER, StringUtils.EMPTY))) {
String[] arr = prefix.split(DELIMITER);
String name = arr[arr.length - 1] + DELIMITER;
if (filter == null) {
result.add(name);
} else {
if (filter.accept(name)) {
result.add(name);
}
}
}
return result.toArray(new String[0]);
}
@Override
public boolean isDirectory(String path) {
if (path.endsWith(DELIMITER)) {
return true;
}
ObjectListing listing = s3.listObjects(bucket, path);
if (listing.getObjectSummaries().isEmpty()) {
if (!path.endsWith(DELIMITER) && fileExist(path)) {
//是文件
return false;
}
if (listing.getObjectSummaries().size() > 1) {
} else {
if (dirExist(path)) {
return true;
} else {
S3ObjectSummary summary = listing.getObjectSummaries().get(0);
return !StringKit.equals(listing.getPrefix(), summary.getKey());
// 是一个虚拟的目录
return openVirtualDirectory && isVirtualDirectory(path);
}
}
}
@ -243,12 +459,15 @@ public class S3ResourceRepository extends BaseResourceRepository {
S3Object s3Object = s3.getObject(bucket, path);
if (s3Object != null) {
try {
//s3Object要全部读完,否则会有警告
IOUtils.copy(s3Object.getObjectContent(), new NullOutputStream());
return s3Object.getObjectMetadata().getLastModified().getTime();
} finally {
s3Object.close();
}
}
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
LogKit.info("{} not exist!", path);
}
@ -258,15 +477,10 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public long length(String path) {
try {
S3Object s3Object = s3.getObject(bucket, path);
if (s3Object != null) {
try {
return s3Object.getObjectMetadata().getContentLength();
} finally {
s3Object.close();
}
}
ObjectMetadata metadata = s3.getObjectMetadata(bucket, path);
return metadata.getContentLength();
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
LogKit.info("{} not exist!", path);
}
@ -275,17 +489,22 @@ public class S3ResourceRepository extends BaseResourceRepository {
@Override
public boolean rename(String path, String newPath) throws ResourceIOException {
try {
CopyObjectRequest copyObjRequest = new CopyObjectRequest(bucket,
path, bucket, newPath);
s3.copyObject(copyObjRequest);
s3.deleteObject(new DeleteObjectRequest(bucket, path));
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return false;
if (copy(path, newPath) && delete(path)) {
if (LogKit.isDebugEnabled()) {
LogKit.debug("[S3] rename {} to {} success.", path, newPath);
}
return true;
}
LogKit.error("[S3] rename {} to {} failed.", path, newPath);
return false;
}
@Override
public boolean copyFile(String origPath, String desPath) throws ResourceIOException {
s3.copyObject(bucket, origPath, bucket, desPath);
return exist(desPath);
}
@Override
public void shutDown() {
@ -297,4 +516,30 @@ public class S3ResourceRepository extends BaseResourceRepository {
return S3RepositoryFactory.IDENTITY;
}
/*--------------------------------------私有方法-----------------------------------------**/
private ObjectMetadata buildEmptyMetadata() {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(0);
return metadata;
}
private FineFileEntry s3Object2FileEntry(S3ObjectSummary s3Object, String path) {
FineFileEntry entry = new FineFileEntry(path);
entry.setDirectory(s3Object.getKey().endsWith(DELIMITER));
entry.setSize(s3Object.getSize());
entry.setTimestamp(s3Object.getLastModified().getTime());
return entry;
}
private FineFileEntry s3Object2FileEntry(ObjectMetadata metadata, String path) {
FineFileEntry entry = new FineFileEntry(path);
entry.setDirectory(path.endsWith(DELIMITER));
entry.setSize(metadata.getContentLength());
entry.setTimestamp(metadata.getLastModified().getTime());
return entry;
}
}

3
src/main/resources/com/fanruan/fs/s3/repository/locale/s3.properties

@ -4,3 +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 "/"
Plugin-S3_Other_Config=
Plugin-S3_EnablePathStyleAccess_Error_Tip=

12
src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en.properties

@ -0,0 +1,12 @@
Dec-Error_Start_With_Slash_Or_End_Without_Slash=The path cannot start with slashes (/) and must end with slashes (/).
Plugin-S3_Access_Key_Id=Access Key ID
Plugin-S3_Access_Key_Secret=Access Key Secret
Plugin-S3_Bucket=Bucket
Plugin-S3_End_Point=Endpoint
Plugin-S3_Input=Enter a value here.
Plugin-S3_Region=Region
Plugin-S3_Other_Config=More Settings
Plugin-S3_EnablePathStyleAccess_Error_Tip=Enter true or false.
Plugin-Xml-I18n-S3repository_Name=S3 Resource Warehouse
Plugin-Xml-I18n-S3repository_Description=This plugin allows you to use a cloud storage file system that supports the S3 protocol as a file server.
Plugin-Xml-I18n-S3repository_Change_Notes=\u0020

6
src/main/resources/com/fanruan/fs/s3/repository/locale/s3_en_US.properties

@ -1,6 +0,0 @@
Plugin-S3_Input=Please Input
Plugin-S3_End_Point=Endpoint
Plugin-S3_Region=Region
Plugin-S3_Access_Key_Id=AccessKeyId
Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket

12
src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ja_JP.properties

@ -0,0 +1,12 @@
Dec-Error_Start_With_Slash_Or_End_Without_Slash=\u30D1\u30B9\u306F\u300C/\u300D\u3067\u59CB\u307E\u308B\u3053\u3068\u304C\u3067\u304D\u306A\u3044\u3002\u300C/\u300D\u3067\u7D42\u308F\u308B\u5FC5\u8981\u304C\u3042\u308B\u3002
Plugin-S3_Access_Key_Id=AccessKeyId
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
Plugin-S3_Other_Config=\u3088\u308A\u591A\u304F\u306E\u8A2D\u5B9A
Plugin-S3_EnablePathStyleAccess_Error_Tip=true\u304Bfalse\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
Plugin-Xml-I18n-S3repository_Name=S3\u30EA\u30BD\u30FC\u30B9\u30A6\u30A7\u30A2\u30CF\u30A6\u30B9
Plugin-Xml-I18n-S3repository_Change_Notes=\u0020
Plugin-Xml-I18n-S3repository_Description=\u3053\u306E\u30D7\u30E9\u30B0\u30A4\u30F3\u306F\u3001S3\u30D7\u30ED\u30C8\u30B3\u30EB\u3092\u30B5\u30DD\u30FC\u30C8\u3059\u308B\u30AF\u30E9\u30A6\u30C9\u30B9\u30C8\u30EC\u30FC\u30B8\u30D5\u30A1\u30A4\u30EB\u30B7\u30B9\u30C6\u30E0\u3092\u30D5\u30A1\u30A4\u30EB\u30B5\u30FC\u30D0\u30FC\u3068\u3057\u3066\u4F7F\u7528\u3067\u304D\u308B\u3088\u3046\u306B\u3057\u307E\u3059\u3002

12
src/main/resources/com/fanruan/fs/s3/repository/locale/s3_ko_KR.properties

@ -0,0 +1,12 @@
Dec-Error_Start_With_Slash_Or_End_Without_Slash=\uACBD\uB85C\uC758 \uC2DC\uC791 \uBD80\uBD84\uC5D0 \uC2AC\uB798\uC2DC\uB97C \uAC00\uD560 \uC218 \uC5C6\uC73C\uBA70, \uBC18\uB4DC\uC2DC \uC2AC\uB798\uC2DC\uB85C \uB9C8\uBB34\uB9AC\uD574\uC57C \uD569\uB2C8\uB2E4
Plugin-S3_Access_Key_Id=AccessKeyId
Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket
Plugin-S3_End_Point=Endpoint
Plugin-S3_Input=\uC785\uB825\uD574 \uC8FC\uC138\uC694
Plugin-S3_Region=Region
Plugin-S3_Other_Config=\uB354 \uB9CE\uC740 \uC124\uC815
Plugin-S3_EnablePathStyleAccess_Error_Tip=true \uB610\uB294 false\uB97C \uC785\uB825\uD558\uC2ED\uC2DC\uC624
Plugin-Xml-I18n-S3repository_Name=S3 \uC800\uC7A5\uC18C
Plugin-Xml-I18n-S3repository_Description=s3 \uD504\uB85C\uD1A0\uCF5C\uC744 \uC9C0\uC6D0\uD558\uB294 \uD074\uB77C\uC6B0\uB4DC \uC2A4\uD1A0\uB9AC\uC9C0 \uD30C\uC77C \uC2DC\uC2A4\uD15C\uC744 \uD30C\uC77C \uC11C\uBC84\uB85C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.
Plugin-Xml-I18n-S3repository_Change_Notes=\u0020

12
src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh.properties

@ -0,0 +1,12 @@
Dec-Error_Start_With_Slash_Or_End_Without_Slash=\u8DEF\u5F84\u5F00\u5934\u4E0D\u80FD\u52A0\u659C\u6760\uFF0C\u5FC5\u987B\u4EE5\u659C\u6760\u7ED3\u5C3E
Plugin-S3_Access_Key_Id=AccessKeyId
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
Plugin-S3_Other_Config=\u66f4\u591a\u8bbe\u7f6e
Plugin-S3_EnablePathStyleAccess_Error_Tip=\u8bf7\u8f93\u5165true\u6216false
Plugin-Xml-I18n-S3repository_Name=S3\u8d44\u6e90\u4ed3\u5e93
Plugin-Xml-I18n-S3repository_Description=\u4f7f\u7528\u652f\u6301s3\u534f\u8bae\u7684\u4e91\u5b58\u50a8\u6587\u4ef6\u7cfb\u7edf\u4f5c\u4e3a\u6587\u4ef6\u670d\u52a1\u5668\u3002
Plugin-Xml-I18n-S3repository_Change_Notes=\u0020

6
src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_CN.properties

@ -1,6 +0,0 @@
Plugin-S3_Input=\u8BF7\u8F93\u5165
Plugin-S3_End_Point=Endpoint
Plugin-S3_Region=Region
Plugin-S3_Access_Key_Id=AccessKeyId
Plugin-S3_Access_Key_Secret=AccessKeySecret
Plugin-S3_Bucket=Bucket

12
src/main/resources/com/fanruan/fs/s3/repository/locale/s3_zh_TW.properties

@ -0,0 +1,12 @@
Dec-Error_Start_With_Slash_Or_End_Without_Slash=\u8DEF\u5F91\u958B\u982D\u4E0D\u80FD\u52A0\u659C\u69D3\uFF0C\u5FC5\u9808\u4EE5\u659C\u69D3\u7D50\u5C3E
Plugin-S3_Access_Key_Id=AccessKeyId
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
Plugin-S3_Other_Config=\u66F4\u591A\u8A2D\u5B9A
Plugin-S3_EnablePathStyleAccess_Error_Tip=\u8ACB\u8F38\u5165true\u6216false
Plugin-Xml-I18n-S3repository_Name=S3\u8CC7\u6E90\u5009\u5EAB
Plugin-Xml-I18n-S3repository_Description=\u4F7F\u7528\u652F\u63F4s3\u5354\u5B9A\u7684\u96F2\u5132\u5B58\u6A94\u6848\u7CFB\u7D71\u4F5C\u70BA\u6A94\u6848\u4F3A\u670D\u5668\u3002
Plugin-Xml-I18n-S3repository_Change_Notes=\u0020

192
src/main/resources/com/fanruan/fs/s3/repository/web/js/bundle.js

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save