opendal 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +89 -56
  3. data/Cargo.toml +1 -1
  4. data/DEPENDENCIES.rust.tsv +55 -41
  5. data/LICENSE +201 -0
  6. data/LICENSE-MPL-2.0.txt +373 -0
  7. data/NOTICE +5 -0
  8. data/core/CHANGELOG.md +175 -0
  9. data/core/Cargo.lock +225 -298
  10. data/core/Cargo.toml +100 -94
  11. data/core/DEPENDENCIES.rust.tsv +44 -73
  12. data/core/benches/metadata/README.md +21 -0
  13. data/core/benches/metadata/main.rs +541 -0
  14. data/core/benches/vs_fs/Cargo.toml +1 -1
  15. data/core/benches/vs_s3/Cargo.toml +1 -1
  16. data/core/core/Cargo.toml +7 -2
  17. data/core/core/src/blocking/delete.rs +5 -1
  18. data/core/core/src/blocking/operator.rs +12 -0
  19. data/core/core/src/blocking/read/std_reader.rs +25 -0
  20. data/core/core/src/docs/concepts.rs +70 -94
  21. data/core/core/src/docs/internals/accessor.rs +62 -293
  22. data/core/core/src/docs/internals/layer.rs +43 -59
  23. data/core/core/src/docs/internals/mod.rs +21 -23
  24. data/core/core/src/docs/mod.rs +10 -6
  25. data/core/core/src/docs/performance/concurrent_write.md +92 -55
  26. data/core/core/src/docs/performance/http_optimization.md +120 -104
  27. data/core/core/src/docs/performance/mod.rs +8 -6
  28. data/core/core/src/docs/rfcs/5485_conditional_reader.md +4 -0
  29. data/core/core/src/docs/rfcs/7182_restore_api.md +139 -557
  30. data/core/core/src/docs/rfcs/7945_limited_read.md +210 -0
  31. data/core/core/src/docs/rfcs/7948_s3_provider_presets.md +254 -0
  32. data/core/core/src/docs/rfcs/8109_writer_copy_from.md +330 -0
  33. data/core/core/src/docs/rfcs/8145_conflict_error_kind.md +210 -0
  34. data/core/core/src/docs/rfcs/8147_write_if_not_changed.md +233 -0
  35. data/core/core/src/docs/rfcs/8188_compose_api.md +292 -0
  36. data/core/core/src/docs/rfcs/8194_compact_metadata_and_operation_args.md +444 -0
  37. data/core/core/src/docs/rfcs/README.md +14 -3
  38. data/core/core/src/docs/rfcs/mod.rs +46 -22
  39. data/core/core/src/docs/specs/README.md +34 -0
  40. data/core/core/src/docs/specs/conditional-operations.md +156 -0
  41. data/core/core/src/docs/specs/metadata.md +63 -0
  42. data/core/core/src/docs/specs/mod.rs +26 -0
  43. data/core/core/src/docs/upgrade.md +114 -1
  44. data/core/core/src/layers/capability_override.rs +15 -2
  45. data/core/core/src/layers/complete.rs +347 -43
  46. data/core/core/src/layers/correctness_check.rs +718 -51
  47. data/core/core/src/layers/error_context.rs +76 -2
  48. data/core/core/src/layers/simulate.rs +91 -28
  49. data/core/core/src/lib.rs +1 -0
  50. data/core/core/src/raw/accessor.rs +91 -15
  51. data/core/core/src/raw/enum_utils.rs +7 -0
  52. data/core/core/src/raw/http_util/header.rs +22 -17
  53. data/core/core/src/raw/oio/compose/api.rs +92 -0
  54. data/core/core/src/raw/oio/compose/mod.rs +19 -0
  55. data/core/core/src/raw/oio/copy/api.rs +3 -3
  56. data/core/core/src/raw/oio/copy/block_copy.rs +32 -4
  57. data/core/core/src/raw/oio/copy/multipart_copy.rs +36 -7
  58. data/core/core/src/raw/oio/entry.rs +48 -22
  59. data/core/core/src/raw/oio/list/flat_list.rs +1 -1
  60. data/core/core/src/raw/oio/list/hierarchy_list.rs +3 -2
  61. data/core/core/src/raw/oio/mod.rs +3 -0
  62. data/core/core/src/raw/oio/read/position_read.rs +1 -1
  63. data/core/core/src/raw/oio/write/api.rs +40 -0
  64. data/core/core/src/raw/oio/write/append_write.rs +4 -4
  65. data/core/core/src/raw/oio/write/block_write.rs +2 -2
  66. data/core/core/src/raw/oio/write/multipart_write.rs +181 -48
  67. data/core/core/src/raw/oio/write/position_write.rs +1 -1
  68. data/core/core/src/raw/operation.rs +6 -0
  69. data/core/core/src/raw/ops.rs +1191 -456
  70. data/core/core/src/raw/rps.rs +11 -0
  71. data/core/core/src/raw/time.rs +14 -3
  72. data/core/core/src/services/memory/backend.rs +5 -10
  73. data/core/core/src/services/memory/lister.rs +4 -4
  74. data/core/core/src/services/memory/writer.rs +7 -6
  75. data/core/core/src/types/buffer.rs +102 -12
  76. data/core/core/src/types/bytes_range.rs +20 -1
  77. data/core/core/src/types/capability.rs +65 -0
  78. data/core/core/src/types/compact.rs +329 -0
  79. data/core/core/src/types/compose/composer.rs +183 -0
  80. data/core/core/src/types/compose/input.rs +57 -0
  81. data/core/core/src/types/compose/mod.rs +23 -0
  82. data/core/core/src/types/context/read.rs +16 -11
  83. data/core/core/src/types/context/write.rs +150 -2
  84. data/core/core/src/types/copy.rs +5 -3
  85. data/core/core/src/types/delete/deleter.rs +20 -12
  86. data/core/core/src/types/delete/input.rs +22 -64
  87. data/core/core/src/types/delete/mod.rs +0 -1
  88. data/core/core/src/types/entry.rs +8 -14
  89. data/core/core/src/types/error.rs +28 -11
  90. data/core/core/src/types/metadata.rs +709 -322
  91. data/core/core/src/types/mod.rs +9 -1
  92. data/core/core/src/types/operator/operator.rs +278 -29
  93. data/core/core/src/types/operator/operator_futures.rs +466 -105
  94. data/core/core/src/types/options.rs +631 -158
  95. data/core/core/src/types/read/futures_async_reader.rs +663 -50
  96. data/core/core/src/types/read/reader.rs +23 -5
  97. data/core/core/src/types/write/futures_async_writer.rs +27 -0
  98. data/core/core/src/types/write/writer.rs +47 -5
  99. data/core/http-transports/reqwest/Cargo.toml +1 -1
  100. data/core/layers/async-backtrace/Cargo.toml +2 -2
  101. data/core/layers/async-backtrace/src/lib.rs +21 -2
  102. data/core/layers/await-tree/Cargo.toml +2 -2
  103. data/core/layers/await-tree/src/lib.rs +25 -2
  104. data/core/layers/capability-check/Cargo.toml +2 -2
  105. data/core/layers/capability-check/src/lib.rs +98 -10
  106. data/core/layers/chaos/Cargo.toml +2 -2
  107. data/core/layers/chaos/src/lib.rs +18 -3
  108. data/core/layers/concurrent-limit/Cargo.toml +3 -3
  109. data/core/layers/concurrent-limit/src/lib.rs +53 -13
  110. data/core/layers/dtrace/Cargo.toml +2 -2
  111. data/core/layers/dtrace/src/lib.rs +29 -2
  112. data/core/layers/fastmetrics/Cargo.toml +3 -3
  113. data/core/layers/fastrace/Cargo.toml +2 -2
  114. data/core/layers/fastrace/src/lib.rs +28 -2
  115. data/core/layers/foyer/Cargo.toml +2 -2
  116. data/core/layers/foyer/src/full.rs +16 -19
  117. data/core/layers/foyer/src/lib.rs +67 -14
  118. data/core/layers/hotpath/Cargo.toml +2 -2
  119. data/core/layers/hotpath/src/lib.rs +20 -2
  120. data/core/layers/immutable-index/Cargo.toml +2 -2
  121. data/core/layers/immutable-index/src/lib.rs +48 -24
  122. data/core/layers/logging/Cargo.toml +2 -2
  123. data/core/layers/logging/src/lib.rs +46 -2
  124. data/core/layers/metrics/Cargo.toml +3 -3
  125. data/core/layers/mime-guess/Cargo.toml +2 -2
  126. data/core/layers/mime-guess/src/lib.rs +31 -4
  127. data/core/layers/observe-metrics-common/Cargo.toml +2 -2
  128. data/core/layers/observe-metrics-common/src/lib.rs +55 -2
  129. data/core/layers/otelmetrics/Cargo.toml +3 -3
  130. data/core/layers/oteltrace/Cargo.toml +2 -2
  131. data/core/layers/oteltrace/src/lib.rs +27 -2
  132. data/core/layers/prometheus/Cargo.toml +3 -3
  133. data/core/layers/prometheus-client/Cargo.toml +3 -3
  134. data/core/layers/retry/Cargo.toml +4 -4
  135. data/core/layers/retry/src/lib.rs +76 -19
  136. data/core/layers/route/Cargo.toml +3 -3
  137. data/core/layers/route/src/lib.rs +34 -7
  138. data/core/layers/tail-cut/Cargo.toml +2 -2
  139. data/core/layers/tail-cut/src/lib.rs +28 -2
  140. data/core/layers/throttle/Cargo.toml +2 -2
  141. data/core/layers/throttle/src/lib.rs +19 -2
  142. data/core/layers/timeout/Cargo.toml +3 -3
  143. data/core/layers/timeout/src/lib.rs +38 -13
  144. data/core/layers/tracing/Cargo.toml +2 -2
  145. data/core/layers/tracing/src/lib.rs +24 -3
  146. data/core/services/aliyun-drive/Cargo.toml +2 -2
  147. data/core/services/aliyun-drive/src/backend.rs +34 -24
  148. data/core/services/aliyun-drive/src/core.rs +143 -54
  149. data/core/services/aliyun-drive/src/lister.rs +19 -18
  150. data/core/services/aliyun-drive/src/reader.rs +4 -1
  151. data/core/services/aliyun-drive/src/writer.rs +3 -3
  152. data/core/services/alluxio/Cargo.toml +1 -1
  153. data/core/services/alluxio/src/backend.rs +1 -1
  154. data/core/services/alluxio/src/core.rs +113 -94
  155. data/core/services/alluxio/src/reader.rs +7 -3
  156. data/core/services/alluxio/src/writer.rs +2 -2
  157. data/core/services/azblob/Cargo.toml +2 -2
  158. data/core/services/azblob/src/backend.rs +17 -9
  159. data/core/services/azblob/src/copier.rs +41 -15
  160. data/core/services/azblob/src/core.rs +372 -135
  161. data/core/services/azblob/src/deleter.rs +41 -18
  162. data/core/services/azblob/src/lister.rs +16 -10
  163. data/core/services/azblob/src/reader.rs +4 -1
  164. data/core/services/azblob/src/writer.rs +48 -15
  165. data/core/services/azdls/Cargo.toml +3 -3
  166. data/core/services/azdls/src/backend.rs +45 -15
  167. data/core/services/azdls/src/config.rs +4 -1
  168. data/core/services/azdls/src/core.rs +276 -87
  169. data/core/services/azdls/src/deleter.rs +13 -4
  170. data/core/services/azdls/src/lister.rs +18 -12
  171. data/core/services/azdls/src/reader.rs +6 -2
  172. data/core/services/azdls/src/writer.rs +44 -23
  173. data/core/services/azfile/Cargo.toml +2 -2
  174. data/core/services/azfile/src/backend.rs +24 -8
  175. data/core/services/azfile/src/core.rs +195 -77
  176. data/core/services/azfile/src/deleter.rs +8 -1
  177. data/core/services/azfile/src/lister.rs +20 -14
  178. data/core/services/azfile/src/reader.rs +5 -2
  179. data/core/services/azfile/src/writer.rs +27 -15
  180. data/core/services/azure-common/Cargo.toml +1 -1
  181. data/core/services/b2/Cargo.toml +2 -2
  182. data/core/services/b2/src/backend.rs +30 -11
  183. data/core/services/b2/src/core.rs +134 -120
  184. data/core/services/b2/src/deleter.rs +1 -1
  185. data/core/services/b2/src/lister.rs +5 -2
  186. data/core/services/b2/src/reader.rs +5 -2
  187. data/core/services/b2/src/writer.rs +29 -12
  188. data/core/services/cacache/Cargo.toml +1 -1
  189. data/core/services/cacache/src/backend.rs +4 -5
  190. data/core/services/cacache/src/reader.rs +4 -1
  191. data/core/services/cacache/src/writer.rs +6 -2
  192. data/core/services/cloudflare-kv/Cargo.toml +1 -1
  193. data/core/services/cloudflare-kv/src/backend.rs +26 -15
  194. data/core/services/cloudflare-kv/src/config.rs +13 -2
  195. data/core/services/cloudflare-kv/src/core.rs +62 -56
  196. data/core/services/cloudflare-kv/src/deleter.rs +12 -3
  197. data/core/services/cloudflare-kv/src/lister.rs +66 -17
  198. data/core/services/cloudflare-kv/src/reader.rs +14 -9
  199. data/core/services/cloudflare-kv/src/writer.rs +10 -7
  200. data/core/services/compfs/Cargo.toml +1 -1
  201. data/core/services/compfs/src/backend.rs +11 -7
  202. data/core/services/compfs/src/lister.rs +7 -7
  203. data/core/services/compfs/src/writer.rs +1 -1
  204. data/core/services/cos/Cargo.toml +1 -1
  205. data/core/services/cos/src/backend.rs +129 -16
  206. data/core/services/cos/src/core.rs +198 -80
  207. data/core/services/cos/src/deleter.rs +4 -1
  208. data/core/services/cos/src/lister.rs +42 -27
  209. data/core/services/cos/src/reader.rs +6 -2
  210. data/core/services/cos/src/writer.rs +45 -21
  211. data/core/services/d1/Cargo.toml +1 -1
  212. data/core/services/d1/src/backend.rs +6 -5
  213. data/core/services/d1/src/core.rs +79 -63
  214. data/core/services/d1/src/reader.rs +4 -1
  215. data/core/services/d1/src/writer.rs +6 -2
  216. data/core/services/dashmap/Cargo.toml +1 -1
  217. data/core/services/dashmap/src/backend.rs +2 -2
  218. data/core/services/dashmap/src/reader.rs +4 -1
  219. data/core/services/dashmap/src/writer.rs +11 -8
  220. data/core/services/dbfs/Cargo.toml +1 -1
  221. data/core/services/dbfs/src/backend.rs +21 -15
  222. data/core/services/dbfs/src/core.rs +65 -60
  223. data/core/services/dbfs/src/deleter.rs +4 -1
  224. data/core/services/dbfs/src/lister.rs +10 -10
  225. data/core/services/dbfs/src/writer.rs +6 -3
  226. data/core/services/dropbox/Cargo.toml +2 -2
  227. data/core/services/dropbox/src/backend.rs +30 -23
  228. data/core/services/dropbox/src/core.rs +65 -63
  229. data/core/services/dropbox/src/deleter.rs +1 -1
  230. data/core/services/dropbox/src/lister.rs +17 -8
  231. data/core/services/dropbox/src/reader.rs +4 -1
  232. data/core/services/dropbox/src/writer.rs +13 -10
  233. data/core/services/etcd/Cargo.toml +1 -1
  234. data/core/services/etcd/src/backend.rs +8 -5
  235. data/core/services/etcd/src/core.rs +5 -11
  236. data/core/services/etcd/src/lister.rs +6 -1
  237. data/core/services/etcd/src/reader.rs +4 -1
  238. data/core/services/etcd/src/writer.rs +6 -3
  239. data/core/services/foundationdb/Cargo.toml +1 -1
  240. data/core/services/foundationdb/src/backend.rs +6 -5
  241. data/core/services/foundationdb/src/reader.rs +4 -1
  242. data/core/services/foundationdb/src/writer.rs +6 -2
  243. data/core/services/foyer/Cargo.toml +3 -3
  244. data/core/services/foyer/src/backend.rs +6 -5
  245. data/core/services/foyer/src/reader.rs +4 -1
  246. data/core/services/foyer/src/writer.rs +6 -2
  247. data/core/services/fs/Cargo.toml +1 -1
  248. data/core/services/fs/src/backend.rs +4 -3
  249. data/core/services/fs/src/core.rs +44 -26
  250. data/core/services/fs/src/lister.rs +9 -6
  251. data/core/services/fs/src/writer.rs +20 -13
  252. data/core/services/ftp/Cargo.toml +4 -6
  253. data/core/services/ftp/src/backend.rs +9 -5
  254. data/core/services/ftp/src/core.rs +9 -7
  255. data/core/services/ftp/src/lister.rs +7 -8
  256. data/core/services/ftp/src/reader.rs +3 -3
  257. data/core/services/ftp/src/writer.rs +3 -3
  258. data/core/services/gcs/Cargo.toml +4 -2
  259. data/core/services/gcs/src/backend.rs +53 -7
  260. data/core/services/gcs/src/composer.rs +705 -0
  261. data/core/services/gcs/src/copier.rs +14 -4
  262. data/core/services/gcs/src/core.rs +828 -124
  263. data/core/services/gcs/src/deleter.rs +33 -18
  264. data/core/services/gcs/src/lib.rs +1 -0
  265. data/core/services/gcs/src/lister.rs +21 -12
  266. data/core/services/gcs/src/reader.rs +12 -5
  267. data/core/services/gcs/src/writer.rs +632 -10
  268. data/core/services/gcs-grpc/Cargo.toml +58 -0
  269. data/core/services/gcs-grpc/README.md +19 -0
  270. data/core/services/gcs-grpc/proto/README.md +23 -0
  271. data/core/services/gcs-grpc/proto/google/storage/v2/storage.proto +171 -0
  272. data/core/services/gcs-grpc/proto/upstream-descriptor.bin +0 -0
  273. data/core/services/gcs-grpc/src/backend.rs +449 -0
  274. data/core/services/gcs-grpc/src/config.rs +116 -0
  275. data/core/services/gcs-grpc/src/copier.rs +98 -0
  276. data/core/services/gcs-grpc/src/core.rs +298 -0
  277. data/core/services/gcs-grpc/src/deleter.rs +65 -0
  278. data/core/services/gcs-grpc/src/docs.md +19 -0
  279. data/core/services/gcs-grpc/src/generated/google.storage.v2.rs +541 -0
  280. data/core/services/gcs-grpc/src/generated/mod.rs +24 -0
  281. data/core/services/gcs-grpc/src/lib.rs +43 -0
  282. data/core/services/gcs-grpc/src/lister.rs +125 -0
  283. data/core/services/gcs-grpc/src/reader.rs +140 -0
  284. data/core/services/gcs-grpc/src/writer.rs +780 -0
  285. data/core/services/gdrive/Cargo.toml +2 -2
  286. data/core/services/gdrive/src/backend.rs +123 -69
  287. data/core/services/gdrive/src/core.rs +87 -69
  288. data/core/services/gdrive/src/deleter.rs +8 -2
  289. data/core/services/gdrive/src/lister.rs +38 -26
  290. data/core/services/gdrive/src/path_index.rs +2 -2
  291. data/core/services/gdrive/src/reader.rs +9 -3
  292. data/core/services/gdrive/src/writer.rs +13 -7
  293. data/core/services/ghac/Cargo.toml +2 -2
  294. data/core/services/ghac/src/backend.rs +5 -2
  295. data/core/services/ghac/src/core.rs +59 -37
  296. data/core/services/ghac/src/reader.rs +5 -2
  297. data/core/services/ghac/src/writer.rs +16 -6
  298. data/core/services/github/Cargo.toml +1 -1
  299. data/core/services/github/src/backend.rs +16 -8
  300. data/core/services/github/src/core.rs +88 -76
  301. data/core/services/github/src/lister.rs +17 -15
  302. data/core/services/github/src/reader.rs +5 -2
  303. data/core/services/github/src/writer.rs +12 -6
  304. data/core/services/goosefs/Cargo.toml +2 -2
  305. data/core/services/goosefs/src/backend.rs +2 -2
  306. data/core/services/goosefs/src/core.rs +291 -208
  307. data/core/services/goosefs/src/docs.md +3 -0
  308. data/core/services/goosefs/src/lister.rs +2 -3
  309. data/core/services/goosefs/src/reader.rs +7 -3
  310. data/core/services/goosefs/src/writer.rs +21 -10
  311. data/core/services/goosefs/tests/safe_conditional_put.rs +37 -0
  312. data/core/services/gridfs/Cargo.toml +2 -2
  313. data/core/services/gridfs/src/backend.rs +12 -8
  314. data/core/services/gridfs/src/core.rs +1 -1
  315. data/core/services/gridfs/src/reader.rs +4 -1
  316. data/core/services/gridfs/src/writer.rs +6 -2
  317. data/core/services/hdfs/Cargo.toml +1 -1
  318. data/core/services/hdfs/src/backend.rs +1 -1
  319. data/core/services/hdfs/src/core.rs +7 -4
  320. data/core/services/hdfs/src/lister.rs +7 -9
  321. data/core/services/hdfs/src/writer.rs +5 -1
  322. data/core/services/hdfs-native/Cargo.toml +1 -1
  323. data/core/services/hdfs-native/src/backend.rs +1 -1
  324. data/core/services/hdfs-native/src/core.rs +44 -50
  325. data/core/services/hdfs-native/src/lister.rs +8 -10
  326. data/core/services/hdfs-native/src/writer.rs +5 -1
  327. data/core/services/hf/Cargo.toml +4 -3
  328. data/core/services/hf/src/backend.rs +4 -3
  329. data/core/services/hf/src/core.rs +907 -153
  330. data/core/services/hf/src/lister.rs +16 -6
  331. data/core/services/hf/src/reader.rs +377 -57
  332. data/core/services/hf/src/writer.rs +6 -2
  333. data/core/services/http/Cargo.toml +3 -3
  334. data/core/services/http/src/backend.rs +8 -6
  335. data/core/services/http/src/core.rs +57 -35
  336. data/core/services/http/src/reader.rs +5 -2
  337. data/core/services/ipfs/Cargo.toml +1 -1
  338. data/core/services/ipfs/src/backend.rs +20 -9
  339. data/core/services/ipfs/src/core.rs +43 -34
  340. data/core/services/ipfs/src/reader.rs +5 -2
  341. data/core/services/ipmfs/Cargo.toml +1 -1
  342. data/core/services/ipmfs/src/backend.rs +17 -8
  343. data/core/services/ipmfs/src/core.rs +66 -60
  344. data/core/services/ipmfs/src/deleter.rs +5 -2
  345. data/core/services/ipmfs/src/lister.rs +15 -12
  346. data/core/services/ipmfs/src/reader.rs +5 -2
  347. data/core/services/ipmfs/src/writer.rs +6 -3
  348. data/core/services/koofr/Cargo.toml +2 -2
  349. data/core/services/koofr/src/backend.rs +46 -17
  350. data/core/services/koofr/src/core.rs +64 -48
  351. data/core/services/koofr/src/deleter.rs +4 -1
  352. data/core/services/koofr/src/lister.rs +11 -10
  353. data/core/services/koofr/src/reader.rs +5 -2
  354. data/core/services/koofr/src/writer.rs +13 -7
  355. data/core/services/lakefs/Cargo.toml +1 -1
  356. data/core/services/lakefs/src/backend.rs +25 -8
  357. data/core/services/lakefs/src/core.rs +79 -73
  358. data/core/services/lakefs/src/deleter.rs +4 -1
  359. data/core/services/lakefs/src/lister.rs +17 -14
  360. data/core/services/lakefs/src/reader.rs +5 -2
  361. data/core/services/lakefs/src/writer.rs +11 -10
  362. data/core/services/memcached/Cargo.toml +1 -1
  363. data/core/services/memcached/src/backend.rs +57 -7
  364. data/core/services/memcached/src/config.rs +13 -2
  365. data/core/services/memcached/src/core.rs +11 -1
  366. data/core/services/memcached/src/reader.rs +4 -1
  367. data/core/services/memcached/src/writer.rs +6 -2
  368. data/core/services/mini_moka/Cargo.toml +1 -1
  369. data/core/services/mini_moka/src/backend.rs +8 -8
  370. data/core/services/mini_moka/src/reader.rs +4 -1
  371. data/core/services/mini_moka/src/writer.rs +11 -7
  372. data/core/services/moka/Cargo.toml +1 -1
  373. data/core/services/moka/src/backend.rs +7 -7
  374. data/core/services/moka/src/reader.rs +4 -1
  375. data/core/services/moka/src/writer.rs +10 -6
  376. data/core/services/mongodb/Cargo.toml +2 -2
  377. data/core/services/mongodb/src/backend.rs +7 -6
  378. data/core/services/mongodb/src/core.rs +1 -1
  379. data/core/services/mongodb/src/reader.rs +4 -1
  380. data/core/services/mongodb/src/writer.rs +6 -2
  381. data/core/services/monoiofs/Cargo.toml +2 -2
  382. data/core/services/monoiofs/src/backend.rs +16 -10
  383. data/core/services/monoiofs/src/core.rs +8 -9
  384. data/core/services/monoiofs/src/reader.rs +8 -10
  385. data/core/services/monoiofs/src/writer.rs +19 -24
  386. data/core/services/mysql/Cargo.toml +2 -2
  387. data/core/services/mysql/src/backend.rs +7 -6
  388. data/core/services/mysql/src/core.rs +1 -1
  389. data/core/services/mysql/src/lister.rs +7 -3
  390. data/core/services/mysql/src/reader.rs +4 -1
  391. data/core/services/mysql/src/writer.rs +6 -2
  392. data/core/services/obs/Cargo.toml +1 -1
  393. data/core/services/obs/src/backend.rs +29 -11
  394. data/core/services/obs/src/core.rs +81 -82
  395. data/core/services/obs/src/deleter.rs +4 -1
  396. data/core/services/obs/src/lister.rs +12 -5
  397. data/core/services/obs/src/reader.rs +5 -2
  398. data/core/services/obs/src/writer.rs +40 -19
  399. data/core/services/onedrive/Cargo.toml +2 -2
  400. data/core/services/onedrive/src/backend.rs +30 -21
  401. data/core/services/onedrive/src/config.rs +2 -2
  402. data/core/services/onedrive/src/core.rs +191 -90
  403. data/core/services/onedrive/src/deleter.rs +5 -2
  404. data/core/services/onedrive/src/graph_model.rs +10 -51
  405. data/core/services/onedrive/src/lister.rs +60 -24
  406. data/core/services/onedrive/src/reader.rs +17 -2
  407. data/core/services/onedrive/src/writer.rs +26 -15
  408. data/core/services/opfs/Cargo.toml +1 -1
  409. data/core/services/opfs/src/backend.rs +6 -13
  410. data/core/services/opfs/src/core.rs +33 -37
  411. data/core/services/opfs/src/lister.rs +4 -4
  412. data/core/services/opfs/src/writer.rs +1 -3
  413. data/core/services/oss/Cargo.toml +1 -1
  414. data/core/services/oss/src/backend.rs +40 -8
  415. data/core/services/oss/src/core.rs +192 -92
  416. data/core/services/oss/src/deleter.rs +16 -6
  417. data/core/services/oss/src/lister.rs +43 -27
  418. data/core/services/oss/src/reader.rs +6 -2
  419. data/core/services/oss/src/writer.rs +40 -22
  420. data/core/services/pcloud/Cargo.toml +1 -1
  421. data/core/services/pcloud/src/backend.rs +40 -6
  422. data/core/services/pcloud/src/core.rs +80 -66
  423. data/core/services/pcloud/src/deleter.rs +8 -1
  424. data/core/services/pcloud/src/lister.rs +4 -1
  425. data/core/services/pcloud/src/reader.rs +5 -2
  426. data/core/services/pcloud/src/writer.rs +6 -3
  427. data/core/services/persy/Cargo.toml +1 -1
  428. data/core/services/persy/src/backend.rs +6 -5
  429. data/core/services/persy/src/core.rs +60 -15
  430. data/core/services/persy/src/reader.rs +4 -1
  431. data/core/services/persy/src/writer.rs +6 -2
  432. data/core/services/postgresql/Cargo.toml +2 -2
  433. data/core/services/postgresql/src/backend.rs +7 -6
  434. data/core/services/postgresql/src/core.rs +1 -1
  435. data/core/services/postgresql/src/reader.rs +4 -1
  436. data/core/services/postgresql/src/writer.rs +6 -2
  437. data/core/services/redb/Cargo.toml +1 -1
  438. data/core/services/redb/src/backend.rs +6 -5
  439. data/core/services/redb/src/reader.rs +4 -1
  440. data/core/services/redb/src/writer.rs +6 -2
  441. data/core/services/redis/Cargo.toml +1 -1
  442. data/core/services/redis/src/backend.rs +18 -8
  443. data/core/services/redis/src/config.rs +13 -2
  444. data/core/services/redis/src/reader.rs +8 -4
  445. data/core/services/redis/src/writer.rs +6 -2
  446. data/core/services/rocksdb/Cargo.toml +1 -1
  447. data/core/services/rocksdb/src/backend.rs +6 -5
  448. data/core/services/rocksdb/src/lister.rs +6 -5
  449. data/core/services/rocksdb/src/reader.rs +4 -1
  450. data/core/services/rocksdb/src/writer.rs +6 -2
  451. data/core/services/s3/Cargo.toml +5 -4
  452. data/core/services/s3/src/backend.rs +995 -39
  453. data/core/services/s3/src/compatible_services.md +57 -0
  454. data/core/services/s3/src/config.rs +16 -0
  455. data/core/services/s3/src/copier.rs +190 -55
  456. data/core/services/s3/src/core.rs +299 -190
  457. data/core/services/s3/src/deleter.rs +26 -7
  458. data/core/services/s3/src/docs.md +57 -0
  459. data/core/services/s3/src/lister.rs +55 -36
  460. data/core/services/s3/src/reader.rs +22 -2
  461. data/core/services/s3/src/writer.rs +154 -32
  462. data/core/services/seafile/Cargo.toml +2 -2
  463. data/core/services/seafile/src/backend.rs +3 -3
  464. data/core/services/seafile/src/core.rs +105 -79
  465. data/core/services/seafile/src/lister.rs +11 -8
  466. data/core/services/seafile/src/reader.rs +5 -2
  467. data/core/services/seafile/src/writer.rs +6 -3
  468. data/core/services/sftp/Cargo.toml +1 -1
  469. data/core/services/sftp/src/backend.rs +19 -4
  470. data/core/services/sftp/src/core.rs +51 -46
  471. data/core/services/sftp/src/lister.rs +4 -4
  472. data/core/services/sftp/src/writer.rs +1 -1
  473. data/core/services/sled/Cargo.toml +1 -1
  474. data/core/services/sled/src/backend.rs +6 -5
  475. data/core/services/sled/src/core.rs +28 -6
  476. data/core/services/sled/src/lister.rs +6 -5
  477. data/core/services/sled/src/reader.rs +4 -1
  478. data/core/services/sled/src/writer.rs +6 -2
  479. data/core/services/sqlite/Cargo.toml +2 -2
  480. data/core/services/sqlite/src/backend.rs +12 -7
  481. data/core/services/sqlite/src/core.rs +3 -3
  482. data/core/services/sqlite/src/reader.rs +4 -1
  483. data/core/services/sqlite/src/writer.rs +7 -3
  484. data/core/services/surrealdb/Cargo.toml +2 -2
  485. data/core/services/surrealdb/src/backend.rs +7 -6
  486. data/core/services/surrealdb/src/core.rs +1 -1
  487. data/core/services/surrealdb/src/reader.rs +4 -1
  488. data/core/services/surrealdb/src/writer.rs +6 -2
  489. data/core/services/swift/Cargo.toml +1 -1
  490. data/core/services/swift/src/backend.rs +38 -8
  491. data/core/services/swift/src/core.rs +63 -67
  492. data/core/services/swift/src/deleter.rs +8 -2
  493. data/core/services/swift/src/lister.rs +11 -8
  494. data/core/services/swift/src/reader.rs +5 -2
  495. data/core/services/swift/src/writer.rs +17 -8
  496. data/core/services/tikv/Cargo.toml +2 -2
  497. data/core/services/tikv/src/backend.rs +7 -6
  498. data/core/services/tikv/src/core.rs +31 -14
  499. data/core/services/tikv/src/reader.rs +4 -1
  500. data/core/services/tikv/src/writer.rs +6 -2
  501. data/core/services/tos/Cargo.toml +2 -2
  502. data/core/services/tos/src/backend.rs +45 -21
  503. data/core/services/tos/src/copier.rs +44 -17
  504. data/core/services/tos/src/core.rs +147 -117
  505. data/core/services/tos/src/deleter.rs +9 -3
  506. data/core/services/tos/src/docs.md +1 -1
  507. data/core/services/tos/src/lister.rs +43 -28
  508. data/core/services/tos/src/reader.rs +5 -2
  509. data/core/services/tos/src/writer.rs +37 -16
  510. data/core/services/upyun/Cargo.toml +1 -1
  511. data/core/services/upyun/src/backend.rs +30 -7
  512. data/core/services/upyun/src/core.rs +122 -87
  513. data/core/services/upyun/src/deleter.rs +4 -1
  514. data/core/services/upyun/src/lister.rs +10 -10
  515. data/core/services/upyun/src/reader.rs +5 -2
  516. data/core/services/upyun/src/writer.rs +19 -7
  517. data/core/services/vercel-artifacts/Cargo.toml +1 -1
  518. data/core/services/vercel-artifacts/src/backend.rs +6 -3
  519. data/core/services/vercel-artifacts/src/core.rs +32 -27
  520. data/core/services/vercel-artifacts/src/reader.rs +5 -2
  521. data/core/services/vercel-artifacts/src/writer.rs +6 -3
  522. data/core/services/vercel-blob/Cargo.toml +1 -1
  523. data/core/services/vercel-blob/src/backend.rs +23 -6
  524. data/core/services/vercel-blob/src/core.rs +92 -81
  525. data/core/services/vercel-blob/src/lister.rs +12 -3
  526. data/core/services/vercel-blob/src/reader.rs +5 -2
  527. data/core/services/vercel-blob/src/writer.rs +19 -7
  528. data/core/services/webdav/Cargo.toml +2 -2
  529. data/core/services/webdav/src/backend.rs +25 -5
  530. data/core/services/webdav/src/core.rs +116 -59
  531. data/core/services/webdav/src/deleter.rs +4 -1
  532. data/core/services/webdav/src/lister.rs +4 -1
  533. data/core/services/webdav/src/reader.rs +6 -2
  534. data/core/services/webdav/src/writer.rs +17 -7
  535. data/core/services/webhdfs/Cargo.toml +2 -2
  536. data/core/services/webhdfs/src/backend.rs +24 -11
  537. data/core/services/webhdfs/src/core.rs +99 -98
  538. data/core/services/webhdfs/src/deleter.rs +5 -2
  539. data/core/services/webhdfs/src/lister.rs +21 -9
  540. data/core/services/webhdfs/src/reader.rs +5 -2
  541. data/core/services/webhdfs/src/writer.rs +49 -14
  542. data/core/services/yandex-disk/Cargo.toml +1 -1
  543. data/core/services/yandex-disk/src/backend.rs +28 -6
  544. data/core/services/yandex-disk/src/core.rs +97 -79
  545. data/core/services/yandex-disk/src/deleter.rs +4 -1
  546. data/core/services/yandex-disk/src/lister.rs +25 -9
  547. data/core/services/yandex-disk/src/reader.rs +5 -2
  548. data/core/services/yandex-disk/src/writer.rs +6 -3
  549. data/core/src/lib.rs +5 -0
  550. data/core/testkit/Cargo.toml +4 -4
  551. data/core/testkit/src/utils.rs +53 -8
  552. data/core/tests/behavior/async_compose.rs +297 -0
  553. data/core/tests/behavior/async_copy.rs +162 -1
  554. data/core/tests/behavior/async_delete.rs +364 -3
  555. data/core/tests/behavior/async_read.rs +86 -0
  556. data/core/tests/behavior/async_restore.rs +162 -0
  557. data/core/tests/behavior/async_stat.rs +90 -0
  558. data/core/tests/behavior/async_write.rs +330 -2
  559. data/core/tests/behavior/main.rs +4 -0
  560. data/core/upgrade.md +114 -1
  561. data/src/capability.rs +0 -1
  562. data/src/io.rs +0 -1
  563. data/src/lister.rs +0 -1
  564. data/src/metadata.rs +0 -1
  565. data/src/operator_info.rs +0 -1
  566. metadata +44 -2
@@ -80,7 +80,10 @@ impl AlluxioCore {
80
80
  let status = resp.status();
81
81
  match status {
82
82
  StatusCode::OK => Ok(()),
83
- _ => Err(parse_error(resp)),
83
+ _ => Err(parse_error(
84
+ ErrorContext::new(ServiceOperation("CreateDirectory")),
85
+ resp,
86
+ )),
84
87
  }
85
88
  }
86
89
 
@@ -119,7 +122,10 @@ impl AlluxioCore {
119
122
  serde_json::from_reader(body.reader()).map_err(new_json_serialize_error)?;
120
123
  Ok(steam_id)
121
124
  }
122
- _ => Err(parse_error(resp)),
125
+ _ => Err(parse_error(
126
+ ErrorContext::new(ServiceOperation("CreateFile")),
127
+ resp,
128
+ )),
123
129
  }
124
130
  }
125
131
 
@@ -148,7 +154,10 @@ impl AlluxioCore {
148
154
  serde_json::from_reader(body.reader()).map_err(new_json_serialize_error)?;
149
155
  Ok(steam_id)
150
156
  }
151
- _ => Err(parse_error(resp)),
157
+ _ => Err(parse_error(
158
+ ErrorContext::new(ServiceOperation("OpenFile")),
159
+ resp,
160
+ )),
152
161
  }
153
162
  }
154
163
 
@@ -173,7 +182,7 @@ impl AlluxioCore {
173
182
  match status {
174
183
  StatusCode::OK => Ok(()),
175
184
  _ => {
176
- let err = parse_error(resp);
185
+ let err = parse_error(ErrorContext::new(ServiceOperation("Delete")), resp);
177
186
  if err.kind() == ErrorKind::NotFound {
178
187
  return Ok(());
179
188
  }
@@ -205,7 +214,10 @@ impl AlluxioCore {
205
214
 
206
215
  match status {
207
216
  StatusCode::OK => Ok(()),
208
- _ => Err(parse_error(resp)),
217
+ _ => Err(parse_error(
218
+ ErrorContext::new(ServiceOperation("Rename")),
219
+ resp,
220
+ )),
209
221
  }
210
222
  }
211
223
 
@@ -235,7 +247,10 @@ impl AlluxioCore {
235
247
  serde_json::from_reader(body.reader()).map_err(new_json_serialize_error)?;
236
248
  Ok(file_info)
237
249
  }
238
- _ => Err(parse_error(resp)),
250
+ _ => Err(parse_error(
251
+ ErrorContext::new(ServiceOperation("GetStatus")),
252
+ resp,
253
+ )),
239
254
  }
240
255
  }
241
256
 
@@ -269,7 +284,10 @@ impl AlluxioCore {
269
284
  serde_json::from_reader(body.reader()).map_err(new_json_deserialize_error)?;
270
285
  Ok(file_infos)
271
286
  }
272
- _ => Err(parse_error(resp)),
287
+ _ => Err(parse_error(
288
+ ErrorContext::new(ServiceOperation("ListStatus")),
289
+ resp,
290
+ )),
273
291
  }
274
292
  }
275
293
 
@@ -329,7 +347,10 @@ impl AlluxioCore {
329
347
  serde_json::from_reader(body.reader()).map_err(new_json_serialize_error)?;
330
348
  Ok(size)
331
349
  }
332
- _ => Err(parse_error(resp)),
350
+ _ => Err(parse_error(
351
+ ErrorContext::new(ServiceOperation("WriteStream")),
352
+ resp,
353
+ )),
333
354
  }
334
355
  }
335
356
 
@@ -351,13 +372,18 @@ impl AlluxioCore {
351
372
 
352
373
  match status {
353
374
  StatusCode::OK => Ok(()),
354
- _ => Err(parse_error(resp)),
375
+ _ => Err(parse_error(
376
+ ErrorContext::new(ServiceOperation("CloseStream")),
377
+ resp,
378
+ )),
355
379
  }
356
380
  }
357
381
  }
358
382
 
359
383
  #[cfg(test)]
360
384
  mod tests {
385
+ use http::StatusCode;
386
+
361
387
  use super::*;
362
388
 
363
389
  #[tokio::test]
@@ -377,6 +403,38 @@ mod tests {
377
403
 
378
404
  assert_eq!(err.kind(), ErrorKind::Unsupported);
379
405
  }
406
+
407
+ /// Error response example is from https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
408
+ #[test]
409
+ fn test_parse_error() {
410
+ let err_res = vec![
411
+ (
412
+ r#"{"statusCode":"ALREADY_EXISTS","message":"The resource you requested already exist"}"#,
413
+ ErrorKind::AlreadyExists,
414
+ ),
415
+ (
416
+ r#"{"statusCode":"NOT_FOUND","message":"The resource you requested does not exist"}"#,
417
+ ErrorKind::NotFound,
418
+ ),
419
+ (
420
+ r#"{"statusCode":"INTERNAL_SERVER_ERROR","message":"Internal server error"}"#,
421
+ ErrorKind::Unexpected,
422
+ ),
423
+ ];
424
+
425
+ for res in err_res {
426
+ let bs = bytes::Bytes::from(res.0);
427
+ let body = Buffer::from(bs);
428
+ let resp = Response::builder()
429
+ .status(StatusCode::INTERNAL_SERVER_ERROR)
430
+ .body(body)
431
+ .unwrap();
432
+
433
+ let err = parse_error(ErrorContext::new(ServiceOperation("Test")), resp);
434
+
435
+ assert_eq!(err.kind(), res.1);
436
+ }
437
+ }
380
438
  }
381
439
 
382
440
  #[derive(Debug, Serialize)]
@@ -413,103 +471,64 @@ impl TryFrom<FileInfo> for Metadata {
413
471
 
414
472
  fn try_from(file_info: FileInfo) -> Result<Metadata> {
415
473
  let mut metadata = if file_info.folder {
416
- Metadata::new(EntryMode::DIR)
474
+ MetadataBuilder::dir()
417
475
  } else {
418
- Metadata::new(EntryMode::FILE)
476
+ MetadataBuilder::file(file_info.length)
419
477
  };
420
- metadata
421
- .set_content_length(file_info.length)
422
- .set_last_modified(Timestamp::from_millisecond(
423
- file_info.last_modification_time_ms,
424
- )?);
425
- Ok(metadata)
478
+ metadata.last_modified(Timestamp::from_millisecond(
479
+ file_info.last_modification_time_ms,
480
+ )?);
481
+ Ok(metadata.build())
426
482
  }
427
483
  }
428
484
 
429
- mod error {
430
- use bytes::Buf;
431
- use http::Response;
432
- use serde::Deserialize;
433
-
434
- use opendal_core::raw::*;
435
- use opendal_core::*;
436
-
437
- /// the error response of alluxio
438
- #[derive(Default, Debug, Deserialize)]
439
- #[serde(rename_all = "camelCase")]
440
- #[allow(dead_code)]
441
- struct AlluxioError {
442
- status_code: String,
443
- message: String,
485
+ /// the error response of alluxio
486
+ #[derive(Default, Debug, Deserialize)]
487
+ #[serde(rename_all = "camelCase")]
488
+ #[allow(dead_code)]
489
+ struct AlluxioError {
490
+ status_code: String,
491
+ message: String,
492
+ }
493
+
494
+ /// Context needed to classify an error from this service.
495
+ #[derive(Clone, Copy, Debug)]
496
+ pub(crate) struct ErrorContext {
497
+ service_operation: ServiceOperation,
498
+ }
499
+
500
+ impl ErrorContext {
501
+ pub(crate) const fn new(service_operation: ServiceOperation) -> Self {
502
+ Self { service_operation }
444
503
  }
504
+ }
445
505
 
446
- pub(crate) fn parse_error(resp: Response<Buffer>) -> Error {
447
- let (parts, body) = resp.into_parts();
448
- let bs = body.to_bytes();
506
+ /// Parse an error response using its service request context.
507
+ pub(crate) fn parse_error(ctx: ErrorContext, resp: Response<Buffer>) -> Error {
508
+ let (parts, body) = resp.into_parts();
509
+ let bs = body.to_bytes();
449
510
 
450
- let mut kind = match parts.status.as_u16() {
451
- 500 => ErrorKind::Unexpected,
452
- _ => ErrorKind::Unexpected,
453
- };
511
+ let mut kind = match parts.status.as_u16() {
512
+ 500 => ErrorKind::Unexpected,
513
+ _ => ErrorKind::Unexpected,
514
+ };
454
515
 
455
- let (message, alluxio_err) =
456
- serde_json::from_reader::<_, AlluxioError>(bs.clone().reader())
457
- .map(|alluxio_err| (format!("{alluxio_err:?}"), Some(alluxio_err)))
458
- .unwrap_or_else(|_| (String::from_utf8_lossy(&bs).into_owned(), None));
516
+ let (message, alluxio_err) = serde_json::from_reader::<_, AlluxioError>(bs.clone().reader())
517
+ .map(|alluxio_err| (format!("{alluxio_err:?}"), Some(alluxio_err)))
518
+ .unwrap_or_else(|_| (String::from_utf8_lossy(&bs).into_owned(), None));
459
519
 
460
- if let Some(alluxio_err) = alluxio_err {
461
- kind = match alluxio_err.status_code.as_str() {
462
- "ALREADY_EXISTS" => ErrorKind::AlreadyExists,
463
- "NOT_FOUND" => ErrorKind::NotFound,
464
- _ => ErrorKind::Unexpected,
465
- }
520
+ if let Some(alluxio_err) = alluxio_err {
521
+ kind = match alluxio_err.status_code.as_str() {
522
+ "ALREADY_EXISTS" => ErrorKind::AlreadyExists,
523
+ "NOT_FOUND" => ErrorKind::NotFound,
524
+ _ => ErrorKind::Unexpected,
466
525
  }
526
+ }
467
527
 
468
- let mut err = Error::new(kind, message);
469
-
470
- err = with_error_response_context(err, parts);
528
+ let mut err = Error::new(kind, message);
471
529
 
472
- err
473
- }
530
+ err = err.with_context("service_operation", ctx.service_operation.0);
531
+ err = with_error_response_context(err, parts);
474
532
 
475
- #[cfg(test)]
476
- mod tests {
477
- use http::StatusCode;
478
-
479
- use super::*;
480
-
481
- /// Error response example is from https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
482
- #[test]
483
- fn test_parse_error() {
484
- let err_res = vec![
485
- (
486
- r#"{"statusCode":"ALREADY_EXISTS","message":"The resource you requested already exist"}"#,
487
- ErrorKind::AlreadyExists,
488
- ),
489
- (
490
- r#"{"statusCode":"NOT_FOUND","message":"The resource you requested does not exist"}"#,
491
- ErrorKind::NotFound,
492
- ),
493
- (
494
- r#"{"statusCode":"INTERNAL_SERVER_ERROR","message":"Internal server error"}"#,
495
- ErrorKind::Unexpected,
496
- ),
497
- ];
498
-
499
- for res in err_res {
500
- let bs = bytes::Bytes::from(res.0);
501
- let body = Buffer::from(bs);
502
- let resp = Response::builder()
503
- .status(StatusCode::INTERNAL_SERVER_ERROR)
504
- .body(body)
505
- .unwrap();
506
-
507
- let err = parse_error(resp);
508
-
509
- assert_eq!(err.kind(), res.1);
510
- }
511
- }
512
- }
533
+ err
513
534
  }
514
-
515
- pub(super) use error::*;
@@ -16,7 +16,7 @@
16
16
  // under the License.
17
17
 
18
18
  use super::backend::*;
19
- use super::core::parse_error;
19
+ use super::core::{ErrorContext, parse_error};
20
20
  use http::Response;
21
21
  use opendal_core::raw::*;
22
22
  use opendal_core::*;
@@ -47,16 +47,20 @@ impl oio::StreamRead for AlluxioReader {
47
47
  async fn open(&self, range: BytesRange) -> Result<(RpRead, Box<dyn oio::ReadStreamDyn>)> {
48
48
  let backend = &self.backend;
49
49
  let path = self.path.as_str();
50
+ let metadata = backend.core.get_status(&self.ctx, path).await?.try_into()?;
50
51
  let stream_id = backend.core.open_file(&self.ctx, path).await?;
51
52
 
52
53
  let resp = backend.core.read(&self.ctx, stream_id, range).await?;
53
54
  if !resp.status().is_success() {
54
55
  let (part, mut body) = resp.into_parts();
55
56
  let buf = body.to_buffer().await?;
56
- return Err(parse_error(Response::from_parts(part, buf)));
57
+ return Err(parse_error(
58
+ ErrorContext::new(ServiceOperation("ReadStream")),
59
+ Response::from_parts(part, buf),
60
+ ));
57
61
  }
58
62
 
59
- let rp = RpRead::new(parse_into_metadata(path, resp.headers())?);
63
+ let rp = RpRead::new(metadata);
60
64
  let stream = resp.into_body();
61
65
 
62
66
  Ok((rp, Box::new(stream) as Box<dyn oio::ReadStreamDyn>))
@@ -60,11 +60,11 @@ impl oio::Write for AlluxioWriter {
60
60
 
61
61
  async fn close(&mut self) -> Result<Metadata> {
62
62
  let Some(stream_id) = self.stream_id else {
63
- return Ok(Metadata::default());
63
+ return Ok(MetadataBuilder::unknown().build());
64
64
  };
65
65
  self.core.close(&self.ctx, stream_id).await?;
66
66
 
67
- Ok(Metadata::default())
67
+ Ok(MetadataBuilder::unknown().build())
68
68
  }
69
69
 
70
70
  async fn abort(&mut self) -> Result<()> {
@@ -36,10 +36,10 @@ base64 = { workspace = true }
36
36
  bytes = { workspace = true }
37
37
  http = { workspace = true }
38
38
  log = { workspace = true }
39
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false, features = [
39
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false, features = [
40
40
  "reqsign",
41
41
  ] }
42
- opendal-service-azure-common = { path = "../azure-common", version = "0.58.1" }
42
+ opendal-service-azure-common = { path = "../azure-common", version = "0.59.0" }
43
43
  quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
44
44
  reqsign-azure-storage = { version = "3.1.1", default-features = false }
45
45
  reqsign-core = { version = "3.2.0", default-features = false }
@@ -37,6 +37,7 @@ use super::config::AzblobConfig;
37
37
  use super::copier::AzblobCopiers;
38
38
  use super::copier::new_azblob_copier;
39
39
  use super::core::AzblobCore;
40
+ use super::core::ErrorContext;
40
41
  use super::core::constants::AZBLOB_COPY_MAX_BLOCK_SIZE;
41
42
  use super::core::constants::AZBLOB_COPY_MIN_BLOCK_SIZE;
42
43
  use super::core::constants::X_MS_META_PREFIX;
@@ -407,15 +408,20 @@ impl Builder for AzblobBuilder {
407
408
  write_can_multi: true,
408
409
  write_with_cache_control: true,
409
410
  write_with_content_type: true,
411
+ write_with_if_match: true,
410
412
  write_with_if_not_exists: true,
411
413
  write_with_if_none_match: true,
412
414
  write_with_user_metadata: true,
413
415
 
414
416
  delete: true,
417
+ delete_with_if_match: true,
418
+ delete_with_if_none_match: true,
415
419
  delete_max_size: Some(AZBLOB_BATCH_LIMIT),
416
420
 
417
421
  copy: true,
418
422
  copy_with_if_not_exists: true,
423
+ copy_with_if_match: true,
424
+ copy_with_if_none_match: true,
419
425
  copy_can_multi: true,
420
426
  copy_multi_min_size: Some(AZBLOB_COPY_MIN_BLOCK_SIZE),
421
427
  copy_multi_max_size: Some(AZBLOB_COPY_MAX_BLOCK_SIZE),
@@ -462,6 +468,7 @@ impl Service for AzblobBackend {
462
468
  type Lister = oio::PageLister<AzblobLister>;
463
469
  type Deleter = oio::BatchDeleter<AzblobDeleter>;
464
470
  type Copier = AzblobCopiers;
471
+ type Composer = ();
465
472
 
466
473
  fn info(&self) -> ServiceInfo {
467
474
  self.core.info.clone()
@@ -484,6 +491,8 @@ impl Service for AzblobBackend {
484
491
  }
485
492
 
486
493
  async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
494
+ let error_ctx = ErrorContext::new(ServiceOperation("GetBlobProperties"))
495
+ .with_caller_condition(args.is_conditional());
487
496
  let resp = self
488
497
  .core
489
498
  .azblob_get_blob_properties(ctx, path, &args)
@@ -494,19 +503,19 @@ impl Service for AzblobBackend {
494
503
  match status {
495
504
  StatusCode::OK => {
496
505
  let headers = resp.headers();
497
- let mut meta = parse_into_metadata(path, headers)?;
506
+ let mut meta = parse_into_metadata(path, headers)?.into_builder();
498
507
  if let Some(version_id) = parse_header_to_str(headers, X_MS_VERSION_ID)? {
499
- meta.set_version(version_id);
508
+ meta.version(version_id);
500
509
  }
501
510
 
502
511
  let user_meta = parse_prefixed_headers(headers, X_MS_META_PREFIX);
503
512
  if !user_meta.is_empty() {
504
- meta = meta.with_user_metadata(user_meta);
513
+ meta.user_metadata(user_meta);
505
514
  }
506
515
 
507
- Ok(RpStat::new(meta))
516
+ Ok(RpStat::new(meta.build()))
508
517
  }
509
- _ => Err(parse_error(resp)),
518
+ _ => Err(parse_error(error_ctx, resp)),
510
519
  }
511
520
  }
512
521
  fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
@@ -579,10 +588,9 @@ impl Service for AzblobBackend {
579
588
  from: &str,
580
589
  to: &str,
581
590
  args: OpCopy,
582
- opts: OpCopier,
583
591
  ) -> Result<Self::Copier> {
584
592
  let output: AzblobCopiers = {
585
- let copier = new_azblob_copier(self.core.clone(), ctx, from, to, args, opts)?;
593
+ let copier = new_azblob_copier(self.core.clone(), ctx, from, to, args)?;
586
594
  Ok(copier)
587
595
  }?;
588
596
 
@@ -611,9 +619,9 @@ impl Service for AzblobBackend {
611
619
  let req = match args.operation() {
612
620
  PresignOperation::Stat(v) => self.core.azblob_head_blob_request(path, v),
613
621
  PresignOperation::Read(range, v) => self.core.azblob_get_blob_request(path, *range, v),
614
- PresignOperation::Write(_) => {
622
+ PresignOperation::Write(v) => {
615
623
  self.core
616
- .azblob_put_blob_request(path, None, &OpWrite::default(), Buffer::new())
624
+ .azblob_put_blob_request(path, None, v, Buffer::new())
617
625
  }
618
626
  PresignOperation::Delete(_) => Err(Error::new(
619
627
  ErrorKind::Unsupported,
@@ -21,6 +21,7 @@ use http::StatusCode;
21
21
  use uuid::Uuid;
22
22
 
23
23
  use super::core::AzblobCore;
24
+ use super::core::ErrorContext;
24
25
  use super::core::constants::AZBLOB_COPY_MAX_BLOCK_SIZE;
25
26
  use super::core::constants::AZBLOB_COPY_MIN_BLOCK_SIZE;
26
27
  use super::core::constants::X_MS_VERSION_ID;
@@ -38,8 +39,10 @@ pub fn new_azblob_copier(
38
39
  from: &str,
39
40
  to: &str,
40
41
  args: OpCopy,
41
- opts: OpCopier,
42
42
  ) -> Result<AzblobCopiers> {
43
+ let chunk = args.chunk();
44
+ let source_content_length_hint = args.source_content_length_hint();
45
+ let concurrent = args.concurrent();
43
46
  let copier = AzblobCopier {
44
47
  core,
45
48
  ctx: ctx.clone(),
@@ -48,9 +51,15 @@ pub fn new_azblob_copier(
48
51
  args,
49
52
  };
50
53
 
51
- let Some(chunk) = opts.chunk() else {
54
+ let Some(chunk) = chunk else {
52
55
  return Ok(TwoWays::One(oio::OneShotCopier::new(async move {
53
- copier.copy_once().await
56
+ let source_size = match source_content_length_hint {
57
+ Some(size) => size,
58
+ None => copier.source_metadata().await?.content_length(),
59
+ };
60
+ let mut metadata = copier.copy_once().await?.into_builder();
61
+ metadata.set_file(source_size);
62
+ Ok(metadata.build())
54
63
  })));
55
64
  };
56
65
 
@@ -59,10 +68,10 @@ pub fn new_azblob_copier(
59
68
  Ok(TwoWays::Two(oio::BlockCopier::new(
60
69
  ctx.executor().clone(),
61
70
  copier,
62
- opts.source_content_length_hint(),
71
+ source_content_length_hint,
63
72
  block_size.saturating_sub(1),
64
73
  block_size,
65
- opts.concurrent(),
74
+ concurrent,
66
75
  )))
67
76
  }
68
77
 
@@ -76,10 +85,11 @@ pub struct AzblobCopier {
76
85
 
77
86
  impl oio::BlockCopy for AzblobCopier {
78
87
  async fn source_metadata(&self) -> Result<Metadata> {
79
- let mut args = OpStat::default();
80
- if let Some(version) = self.args.source_version() {
81
- args = args.with_version(version);
88
+ let args = options::StatOptions {
89
+ version: self.args.source_version().map(str::to_owned),
90
+ ..Default::default()
82
91
  }
92
+ .into();
83
93
 
84
94
  let resp = self
85
95
  .core
@@ -89,13 +99,16 @@ impl oio::BlockCopy for AzblobCopier {
89
99
  match resp.status() {
90
100
  StatusCode::OK => {
91
101
  let headers = resp.headers();
92
- let mut meta = parse_into_metadata(&self.from, headers)?;
102
+ let mut meta = parse_into_metadata(&self.from, headers)?.into_builder();
93
103
  if let Some(version_id) = parse_header_to_str(headers, X_MS_VERSION_ID)? {
94
- meta.set_version(version_id);
104
+ meta.version(version_id);
95
105
  }
96
- Ok(meta)
106
+ Ok(meta.build())
97
107
  }
98
- _ => Err(parse_error(resp)),
108
+ _ => Err(parse_error(
109
+ ErrorContext::new(ServiceOperation("GetBlobProperties")),
110
+ resp,
111
+ )),
99
112
  }
100
113
  }
101
114
 
@@ -107,7 +120,12 @@ impl oio::BlockCopy for AzblobCopier {
107
120
 
108
121
  match resp.status() {
109
122
  StatusCode::ACCEPTED => AzblobWriter::parse_metadata(resp.headers()),
110
- _ => Err(parse_error(resp)),
123
+ _ => Err(parse_error(
124
+ ErrorContext::new(ServiceOperation("CopyBlob"))
125
+ .with_caller_condition(self.args.is_conditional())
126
+ .with_if_not_exists(self.args.if_not_exists()),
127
+ resp,
128
+ )),
111
129
  }
112
130
  }
113
131
 
@@ -126,7 +144,10 @@ impl oio::BlockCopy for AzblobCopier {
126
144
 
127
145
  match resp.status() {
128
146
  StatusCode::CREATED | StatusCode::OK => Ok(()),
129
- _ => Err(parse_error(resp)),
147
+ _ => Err(parse_error(
148
+ ErrorContext::new(ServiceOperation("PutBlockFromUrl")),
149
+ resp,
150
+ )),
130
151
  }
131
152
  }
132
153
 
@@ -139,7 +160,12 @@ impl oio::BlockCopy for AzblobCopier {
139
160
  let meta = AzblobWriter::parse_metadata(resp.headers())?;
140
161
  match resp.status() {
141
162
  StatusCode::CREATED | StatusCode::OK => Ok(meta),
142
- _ => Err(parse_error(resp)),
163
+ _ => Err(parse_error(
164
+ ErrorContext::new(ServiceOperation("PutBlockList"))
165
+ .with_caller_condition(self.args.is_conditional())
166
+ .with_if_not_exists(self.args.if_not_exists()),
167
+ resp,
168
+ )),
143
169
  }
144
170
  }
145
171