This is page 72 of 74. Use http://codebase.md/apache/opendal?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .asf.yaml
├── .config
│ └── nextest.toml
├── .devcontainer
│ ├── devcontainer.json
│ └── post_create.sh
├── .editorconfig
├── .env.example
├── .gitattributes
├── .github
│ ├── actions
│ │ ├── fuzz_test
│ │ │ └── action.yaml
│ │ ├── setup
│ │ │ └── action.yaml
│ │ ├── setup-hadoop
│ │ │ └── action.yaml
│ │ ├── setup-ocaml
│ │ │ └── action.yaml
│ │ ├── test_behavior_binding_c
│ │ │ └── action.yaml
│ │ ├── test_behavior_binding_cpp
│ │ │ └── action.yaml
│ │ ├── test_behavior_binding_go
│ │ │ └── action.yaml
│ │ ├── test_behavior_binding_java
│ │ │ └── action.yaml
│ │ ├── test_behavior_binding_nodejs
│ │ │ └── action.yaml
│ │ ├── test_behavior_binding_python
│ │ │ └── action.yaml
│ │ ├── test_behavior_core
│ │ │ └── action.yaml
│ │ └── test_behavior_integration_object_store
│ │ └── action.yml
│ ├── CODEOWNERS
│ ├── dependabot.yml
│ ├── ISSUE_TEMPLATE
│ │ ├── 1-bug-report.yml
│ │ ├── 2-feature-request.yml
│ │ ├── 3-new-release.md
│ │ └── config.yml
│ ├── pull_request_template.md
│ ├── release.yml
│ ├── scripts
│ │ ├── test_behavior
│ │ │ ├── __init__.py
│ │ │ ├── plan.py
│ │ │ └── test_plan.py
│ │ ├── test_go_binding
│ │ │ ├── generate_test_scheme.py
│ │ │ └── matrix.yaml
│ │ └── weekly_update
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── main.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── services
│ │ ├── aliyun_drive
│ │ │ └── aliyun_drive
│ │ │ └── disable_action.yml
│ │ ├── alluxio
│ │ │ └── alluxio
│ │ │ └── action.yml
│ │ ├── azblob
│ │ │ ├── azure_azblob
│ │ │ │ └── action.yml
│ │ │ └── azurite_azblob
│ │ │ └── action.yml
│ │ ├── azdls
│ │ │ └── azdls
│ │ │ └── action.yml
│ │ ├── azfile
│ │ │ └── azfile
│ │ │ └── action.yml
│ │ ├── b2
│ │ │ └── b2
│ │ │ └── action.yml
│ │ ├── cacache
│ │ │ └── cacache
│ │ │ └── action.yml
│ │ ├── compfs
│ │ │ └── compfs
│ │ │ └── action.yml
│ │ ├── cos
│ │ │ └── cos
│ │ │ └── action.yml
│ │ ├── dashmap
│ │ │ └── dashmap
│ │ │ └── action.yml
│ │ ├── dropbox
│ │ │ └── dropbox
│ │ │ └── disable_action.yml
│ │ ├── etcd
│ │ │ ├── etcd
│ │ │ │ └── action.yml
│ │ │ ├── etcd-cluster
│ │ │ │ └── action.yml
│ │ │ └── etcd-tls
│ │ │ └── action.yml
│ │ ├── fs
│ │ │ └── local_fs
│ │ │ └── action.yml
│ │ ├── ftp
│ │ │ └── vsftpd
│ │ │ └── disable_action.yml
│ │ ├── gcs
│ │ │ ├── gcs
│ │ │ │ └── action.yml
│ │ │ └── gcs_with_default_storage_class
│ │ │ └── action.yml
│ │ ├── gdrive
│ │ │ └── gdrive
│ │ │ └── action.yml
│ │ ├── gridfs
│ │ │ ├── gridfs
│ │ │ │ └── action.yml
│ │ │ └── gridfs_with_basic_auth
│ │ │ └── action.yml
│ │ ├── hdfs
│ │ │ ├── hdfs_cluster
│ │ │ │ └── action.yml
│ │ │ ├── hdfs_cluster_with_atomic_write_dir
│ │ │ │ └── action.yml
│ │ │ ├── hdfs_default
│ │ │ │ └── action.yml
│ │ │ ├── hdfs_default_gcs
│ │ │ │ └── action.yml
│ │ │ ├── hdfs_default_on_azurite_azblob
│ │ │ │ └── action.yml
│ │ │ ├── hdfs_default_on_minio_s3
│ │ │ │ └── action.yml
│ │ │ └── hdfs_default_with_atomic_write_dir
│ │ │ └── action.yml
│ │ ├── hdfs_native
│ │ │ └── hdfs_native_cluster
│ │ │ └── action.yml
│ │ ├── http
│ │ │ ├── caddy
│ │ │ │ └── action.yml
│ │ │ └── nginx
│ │ │ └── action.yml
│ │ ├── huggingface
│ │ │ └── huggingface
│ │ │ └── action.yml
│ │ ├── koofr
│ │ │ └── koofr
│ │ │ └── disable_action.yml
│ │ ├── memcached
│ │ │ ├── memcached
│ │ │ │ └── action.yml
│ │ │ └── memcached_with_auth
│ │ │ └── action.yml
│ │ ├── memory
│ │ │ └── memory
│ │ │ └── action.yml
│ │ ├── mini_moka
│ │ │ └── mini_moka
│ │ │ └── action.yml
│ │ ├── moka
│ │ │ └── moka
│ │ │ └── action.yml
│ │ ├── mongodb
│ │ │ ├── mongodb_with_basic_auth
│ │ │ │ └── action.yml
│ │ │ └── mongodb_with_no_auth
│ │ │ └── action.yml
│ │ ├── monoiofs
│ │ │ └── monoiofs
│ │ │ └── action.yml
│ │ ├── mysql
│ │ │ └── mysql
│ │ │ └── action.yml
│ │ ├── oss
│ │ │ ├── oss
│ │ │ │ └── action.yml
│ │ │ └── oss_with_versioning
│ │ │ └── action.yml
│ │ ├── persy
│ │ │ └── persy
│ │ │ └── action.yml
│ │ ├── postgresql
│ │ │ └── postgresql
│ │ │ └── action.yml
│ │ ├── redb
│ │ │ └── redb
│ │ │ └── action.yml
│ │ ├── redis
│ │ │ ├── dragonfly
│ │ │ │ └── action.yml
│ │ │ ├── kvrocks
│ │ │ │ └── action.yml
│ │ │ ├── redis
│ │ │ │ └── action.yml
│ │ │ ├── redis_tls
│ │ │ │ └── action.yml
│ │ │ ├── redis_with_cluster
│ │ │ │ └── action.yml
│ │ │ └── redis_with_cluster_tls
│ │ │ └── action.yml
│ │ ├── rocksdb
│ │ │ └── rocksdb
│ │ │ └── action.yml
│ │ ├── s3
│ │ │ ├── 0_minio_s3
│ │ │ │ └── action.yml
│ │ │ ├── aws_s3
│ │ │ │ └── action.yml
│ │ │ ├── aws_s3_with_list_objects_v1
│ │ │ │ └── action.yml
│ │ │ ├── aws_s3_with_sse_c
│ │ │ │ └── action.yml
│ │ │ ├── aws_s3_with_versioning
│ │ │ │ └── action.yml
│ │ │ ├── aws_s3_with_virtual_host
│ │ │ │ └── action.yml
│ │ │ ├── ceph_radios_s3_with_versioning
│ │ │ │ └── disable_action.yml
│ │ │ ├── ceph_rados_s3
│ │ │ │ └── disable_action.yml
│ │ │ ├── minio_s3_with_anonymous
│ │ │ │ └── action.yml
│ │ │ ├── minio_s3_with_list_objects_v1
│ │ │ │ └── action.yml
│ │ │ ├── minio_s3_with_versioning
│ │ │ │ └── action.yml
│ │ │ └── r2
│ │ │ └── disabled_action.yml
│ │ ├── seafile
│ │ │ └── seafile
│ │ │ └── action.yml
│ │ ├── sftp
│ │ │ ├── sftp
│ │ │ │ └── action.yml
│ │ │ └── sftp_with_default_root
│ │ │ └── action.yml
│ │ ├── sled
│ │ │ ├── sled
│ │ │ │ └── action.yml
│ │ │ └── sled_with_tree
│ │ │ └── action.yml
│ │ ├── sqlite
│ │ │ └── sqlite
│ │ │ └── action.yml
│ │ ├── swift
│ │ │ ├── ceph_rados_swift
│ │ │ │ └── action.yml
│ │ │ └── swift
│ │ │ └── action.yml
│ │ ├── tikv
│ │ │ └── tikv
│ │ │ └── disable_action.yml
│ │ ├── webdav
│ │ │ ├── 0_nginx
│ │ │ │ └── action.yml
│ │ │ ├── jfrog
│ │ │ │ └── disabled_action.yml
│ │ │ ├── nextcloud
│ │ │ │ └── action.yml
│ │ │ ├── nginx_with_empty_password
│ │ │ │ └── action.yml
│ │ │ ├── nginx_with_password
│ │ │ │ └── action.yml
│ │ │ ├── nginx_with_redirect
│ │ │ │ └── action.yml
│ │ │ └── owncloud
│ │ │ └── action.yml
│ │ └── webhdfs
│ │ ├── webhdfs
│ │ │ └── action.yml
│ │ ├── webhdfs_with_list_batch_disabled
│ │ │ └── action.yml
│ │ └── webhdfs_with_user_name
│ │ └── action.yml
│ └── workflows
│ ├── ci_bindings_c.yml
│ ├── ci_bindings_cpp.yml
│ ├── ci_bindings_d.yml
│ ├── ci_bindings_dart.yml
│ ├── ci_bindings_dotnet.yml
│ ├── ci_bindings_go.yml
│ ├── ci_bindings_haskell.yml
│ ├── ci_bindings_java.yml
│ ├── ci_bindings_lua.yml
│ ├── ci_bindings_nodejs.yml
│ ├── ci_bindings_ocaml.yml
│ ├── ci_bindings_php.yml
│ ├── ci_bindings_python.yml
│ ├── ci_bindings_ruby.yml
│ ├── ci_bindings_swift.yml
│ ├── ci_bindings_zig.yml
│ ├── ci_check.yml
│ ├── ci_core.yml
│ ├── ci_integration_dav_server.yml
│ ├── ci_integration_object_store.yml
│ ├── ci_integration_parquet.yml
│ ├── ci_integration_spring.yml
│ ├── ci_integration_unftp_sbe.yml
│ ├── ci_odev.yml
│ ├── ci_weekly_update.yml
│ ├── discussion-thread-link.yml
│ ├── docs.yml
│ ├── full-ci-promote.yml
│ ├── release_dart.yml
│ ├── release_java.yml
│ ├── release_nodejs.yml
│ ├── release_python.yml
│ ├── release_ruby.yml
│ ├── release_rust.yml
│ ├── service_test_ghac.yml
│ ├── test_behavior_binding_c.yml
│ ├── test_behavior_binding_cpp.yml
│ ├── test_behavior_binding_go.yml
│ ├── test_behavior_binding_java.yml
│ ├── test_behavior_binding_nodejs.yml
│ ├── test_behavior_binding_python.yml
│ ├── test_behavior_core.yml
│ ├── test_behavior_integration_object_store.yml
│ ├── test_behavior.yml
│ ├── test_edge.yml
│ └── test_fuzz.yml
├── .gitignore
├── .taplo.toml
├── .typos.toml
├── .vscode
│ └── settings.json
├── .yamlfmt
├── AGENTS.md
├── bindings
│ ├── java
│ │ ├── .cargo
│ │ │ └── config.toml
│ │ ├── .gitignore
│ │ ├── .mvn
│ │ │ └── wrapper
│ │ │ └── maven-wrapper.properties
│ │ ├── Cargo.toml
│ │ ├── DEPENDENCIES.md
│ │ ├── DEPENDENCIES.rust.tsv
│ │ ├── mvnw
│ │ ├── mvnw.cmd
│ │ ├── pom.xml
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── async_operator.rs
│ │ │ ├── convert.rs
│ │ │ ├── error.rs
│ │ │ ├── executor.rs
│ │ │ ├── layer.rs
│ │ │ ├── lib.rs
│ │ │ ├── main
│ │ │ │ ├── java
│ │ │ │ │ └── org
│ │ │ │ │ └── apache
│ │ │ │ │ └── opendal
│ │ │ │ │ ├── AsyncExecutor.java
│ │ │ │ │ ├── AsyncOperator.java
│ │ │ │ │ ├── Capability.java
│ │ │ │ │ ├── Entry.java
│ │ │ │ │ ├── Environment.java
│ │ │ │ │ ├── layer
│ │ │ │ │ │ ├── ConcurrentLimitLayer.java
│ │ │ │ │ │ ├── package-info.java
│ │ │ │ │ │ └── RetryLayer.java
│ │ │ │ │ ├── Layer.java
│ │ │ │ │ ├── ListOptions.java
│ │ │ │ │ ├── Metadata.java
│ │ │ │ │ ├── NativeLibrary.java
│ │ │ │ │ ├── NativeObject.java
│ │ │ │ │ ├── OpenDAL.java
│ │ │ │ │ ├── OpenDALException.java
│ │ │ │ │ ├── Operator.java
│ │ │ │ │ ├── OperatorInfo.java
│ │ │ │ │ ├── OperatorInputStream.java
│ │ │ │ │ ├── OperatorOutputStream.java
│ │ │ │ │ ├── package-info.java
│ │ │ │ │ ├── PresignedRequest.java
│ │ │ │ │ ├── ReadOptions.java
│ │ │ │ │ ├── ServiceConfig.java
│ │ │ │ │ ├── StatOptions.java
│ │ │ │ │ └── WriteOptions.java
│ │ │ │ └── resources
│ │ │ │ ├── bindings.properties
│ │ │ │ └── META-INF
│ │ │ │ └── NOTICE
│ │ │ ├── operator_input_stream.rs
│ │ │ ├── operator_output_stream.rs
│ │ │ ├── operator.rs
│ │ │ ├── test
│ │ │ │ └── java
│ │ │ │ └── org
│ │ │ │ └── apache
│ │ │ │ └── opendal
│ │ │ │ └── test
│ │ │ │ ├── AsyncExecutorTest.java
│ │ │ │ ├── behavior
│ │ │ │ │ ├── AsyncCopyTest.java
│ │ │ │ │ ├── AsyncCreateDirTest.java
│ │ │ │ │ ├── AsyncListTest.java
│ │ │ │ │ ├── AsyncPresignTest.java
│ │ │ │ │ ├── AsyncReadOnlyTest.java
│ │ │ │ │ ├── AsyncRenameTest.java
│ │ │ │ │ ├── AsyncStatOptionsTest.java
│ │ │ │ │ ├── AsyncWriteOptionsTest.java
│ │ │ │ │ ├── AsyncWriteTest.java
│ │ │ │ │ ├── BehaviorExtension.java
│ │ │ │ │ ├── BehaviorTestBase.java
│ │ │ │ │ ├── BlockingCopyTest.java
│ │ │ │ │ ├── BlockingCreateDirTest.java
│ │ │ │ │ ├── BlockingListTest.java
│ │ │ │ │ ├── BlockingReadOnlyTest.java
│ │ │ │ │ ├── BlockingRenameTest.java
│ │ │ │ │ ├── BlockingStatOptionsTest.java
│ │ │ │ │ ├── BlockingWriteOptionTest.java
│ │ │ │ │ ├── BlockingWriteTest.java
│ │ │ │ │ └── RegressionTest.java
│ │ │ │ ├── condition
│ │ │ │ │ └── OpenDALExceptionCondition.java
│ │ │ │ ├── LayerTest.java
│ │ │ │ ├── MetadataTest.java
│ │ │ │ ├── OperatorDuplicateTest.java
│ │ │ │ ├── OperatorInfoTest.java
│ │ │ │ ├── OperatorInputOutputStreamTest.java
│ │ │ │ ├── OperatorUtf8DecodeTest.java
│ │ │ │ └── UtilityTest.java
│ │ │ └── utility.rs
│ │ ├── tools
│ │ │ └── build.py
│ │ ├── upgrade.md
│ │ └── users.md
│ ├── nodejs
│ │ ├── .cargo
│ │ │ └── config.toml
│ │ ├── .gitignore
│ │ ├── .node-version
│ │ ├── .npmignore
│ │ ├── .npmrc
│ │ ├── .prettierignore
│ │ ├── benchmark
│ │ │ ├── deno.ts
│ │ │ ├── node.js
│ │ │ └── README.md
│ │ ├── build.rs
│ │ ├── Cargo.toml
│ │ ├── CONTRIBUTING.md
│ │ ├── DEPENDENCIES.md
│ │ ├── DEPENDENCIES.rust.tsv
│ │ ├── devbox.json
│ │ ├── devbox.lock
│ │ ├── generated.d.ts
│ │ ├── generated.js
│ │ ├── index.cjs
│ │ ├── index.d.ts
│ │ ├── index.mjs
│ │ ├── npm
│ │ │ ├── darwin-arm64
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── darwin-x64
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── linux-arm64-gnu
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── linux-arm64-musl
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── linux-x64-gnu
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── linux-x64-musl
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── win32-arm64-msvc
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ └── win32-x64-msvc
│ │ │ ├── package.json
│ │ │ └── README.md
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── README.md
│ │ ├── scripts
│ │ │ └── header.mjs
│ │ ├── src
│ │ │ ├── capability.rs
│ │ │ ├── layer.rs
│ │ │ ├── lib.rs
│ │ │ └── options.rs
│ │ ├── tests
│ │ │ ├── service.test.mjs
│ │ │ ├── suites
│ │ │ │ ├── async.suite.mjs
│ │ │ │ ├── asyncDeleteOptions.suite.mjs
│ │ │ │ ├── asyncLister.suite.mjs
│ │ │ │ ├── asyncListOptions.suite.mjs
│ │ │ │ ├── asyncReadOptions.suite.mjs
│ │ │ │ ├── asyncStatOptions.suite.mjs
│ │ │ │ ├── asyncWriteOptions.suite.mjs
│ │ │ │ ├── index.mjs
│ │ │ │ ├── layer.suite.mjs
│ │ │ │ ├── services.suite.mjs
│ │ │ │ ├── sync.suite.mjs
│ │ │ │ ├── syncDeleteOptions.suite.mjs
│ │ │ │ ├── syncLister.suite.mjs
│ │ │ │ ├── syncListOptions.suite.mjs
│ │ │ │ ├── syncReadOptions.suite.mjs
│ │ │ │ ├── syncStatOptions.suite.mjs
│ │ │ │ └── syncWriteOptions.suite.mjs
│ │ │ └── utils.mjs
│ │ ├── theme
│ │ │ ├── index.tsx
│ │ │ └── package.json
│ │ ├── tsconfig.json
│ │ ├── tsconfig.theme.json
│ │ ├── typedoc.json
│ │ ├── upgrade.md
│ │ └── vitest.config.mjs
│ ├── python
│ │ ├── .gitignore
│ │ ├── benchmark
│ │ │ ├── async_opendal_benchmark.py
│ │ │ ├── async_origin_s3_benchmark_with_gevent.py
│ │ │ └── README.md
│ │ ├── Cargo.toml
│ │ ├── CONTRIBUTING.md
│ │ ├── DEPENDENCIES.md
│ │ ├── DEPENDENCIES.rust.tsv
│ │ ├── docs
│ │ │ ├── api
│ │ │ │ ├── async_file.md
│ │ │ │ ├── async_operator.md
│ │ │ │ ├── capability.md
│ │ │ │ ├── exceptions.md
│ │ │ │ ├── file.md
│ │ │ │ ├── layers.md
│ │ │ │ ├── operator.md
│ │ │ │ └── types.md
│ │ │ └── index.md
│ │ ├── justfile
│ │ ├── mkdocs.yml
│ │ ├── pyproject.toml
│ │ ├── pyrightconfig.json
│ │ ├── python
│ │ │ └── opendal
│ │ │ ├── __init__.py
│ │ │ ├── capability.pyi
│ │ │ ├── exceptions.pyi
│ │ │ ├── file.pyi
│ │ │ ├── layers.pyi
│ │ │ ├── operator.pyi
│ │ │ ├── py.typed
│ │ │ ├── services.pyi
│ │ │ └── types.pyi
│ │ ├── README.md
│ │ ├── ruff.toml
│ │ ├── src
│ │ │ ├── capability.rs
│ │ │ ├── errors.rs
│ │ │ ├── file.rs
│ │ │ ├── layers.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── metadata.rs
│ │ │ ├── operator.rs
│ │ │ ├── options.rs
│ │ │ ├── services.rs
│ │ │ └── utils.rs
│ │ ├── template
│ │ │ └── module.html.jinja2
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_async_check.py
│ │ │ ├── test_async_copy.py
│ │ │ ├── test_async_delete.py
│ │ │ ├── test_async_exists.py
│ │ │ ├── test_async_list.py
│ │ │ ├── test_async_pickle_types.py
│ │ │ ├── test_async_rename.py
│ │ │ ├── test_capability.py
│ │ │ ├── test_exceptions.py
│ │ │ ├── test_pickle_rw.py
│ │ │ ├── test_read.py
│ │ │ ├── test_sync_check.py
│ │ │ ├── test_sync_copy.py
│ │ │ ├── test_sync_delete.py
│ │ │ ├── test_sync_exists.py
│ │ │ ├── test_sync_list.py
│ │ │ ├── test_sync_pickle_types.py
│ │ │ ├── test_sync_rename.py
│ │ │ └── test_write.py
│ │ ├── upgrade.md
│ │ ├── users.md
│ │ └── uv.lock
│ └── README.md
├── CHANGELOG.md
├── CITATION.cff
├── CLAUDE.md
├── CONTRIBUTING.md
├── core
│ ├── benches
│ │ ├── ops
│ │ │ ├── main.rs
│ │ │ ├── read.rs
│ │ │ ├── README.md
│ │ │ ├── utils.rs
│ │ │ └── write.rs
│ │ ├── README.md
│ │ ├── types
│ │ │ ├── buffer.rs
│ │ │ ├── main.rs
│ │ │ ├── README.md
│ │ │ └── tasks.rs
│ │ ├── vs_fs
│ │ │ ├── Cargo.toml
│ │ │ ├── README.md
│ │ │ └── src
│ │ │ └── main.rs
│ │ └── vs_s3
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ └── src
│ │ └── main.rs
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── CHANGELOG.md
│ ├── CONTRIBUTING.md
│ ├── core
│ │ ├── Cargo.toml
│ │ └── src
│ │ ├── blocking
│ │ │ ├── delete.rs
│ │ │ ├── list.rs
│ │ │ ├── mod.rs
│ │ │ ├── operator.rs
│ │ │ ├── read
│ │ │ │ ├── buffer_iterator.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── reader.rs
│ │ │ │ ├── std_bytes_iterator.rs
│ │ │ │ └── std_reader.rs
│ │ │ └── write
│ │ │ ├── mod.rs
│ │ │ ├── std_writer.rs
│ │ │ └── writer.rs
│ │ ├── docs
│ │ │ ├── comparisons
│ │ │ │ ├── mod.rs
│ │ │ │ └── vs_object_store.md
│ │ │ ├── concepts.rs
│ │ │ ├── internals
│ │ │ │ ├── accessor.rs
│ │ │ │ ├── layer.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mod.rs
│ │ │ ├── performance
│ │ │ │ ├── concurrent_write.md
│ │ │ │ ├── http_optimization.md
│ │ │ │ └── mod.rs
│ │ │ ├── rfcs
│ │ │ │ ├── 0000_example.md
│ │ │ │ ├── 0041_object_native_api.md
│ │ │ │ ├── 0044_error_handle.md
│ │ │ │ ├── 0057_auto_region.md
│ │ │ │ ├── 0069_object_stream.md
│ │ │ │ ├── 0090_limited_reader.md
│ │ │ │ ├── 0112_path_normalization.md
│ │ │ │ ├── 0191_async_streaming_io.md
│ │ │ │ ├── 0203_remove_credential.md
│ │ │ │ ├── 0221_create_dir.md
│ │ │ │ ├── 0247_retryable_error.md
│ │ │ │ ├── 0293_object_id.md
│ │ │ │ ├── 0337_dir_entry.md
│ │ │ │ ├── 0409_accessor_capabilities.md
│ │ │ │ ├── 0413_presign.md
│ │ │ │ ├── 0423_command_line_interface.md
│ │ │ │ ├── 0429_init_from_iter.md
│ │ │ │ ├── 0438_multipart.md
│ │ │ │ ├── 0443_gateway.md
│ │ │ │ ├── 0501_new_builder.md
│ │ │ │ ├── 0554_write_refactor.md
│ │ │ │ ├── 0561_list_metadata_reuse.md
│ │ │ │ ├── 0599_blocking_api.md
│ │ │ │ ├── 0623_redis_service.md
│ │ │ │ ├── 0627_split_capabilities.md
│ │ │ │ ├── 0661_path_in_accessor.md
│ │ │ │ ├── 0793_generic_kv_services.md
│ │ │ │ ├── 0926_object_reader.md
│ │ │ │ ├── 0977_refactor_error.md
│ │ │ │ ├── 1085_object_handler.md
│ │ │ │ ├── 1391_object_metadataer.md
│ │ │ │ ├── 1398_query_based_metadata.md
│ │ │ │ ├── 1420_object_writer.md
│ │ │ │ ├── 1477_remove_object_concept.md
│ │ │ │ ├── 1735_operation_extension.md
│ │ │ │ ├── 2083_writer_sink_api.md
│ │ │ │ ├── 2133_append_api.md
│ │ │ │ ├── 2299_chain_based_operator_api.md
│ │ │ │ ├── 2602_object_versioning.md
│ │ │ │ ├── 2758_merge_append_into_write.md
│ │ │ │ ├── 2774_lister_api.md
│ │ │ │ ├── 2779_list_with_metakey.md
│ │ │ │ ├── 2852_native_capability.md
│ │ │ │ ├── 2884_merge_range_read_into_read.md
│ │ │ │ ├── 3017_remove_write_copy_from.md
│ │ │ │ ├── 3197_config.md
│ │ │ │ ├── 3232_align_list_api.md
│ │ │ │ ├── 3243_list_prefix.md
│ │ │ │ ├── 3356_lazy_reader.md
│ │ │ │ ├── 3526_list_recursive.md
│ │ │ │ ├── 3574_concurrent_stat_in_list.md
│ │ │ │ ├── 3734_buffered_reader.md
│ │ │ │ ├── 3898_concurrent_writer.md
│ │ │ │ ├── 3911_deleter_api.md
│ │ │ │ ├── 4382_range_based_read.md
│ │ │ │ ├── 4638_executor.md
│ │ │ │ ├── 5314_remove_metakey.md
│ │ │ │ ├── 5444_operator_from_uri.md
│ │ │ │ ├── 5479_context.md
│ │ │ │ ├── 5485_conditional_reader.md
│ │ │ │ ├── 5495_list_with_deleted.md
│ │ │ │ ├── 5556_write_returns_metadata.md
│ │ │ │ ├── 5871_read_returns_metadata.md
│ │ │ │ ├── 6189_remove_native_blocking.md
│ │ │ │ ├── 6209_glob_support.md
│ │ │ │ ├── 6213_options_api.md
│ │ │ │ ├── 6370_foyer_integration.md
│ │ │ │ ├── 6678_simulate_layer.md
│ │ │ │ ├── 6707_capability_override_layer.md
│ │ │ │ ├── 6817_checksum.md
│ │ │ │ ├── 6828_core.md
│ │ │ │ ├── 7130_route_layer.md
│ │ │ │ ├── mod.rs
│ │ │ │ └── README.md
│ │ │ └── upgrade.md
│ │ ├── layers
│ │ │ ├── complete.rs
│ │ │ ├── correctness_check.rs
│ │ │ ├── error_context.rs
│ │ │ ├── http_client.rs
│ │ │ ├── mod.rs
│ │ │ ├── simulate.rs
│ │ │ └── type_eraser.rs
│ │ ├── lib.rs
│ │ ├── raw
│ │ │ ├── accessor.rs
│ │ │ ├── atomic_util.rs
│ │ │ ├── enum_utils.rs
│ │ │ ├── futures_util.rs
│ │ │ ├── http_util
│ │ │ │ ├── body.rs
│ │ │ │ ├── bytes_content_range.rs
│ │ │ │ ├── bytes_range.rs
│ │ │ │ ├── client.rs
│ │ │ │ ├── error.rs
│ │ │ │ ├── header.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── multipart.rs
│ │ │ │ └── uri.rs
│ │ │ ├── layer.rs
│ │ │ ├── mod.rs
│ │ │ ├── oio
│ │ │ │ ├── buf
│ │ │ │ │ ├── flex_buf.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── pooled_buf.rs
│ │ │ │ │ └── queue_buf.rs
│ │ │ │ ├── delete
│ │ │ │ │ ├── api.rs
│ │ │ │ │ ├── batch_delete.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ └── one_shot_delete.rs
│ │ │ │ ├── entry.rs
│ │ │ │ ├── list
│ │ │ │ │ ├── api.rs
│ │ │ │ │ ├── flat_list.rs
│ │ │ │ │ ├── hierarchy_list.rs
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── page_list.rs
│ │ │ │ │ └── prefix_list.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── read
│ │ │ │ │ ├── api.rs
│ │ │ │ │ └── mod.rs
│ │ │ │ └── write
│ │ │ │ ├── api.rs
│ │ │ │ ├── append_write.rs
│ │ │ │ ├── block_write.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── multipart_write.rs
│ │ │ │ ├── one_shot_write.rs
│ │ │ │ └── position_write.rs
│ │ │ ├── operation.rs
│ │ │ ├── ops.rs
│ │ │ ├── path_cache.rs
│ │ │ ├── path.rs
│ │ │ ├── rps.rs
│ │ │ ├── serde_util.rs
│ │ │ ├── std_io_util.rs
│ │ │ ├── time.rs
│ │ │ ├── tokio_util.rs
│ │ │ └── version.rs
│ │ ├── services
│ │ │ ├── memory
│ │ │ │ ├── backend.rs
│ │ │ │ ├── config.rs
│ │ │ │ ├── core.rs
│ │ │ │ ├── deleter.rs
│ │ │ │ ├── docs.md
│ │ │ │ ├── lister.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── writer.rs
│ │ │ └── mod.rs
│ │ └── types
│ │ ├── buffer.rs
│ │ ├── builder.rs
│ │ ├── capability.rs
│ │ ├── context
│ │ │ ├── mod.rs
│ │ │ ├── read.rs
│ │ │ └── write.rs
│ │ ├── delete
│ │ │ ├── deleter.rs
│ │ │ ├── futures_delete_sink.rs
│ │ │ ├── input.rs
│ │ │ └── mod.rs
│ │ ├── entry.rs
│ │ ├── error.rs
│ │ ├── execute
│ │ │ ├── api.rs
│ │ │ ├── executor.rs
│ │ │ ├── executors
│ │ │ │ ├── mod.rs
│ │ │ │ └── tokio_executor.rs
│ │ │ └── mod.rs
│ │ ├── list.rs
│ │ ├── metadata.rs
│ │ ├── mod.rs
│ │ ├── mode.rs
│ │ ├── operator
│ │ │ ├── builder.rs
│ │ │ ├── info.rs
│ │ │ ├── mod.rs
│ │ │ ├── operator_futures.rs
│ │ │ ├── operator.rs
│ │ │ ├── registry.rs
│ │ │ └── uri.rs
│ │ ├── options.rs
│ │ ├── read
│ │ │ ├── buffer_stream.rs
│ │ │ ├── futures_async_reader.rs
│ │ │ ├── futures_bytes_stream.rs
│ │ │ ├── mod.rs
│ │ │ └── reader.rs
│ │ └── write
│ │ ├── buffer_sink.rs
│ │ ├── futures_async_writer.rs
│ │ ├── futures_bytes_sink.rs
│ │ ├── mod.rs
│ │ └── writer.rs
│ ├── DEPENDENCIES.md
│ ├── DEPENDENCIES.rust.tsv
│ ├── edge
│ │ ├── file_write_on_full_disk
│ │ │ ├── Cargo.toml
│ │ │ ├── README.md
│ │ │ └── src
│ │ │ └── main.rs
│ │ ├── README.md
│ │ ├── s3_aws_assume_role_with_web_identity
│ │ │ ├── Cargo.toml
│ │ │ ├── README.md
│ │ │ └── src
│ │ │ └── main.rs
│ │ └── s3_read_on_wasm
│ │ ├── .gitignore
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── src
│ │ │ └── lib.rs
│ │ └── webdriver.json
│ ├── fuzz
│ │ ├── .gitignore
│ │ ├── Cargo.toml
│ │ ├── fuzz_reader.rs
│ │ ├── fuzz_writer.rs
│ │ └── README.md
│ ├── layers
│ │ ├── async-backtrace
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── await-tree
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── capability-check
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── chaos
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── concurrent-limit
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── dtrace
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── fastmetrics
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── fastrace
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── foyer
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── hotpath
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── immutable-index
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── logging
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── metrics
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── mime-guess
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── observe-metrics-common
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── otelmetrics
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── oteltrace
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── prometheus
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── prometheus-client
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── retry
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── route
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── tail-cut
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── throttle
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── timeout
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ └── tracing
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── lib.rs
│ ├── LICENSE
│ ├── README.md
│ ├── services
│ │ ├── aliyun-drive
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── alluxio
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── azblob
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── azdls
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── azfile
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── azure-common
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ │ ├── b2
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── cacache
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── cloudflare-kv
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── model.rs
│ │ │ └── writer.rs
│ │ ├── compfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── reader.rs
│ │ │ └── writer.rs
│ │ ├── cos
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── d1
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── model.rs
│ │ │ └── writer.rs
│ │ ├── dashmap
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── dbfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── dropbox
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── builder.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── etcd
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── foundationdb
│ │ │ ├── build.rs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── fs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── reader.rs
│ │ │ └── writer.rs
│ │ ├── ftp
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── err.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── reader.rs
│ │ │ └── writer.rs
│ │ ├── gcs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── uri.rs
│ │ │ └── writer.rs
│ │ ├── gdrive
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── builder.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── ghac
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── github
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── mod.rs
│ │ │ └── writer.rs
│ │ ├── gridfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── hdfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── reader.rs
│ │ │ └── writer.rs
│ │ ├── hdfs-native
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── reader.rs
│ │ │ └── writer.rs
│ │ ├── http
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ └── lib.rs
│ │ ├── huggingface
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ └── lister.rs
│ │ ├── ipfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── ipld.rs
│ │ │ └── lib.rs
│ │ ├── ipmfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── builder.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── koofr
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── lakefs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── memcached
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── binary.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── mini_moka
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── moka
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── mongodb
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── monoiofs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ ├── reader.rs
│ │ │ └── writer.rs
│ │ ├── mysql
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── obs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── onedrive
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── builder.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── graph_model.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── opfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ └── utils.rs
│ │ ├── oss
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── pcloud
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── persy
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── postgresql
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── redb
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── redis
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── delete.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── rocksdb
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── s3
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── compatible_services.md
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── mod.rs
│ │ │ └── writer.rs
│ │ ├── seafile
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── sftp
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── reader.rs
│ │ │ ├── utils.rs
│ │ │ └── writer.rs
│ │ ├── sled
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── sqlite
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── surrealdb
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── swift
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── compatible_services.md
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── tikv
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── upyun
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── vercel-artifacts
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── builder.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ └── writer.rs
│ │ ├── vercel-blob
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── webdav
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ └── writer.rs
│ │ ├── webhdfs
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── backend.rs
│ │ │ ├── config.rs
│ │ │ ├── core.rs
│ │ │ ├── deleter.rs
│ │ │ ├── docs.md
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── lister.rs
│ │ │ ├── message.rs
│ │ │ └── writer.rs
│ │ └── yandex-disk
│ │ ├── Cargo.toml
│ │ └── src
│ │ ├── backend.rs
│ │ ├── config.rs
│ │ ├── core.rs
│ │ ├── deleter.rs
│ │ ├── docs.md
│ │ ├── error.rs
│ │ ├── lib.rs
│ │ ├── lister.rs
│ │ └── writer.rs
│ ├── src
│ │ └── lib.rs
│ ├── testkit
│ │ ├── Cargo.toml
│ │ └── src
│ │ ├── lib.rs
│ │ ├── read.rs
│ │ ├── utils.rs
│ │ └── write.rs
│ ├── tests
│ │ ├── behavior
│ │ │ ├── async_copy.rs
│ │ │ ├── async_create_dir.rs
│ │ │ ├── async_delete.rs
│ │ │ ├── async_list.rs
│ │ │ ├── async_presign.rs
│ │ │ ├── async_read.rs
│ │ │ ├── async_rename.rs
│ │ │ ├── async_stat.rs
│ │ │ ├── async_write.rs
│ │ │ ├── main.rs
│ │ │ ├── README.md
│ │ │ └── utils.rs
│ │ └── data
│ │ ├── normal_dir
│ │ │ └── .gitkeep
│ │ ├── normal_file.txt
│ │ ├── special_dir !@#$%^&()_+-=;',
│ │ │ └── .gitkeep
│ │ └── special_file !@#$%^&()_+-=;',.txt
│ ├── upgrade.md
│ └── users.md
├── deny.toml
├── DEPENDENCIES.md
├── dev
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ └── src
│ ├── generate
│ │ ├── java.j2
│ │ ├── java.rs
│ │ ├── mod.rs
│ │ ├── parser.rs
│ │ ├── python.j2
│ │ └── python.rs
│ ├── main.rs
│ └── release
│ ├── mod.rs
│ └── package.rs
├── doap.rdf
├── fixtures
│ ├── alluxio
│ │ └── docker-compose-alluxio.yml
│ ├── azblob
│ │ └── docker-compose-azurite.yml
│ ├── data
│ │ ├── normal_dir
│ │ │ └── .gitkeep
│ │ ├── normal_file.txt
│ │ ├── special_dir !@#$%^&()_+-=;',
│ │ │ └── .gitkeep
│ │ └── special_file !@#$%^&()_+-=;',.txt
│ ├── etcd
│ │ ├── ca-key.pem
│ │ ├── ca.pem
│ │ ├── client-key.pem
│ │ ├── client.pem
│ │ ├── docker-compose-cluster.yml
│ │ ├── docker-compose-standalone-tls.yml
│ │ ├── docker-compose-standalone.yml
│ │ ├── server-key.pem
│ │ └── server.pem
│ ├── ftp
│ │ └── docker-compose-vsftpd.yml
│ ├── hdfs
│ │ ├── azurite-azblob-core-site.xml
│ │ ├── docker-compose-hdfs-cluster.yml
│ │ ├── gcs-core-site.xml
│ │ ├── hdfs-site.xml
│ │ └── minio-s3-core-site.xml
│ ├── http
│ │ ├── Caddyfile
│ │ ├── docker-compose-caddy.yml
│ │ ├── docker-compose-nginx.yml
│ │ └── nginx.conf
│ ├── libsql
│ │ ├── docker-compose-auth.yml
│ │ └── docker-compose.yml
│ ├── memcached
│ │ ├── docker-compose-memcached-with-auth.yml
│ │ └── docker-compose-memcached.yml
│ ├── mongodb
│ │ ├── docker-compose-basic-auth.yml
│ │ └── docker-compose-no-auth.yml
│ ├── mysql
│ │ ├── docker-compose.yml
│ │ └── init.sql
│ ├── postgresql
│ │ ├── docker-compose.yml
│ │ └── init.sql
│ ├── redis
│ │ ├── docker-compose-dragonfly.yml
│ │ ├── docker-compose-kvrocks.yml
│ │ ├── docker-compose-redis-cluster-tls.yml
│ │ ├── docker-compose-redis-cluster.yml
│ │ ├── docker-compose-redis-tls.yml
│ │ ├── docker-compose-redis.yml
│ │ └── ssl
│ │ ├── .gitignore
│ │ ├── ca.crt
│ │ ├── ca.key
│ │ ├── ca.srl
│ │ ├── README.md
│ │ ├── redis.crt
│ │ ├── redis.key
│ │ └── req.conf
│ ├── s3
│ │ ├── docker-compose-ceph-rados.yml
│ │ └── docker-compose-minio.yml
│ ├── seafile
│ │ └── docker-compose-seafile.yml
│ ├── sftp
│ │ ├── change_root_dir.sh
│ │ ├── docker-compose-sftp-with-default-root.yml
│ │ ├── docker-compose-sftp.yml
│ │ ├── health-check.sh
│ │ ├── test_ssh_key
│ │ └── test_ssh_key.pub
│ ├── sqlite
│ │ └── data.sql
│ ├── swift
│ │ ├── docker-compose-ceph-rados.yml
│ │ └── docker-compose-swift.yml
│ ├── tikv
│ │ ├── gen_cert.sh
│ │ ├── pd-tls.toml
│ │ ├── pd.toml
│ │ ├── ssl
│ │ │ ├── ca-key.pem
│ │ │ ├── ca.pem
│ │ │ ├── client-key.pem
│ │ │ ├── client.pem
│ │ │ ├── pd-server-key.pem
│ │ │ ├── pd-server.pem
│ │ │ ├── tikv-server-key.pem
│ │ │ └── tikv-server.pem
│ │ ├── tikv-tls.toml
│ │ └── tikv.toml
│ ├── webdav
│ │ ├── config
│ │ │ └── nginx
│ │ │ └── http.conf
│ │ ├── docker-compose-webdav-jfrog.yml
│ │ ├── docker-compose-webdav-nextcloud.yml
│ │ ├── docker-compose-webdav-owncloud.yml
│ │ ├── docker-compose-webdav-with-auth.yml
│ │ ├── docker-compose-webdav-with-empty-passwd.yml
│ │ ├── docker-compose-webdav.yml
│ │ └── health-check-nextcloud.sh
│ └── webhdfs
│ └── docker-compose-webhdfs.yml
├── justfile
├── LICENSE
├── licenserc.toml
├── NOTICE
├── README.md
├── rust-toolchain.toml
├── rustfmt.toml
└── scripts
├── constants.py
├── dependencies.py
├── merge_local_staging.py
├── README.md
├── verify.py
└── workspace.py
```
# Files
--------------------------------------------------------------------------------
/bindings/java/src/main/java/org/apache/opendal/ServiceConfig.java:
--------------------------------------------------------------------------------
```java
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 |
20 | // DO NOT EDIT IT MANUALLY. This file is generated by opendal/dev/generate/java.rs.
21 |
22 | package org.apache.opendal;
23 |
24 | import java.time.Duration;
25 | import java.util.HashMap;
26 | import java.util.Map;
27 | import lombok.AccessLevel;
28 | import lombok.Builder;
29 | import lombok.Data;
30 | import lombok.NonNull;
31 | import lombok.RequiredArgsConstructor;
32 |
33 | /**
34 | * Service configurations that are mapped from
35 | * <a href="https://docs.rs/opendal/latest/opendal/services/index.html">OpenDAL's services</a>.
36 | */
37 | @SuppressWarnings("unused") // intended to be used by users
38 | public interface ServiceConfig {
39 | /**
40 | * The scheme of the service.
41 | *
42 | * @return the scheme
43 | */
44 | String scheme();
45 |
46 | /**
47 | * Convert the structured config to a type erased config map.
48 | *
49 | * @return the config map
50 | */
51 | Map<String, String> configMap();
52 |
53 | /**
54 | * Configuration for service aliyun_drive.
55 | */
56 | @Builder
57 | @Data
58 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
59 | class AliyunDrive implements ServiceConfig {
60 | /**
61 | * <p>The access_token of this backend.</p>
62 | * <p>Solution for client-only purpose. #4733</p>
63 | * <p>Required if no client_id, client_secret and refresh_token are provided.</p>
64 | */
65 | public final String accessToken;
66 | /**
67 | * <p>The client_id of this backend.</p>
68 | * <p>Required if no access_token is provided.</p>
69 | */
70 | public final String clientId;
71 | /**
72 | * <p>The client_secret of this backend.</p>
73 | * <p>Required if no access_token is provided.</p>
74 | */
75 | public final String clientSecret;
76 | /**
77 | * <p>The drive_type of this backend.</p>
78 | * <p>All operations will happen under this type of drive.</p>
79 | * <p>Available values are <code>default</code>, <code>backup</code> and <code>resource</code>.</p>
80 | * <p>Fallback to default if not set or no other drives can be found.</p>
81 | */
82 | public final @NonNull String driveType;
83 | /**
84 | * <p>The refresh_token of this backend.</p>
85 | * <p>Required if no access_token is provided.</p>
86 | */
87 | public final String refreshToken;
88 | /**
89 | * <p>The Root of this backend.</p>
90 | * <p>All operations will happen under this root.</p>
91 | * <p>Default to <code>/</code> if not set.</p>
92 | */
93 | public final String root;
94 |
95 | @Override
96 | public String scheme() {
97 | return "aliyun_drive";
98 | }
99 |
100 | @Override
101 | public Map<String, String> configMap() {
102 | final HashMap<String, String> map = new HashMap<>();
103 | if (accessToken != null) {
104 | map.put("access_token", accessToken);
105 | }
106 | if (clientId != null) {
107 | map.put("client_id", clientId);
108 | }
109 | if (clientSecret != null) {
110 | map.put("client_secret", clientSecret);
111 | }
112 | map.put("drive_type", driveType);
113 | if (refreshToken != null) {
114 | map.put("refresh_token", refreshToken);
115 | }
116 | if (root != null) {
117 | map.put("root", root);
118 | }
119 | return map;
120 | }
121 | }
122 |
123 | /**
124 | * Configuration for service alluxio.
125 | */
126 | @Builder
127 | @Data
128 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
129 | class Alluxio implements ServiceConfig {
130 | /**
131 | * <p>endpoint of this backend.</p>
132 | * <p>Endpoint must be full uri, mostly like <code>http://127.0.0.1:39999</code>.</p>
133 | */
134 | public final String endpoint;
135 | /**
136 | * <p>root of this backend.</p>
137 | * <p>All operations will happen under this root.</p>
138 | * <p>default to <code>/</code> if not set.</p>
139 | */
140 | public final String root;
141 |
142 | @Override
143 | public String scheme() {
144 | return "alluxio";
145 | }
146 |
147 | @Override
148 | public Map<String, String> configMap() {
149 | final HashMap<String, String> map = new HashMap<>();
150 | if (endpoint != null) {
151 | map.put("endpoint", endpoint);
152 | }
153 | if (root != null) {
154 | map.put("root", root);
155 | }
156 | return map;
157 | }
158 | }
159 |
160 | /**
161 | * Configuration for service azblob.
162 | */
163 | @Builder
164 | @Data
165 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
166 | class Azblob implements ServiceConfig {
167 | /**
168 | * <p>The account key of Azblob service backend.</p>
169 | */
170 | public final String accountKey;
171 | /**
172 | * <p>The account name of Azblob service backend.</p>
173 | */
174 | public final String accountName;
175 | /**
176 | * <p>The maximum batch operations of Azblob service backend.</p>
177 | */
178 | public final Long batchMaxOperations;
179 | /**
180 | * <p>The container name of Azblob service backend.</p>
181 | */
182 | public final @NonNull String container;
183 | /**
184 | * <p>The encryption algorithm of Azblob service backend.</p>
185 | */
186 | public final String encryptionAlgorithm;
187 | /**
188 | * <p>The encryption key of Azblob service backend.</p>
189 | */
190 | public final String encryptionKey;
191 | /**
192 | * <p>The encryption key sha256 of Azblob service backend.</p>
193 | */
194 | public final String encryptionKeySha256;
195 | /**
196 | * <p>The endpoint of Azblob service backend.</p>
197 | * <p>Endpoint must be full uri, e.g.</p>
198 | * <ul>
199 | * <li>Azblob: <code>https://accountname.blob.core.windows.net</code></li>
200 | * <li>Azurite: <code>http://127.0.0.1:10000/devstoreaccount1</code></li>
201 | * </ul>
202 | */
203 | public final String endpoint;
204 | /**
205 | * <p>The root of Azblob service backend.</p>
206 | * <p>All operations will happen under this root.</p>
207 | */
208 | public final String root;
209 | /**
210 | * <p>The sas token of Azblob service backend.</p>
211 | */
212 | public final String sasToken;
213 |
214 | @Override
215 | public String scheme() {
216 | return "azblob";
217 | }
218 |
219 | @Override
220 | public Map<String, String> configMap() {
221 | final HashMap<String, String> map = new HashMap<>();
222 | if (accountKey != null) {
223 | map.put("account_key", accountKey);
224 | }
225 | if (accountName != null) {
226 | map.put("account_name", accountName);
227 | }
228 | if (batchMaxOperations != null) {
229 | map.put("batch_max_operations", String.valueOf(batchMaxOperations));
230 | }
231 | map.put("container", container);
232 | if (encryptionAlgorithm != null) {
233 | map.put("encryption_algorithm", encryptionAlgorithm);
234 | }
235 | if (encryptionKey != null) {
236 | map.put("encryption_key", encryptionKey);
237 | }
238 | if (encryptionKeySha256 != null) {
239 | map.put("encryption_key_sha256", encryptionKeySha256);
240 | }
241 | if (endpoint != null) {
242 | map.put("endpoint", endpoint);
243 | }
244 | if (root != null) {
245 | map.put("root", root);
246 | }
247 | if (sasToken != null) {
248 | map.put("sas_token", sasToken);
249 | }
250 | return map;
251 | }
252 | }
253 |
254 | /**
255 | * Configuration for service azdls.
256 | */
257 | @Builder
258 | @Data
259 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
260 | class Azdls implements ServiceConfig {
261 | /**
262 | * <p>Account key of this backend.</p>
263 | * <ul>
264 | * <li>required for shared_key authentication</li>
265 | * </ul>
266 | */
267 | public final String accountKey;
268 | /**
269 | * <p>Account name of this backend.</p>
270 | */
271 | public final String accountName;
272 | /**
273 | * <p>authority_host
274 | * The authority host of the service principal.</p>
275 | * <ul>
276 | * <li>required for client_credentials authentication</li>
277 | * <li>default value: <code>https://login.microsoftonline.com</code></li>
278 | * </ul>
279 | */
280 | public final String authorityHost;
281 | /**
282 | * <p>client_id
283 | * The client id of the service principal.</p>
284 | * <ul>
285 | * <li>required for client_credentials authentication</li>
286 | * </ul>
287 | */
288 | public final String clientId;
289 | /**
290 | * <p>client_secret
291 | * The client secret of the service principal.</p>
292 | * <ul>
293 | * <li>required for client_credentials authentication</li>
294 | * </ul>
295 | */
296 | public final String clientSecret;
297 | /**
298 | * <p>Endpoint of this backend.</p>
299 | */
300 | public final String endpoint;
301 | /**
302 | * <p>Filesystem name of this backend.</p>
303 | */
304 | public final @NonNull String filesystem;
305 | /**
306 | * <p>Root of this backend.</p>
307 | */
308 | public final String root;
309 | /**
310 | * <p>sas_token
311 | * The shared access signature token.</p>
312 | * <ul>
313 | * <li>required for sas authentication</li>
314 | * </ul>
315 | */
316 | public final String sasToken;
317 | /**
318 | * <p>tenant_id
319 | * The tenant id of the service principal.</p>
320 | * <ul>
321 | * <li>required for client_credentials authentication</li>
322 | * </ul>
323 | */
324 | public final String tenantId;
325 |
326 | @Override
327 | public String scheme() {
328 | return "azdls";
329 | }
330 |
331 | @Override
332 | public Map<String, String> configMap() {
333 | final HashMap<String, String> map = new HashMap<>();
334 | if (accountKey != null) {
335 | map.put("account_key", accountKey);
336 | }
337 | if (accountName != null) {
338 | map.put("account_name", accountName);
339 | }
340 | if (authorityHost != null) {
341 | map.put("authority_host", authorityHost);
342 | }
343 | if (clientId != null) {
344 | map.put("client_id", clientId);
345 | }
346 | if (clientSecret != null) {
347 | map.put("client_secret", clientSecret);
348 | }
349 | if (endpoint != null) {
350 | map.put("endpoint", endpoint);
351 | }
352 | map.put("filesystem", filesystem);
353 | if (root != null) {
354 | map.put("root", root);
355 | }
356 | if (sasToken != null) {
357 | map.put("sas_token", sasToken);
358 | }
359 | if (tenantId != null) {
360 | map.put("tenant_id", tenantId);
361 | }
362 | return map;
363 | }
364 | }
365 |
366 | /**
367 | * Configuration for service azfile.
368 | */
369 | @Builder
370 | @Data
371 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
372 | class Azfile implements ServiceConfig {
373 | /**
374 | * <p>The account key for azfile.</p>
375 | */
376 | public final String accountKey;
377 | /**
378 | * <p>The account name for azfile.</p>
379 | */
380 | public final String accountName;
381 | /**
382 | * <p>The endpoint for azfile.</p>
383 | */
384 | public final String endpoint;
385 | /**
386 | * <p>The root path for azfile.</p>
387 | */
388 | public final String root;
389 | /**
390 | * <p>The sas token for azfile.</p>
391 | */
392 | public final String sasToken;
393 | /**
394 | * <p>The share name for azfile.</p>
395 | */
396 | public final @NonNull String shareName;
397 |
398 | @Override
399 | public String scheme() {
400 | return "azfile";
401 | }
402 |
403 | @Override
404 | public Map<String, String> configMap() {
405 | final HashMap<String, String> map = new HashMap<>();
406 | if (accountKey != null) {
407 | map.put("account_key", accountKey);
408 | }
409 | if (accountName != null) {
410 | map.put("account_name", accountName);
411 | }
412 | if (endpoint != null) {
413 | map.put("endpoint", endpoint);
414 | }
415 | if (root != null) {
416 | map.put("root", root);
417 | }
418 | if (sasToken != null) {
419 | map.put("sas_token", sasToken);
420 | }
421 | map.put("share_name", shareName);
422 | return map;
423 | }
424 | }
425 |
426 | /**
427 | * Configuration for service b2.
428 | */
429 | @Builder
430 | @Data
431 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
432 | class B2 implements ServiceConfig {
433 | /**
434 | * <p>applicationKey of this backend.</p>
435 | * <ul>
436 | * <li>If application_key is set, we will take user's input first.</li>
437 | * <li>If not, we will try to load it from environment.</li>
438 | * </ul>
439 | */
440 | public final String applicationKey;
441 | /**
442 | * <p>keyID of this backend.</p>
443 | * <ul>
444 | * <li>If application_key_id is set, we will take user's input first.</li>
445 | * <li>If not, we will try to load it from environment.</li>
446 | * </ul>
447 | */
448 | public final String applicationKeyId;
449 | /**
450 | * <p>bucket of this backend.</p>
451 | * <p>required.</p>
452 | */
453 | public final @NonNull String bucket;
454 | /**
455 | * <p>bucket id of this backend.</p>
456 | * <p>required.</p>
457 | */
458 | public final @NonNull String bucketId;
459 | /**
460 | * <p>root of this backend.</p>
461 | * <p>All operations will happen under this root.</p>
462 | */
463 | public final String root;
464 |
465 | @Override
466 | public String scheme() {
467 | return "b2";
468 | }
469 |
470 | @Override
471 | public Map<String, String> configMap() {
472 | final HashMap<String, String> map = new HashMap<>();
473 | if (applicationKey != null) {
474 | map.put("application_key", applicationKey);
475 | }
476 | if (applicationKeyId != null) {
477 | map.put("application_key_id", applicationKeyId);
478 | }
479 | map.put("bucket", bucket);
480 | map.put("bucket_id", bucketId);
481 | if (root != null) {
482 | map.put("root", root);
483 | }
484 | return map;
485 | }
486 | }
487 |
488 | /**
489 | * Configuration for service cacache.
490 | */
491 | @Builder
492 | @Data
493 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
494 | class Cacache implements ServiceConfig {
495 | /**
496 | * <p>That path to the cacache data directory.</p>
497 | */
498 | public final String datadir;
499 |
500 | @Override
501 | public String scheme() {
502 | return "cacache";
503 | }
504 |
505 | @Override
506 | public Map<String, String> configMap() {
507 | final HashMap<String, String> map = new HashMap<>();
508 | if (datadir != null) {
509 | map.put("datadir", datadir);
510 | }
511 | return map;
512 | }
513 | }
514 |
515 | /**
516 | * Configuration for service cloudflare_kv.
517 | */
518 | @Builder
519 | @Data
520 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
521 | class CloudflareKv implements ServiceConfig {
522 | /**
523 | * <p>The account ID used to authenticate with CloudFlare. Used as URI path parameter.</p>
524 | */
525 | public final String accountId;
526 | /**
527 | * <p>The token used to authenticate with CloudFlare.</p>
528 | */
529 | public final String apiToken;
530 | /**
531 | * <p>The default ttl for write operations.</p>
532 | */
533 | public final Duration defaultTtl;
534 | /**
535 | * <p>The namespace ID. Used as URI path parameter.</p>
536 | */
537 | public final String namespaceId;
538 | /**
539 | * <p>Root within this backend.</p>
540 | */
541 | public final String root;
542 |
543 | @Override
544 | public String scheme() {
545 | return "cloudflare_kv";
546 | }
547 |
548 | @Override
549 | public Map<String, String> configMap() {
550 | final HashMap<String, String> map = new HashMap<>();
551 | if (accountId != null) {
552 | map.put("account_id", accountId);
553 | }
554 | if (apiToken != null) {
555 | map.put("api_token", apiToken);
556 | }
557 | if (defaultTtl != null) {
558 | map.put("default_ttl", defaultTtl.toString());
559 | }
560 | if (namespaceId != null) {
561 | map.put("namespace_id", namespaceId);
562 | }
563 | if (root != null) {
564 | map.put("root", root);
565 | }
566 | return map;
567 | }
568 | }
569 |
570 | /**
571 | * Configuration for service compfs.
572 | */
573 | @Builder
574 | @Data
575 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
576 | class Compfs implements ServiceConfig {
577 | /**
578 | * <p>root of this backend.</p>
579 | * <p>All operations will happen under this root.</p>
580 | */
581 | public final String root;
582 |
583 | @Override
584 | public String scheme() {
585 | return "compfs";
586 | }
587 |
588 | @Override
589 | public Map<String, String> configMap() {
590 | final HashMap<String, String> map = new HashMap<>();
591 | if (root != null) {
592 | map.put("root", root);
593 | }
594 | return map;
595 | }
596 | }
597 |
598 | /**
599 | * Configuration for service cos.
600 | */
601 | @Builder
602 | @Data
603 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
604 | class Cos implements ServiceConfig {
605 | /**
606 | * <p>Bucket of this backend.</p>
607 | */
608 | public final String bucket;
609 | /**
610 | * <p>Disable config load so that opendal will not load config from</p>
611 | */
612 | public final Boolean disableConfigLoad;
613 | /**
614 | * <p>is bucket versioning enabled for this bucket</p>
615 | */
616 | public final Boolean enableVersioning;
617 | /**
618 | * <p>Endpoint of this backend.</p>
619 | */
620 | public final String endpoint;
621 | /**
622 | * <p>Root of this backend.</p>
623 | */
624 | public final String root;
625 | /**
626 | * <p>Secret ID of this backend.</p>
627 | */
628 | public final String secretId;
629 | /**
630 | * <p>Secret key of this backend.</p>
631 | */
632 | public final String secretKey;
633 |
634 | @Override
635 | public String scheme() {
636 | return "cos";
637 | }
638 |
639 | @Override
640 | public Map<String, String> configMap() {
641 | final HashMap<String, String> map = new HashMap<>();
642 | if (bucket != null) {
643 | map.put("bucket", bucket);
644 | }
645 | if (disableConfigLoad != null) {
646 | map.put("disable_config_load", String.valueOf(disableConfigLoad));
647 | }
648 | if (enableVersioning != null) {
649 | map.put("enable_versioning", String.valueOf(enableVersioning));
650 | }
651 | if (endpoint != null) {
652 | map.put("endpoint", endpoint);
653 | }
654 | if (root != null) {
655 | map.put("root", root);
656 | }
657 | if (secretId != null) {
658 | map.put("secret_id", secretId);
659 | }
660 | if (secretKey != null) {
661 | map.put("secret_key", secretKey);
662 | }
663 | return map;
664 | }
665 | }
666 |
667 | /**
668 | * Configuration for service d1.
669 | */
670 | @Builder
671 | @Data
672 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
673 | class D1 implements ServiceConfig {
674 | /**
675 | * <p>Set the account id of cloudflare api.</p>
676 | */
677 | public final String accountId;
678 | /**
679 | * <p>Set the database id of cloudflare api.</p>
680 | */
681 | public final String databaseId;
682 | /**
683 | * <p>Set the key field of D1 Database.</p>
684 | */
685 | public final String keyField;
686 | /**
687 | * <p>Set the working directory of OpenDAL.</p>
688 | */
689 | public final String root;
690 | /**
691 | * <p>Set the table of D1 Database.</p>
692 | */
693 | public final String table;
694 | /**
695 | * <p>Set the token of cloudflare api.</p>
696 | */
697 | public final String token;
698 | /**
699 | * <p>Set the value field of D1 Database.</p>
700 | */
701 | public final String valueField;
702 |
703 | @Override
704 | public String scheme() {
705 | return "d1";
706 | }
707 |
708 | @Override
709 | public Map<String, String> configMap() {
710 | final HashMap<String, String> map = new HashMap<>();
711 | if (accountId != null) {
712 | map.put("account_id", accountId);
713 | }
714 | if (databaseId != null) {
715 | map.put("database_id", databaseId);
716 | }
717 | if (keyField != null) {
718 | map.put("key_field", keyField);
719 | }
720 | if (root != null) {
721 | map.put("root", root);
722 | }
723 | if (table != null) {
724 | map.put("table", table);
725 | }
726 | if (token != null) {
727 | map.put("token", token);
728 | }
729 | if (valueField != null) {
730 | map.put("value_field", valueField);
731 | }
732 | return map;
733 | }
734 | }
735 |
736 | /**
737 | * Configuration for service dashmap.
738 | */
739 | @Builder
740 | @Data
741 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
742 | class Dashmap implements ServiceConfig {
743 | /**
744 | * <p>root path of this backend</p>
745 | */
746 | public final String root;
747 |
748 | @Override
749 | public String scheme() {
750 | return "dashmap";
751 | }
752 |
753 | @Override
754 | public Map<String, String> configMap() {
755 | final HashMap<String, String> map = new HashMap<>();
756 | if (root != null) {
757 | map.put("root", root);
758 | }
759 | return map;
760 | }
761 | }
762 |
763 | /**
764 | * Configuration for service dbfs.
765 | */
766 | @Builder
767 | @Data
768 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
769 | class Dbfs implements ServiceConfig {
770 | /**
771 | * <p>The endpoint for dbfs.</p>
772 | */
773 | public final String endpoint;
774 | /**
775 | * <p>The root for dbfs.</p>
776 | */
777 | public final String root;
778 | /**
779 | * <p>The token for dbfs.</p>
780 | */
781 | public final String token;
782 |
783 | @Override
784 | public String scheme() {
785 | return "dbfs";
786 | }
787 |
788 | @Override
789 | public Map<String, String> configMap() {
790 | final HashMap<String, String> map = new HashMap<>();
791 | if (endpoint != null) {
792 | map.put("endpoint", endpoint);
793 | }
794 | if (root != null) {
795 | map.put("root", root);
796 | }
797 | if (token != null) {
798 | map.put("token", token);
799 | }
800 | return map;
801 | }
802 | }
803 |
804 | /**
805 | * Configuration for service dropbox.
806 | */
807 | @Builder
808 | @Data
809 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
810 | class Dropbox implements ServiceConfig {
811 | /**
812 | * <p>access token for dropbox.</p>
813 | */
814 | public final String accessToken;
815 | /**
816 | * <p>client_id for dropbox.</p>
817 | */
818 | public final String clientId;
819 | /**
820 | * <p>client_secret for dropbox.</p>
821 | */
822 | public final String clientSecret;
823 | /**
824 | * <p>refresh_token for dropbox.</p>
825 | */
826 | public final String refreshToken;
827 | /**
828 | * <p>root path for dropbox.</p>
829 | */
830 | public final String root;
831 |
832 | @Override
833 | public String scheme() {
834 | return "dropbox";
835 | }
836 |
837 | @Override
838 | public Map<String, String> configMap() {
839 | final HashMap<String, String> map = new HashMap<>();
840 | if (accessToken != null) {
841 | map.put("access_token", accessToken);
842 | }
843 | if (clientId != null) {
844 | map.put("client_id", clientId);
845 | }
846 | if (clientSecret != null) {
847 | map.put("client_secret", clientSecret);
848 | }
849 | if (refreshToken != null) {
850 | map.put("refresh_token", refreshToken);
851 | }
852 | if (root != null) {
853 | map.put("root", root);
854 | }
855 | return map;
856 | }
857 | }
858 |
859 | /**
860 | * Configuration for service etcd.
861 | */
862 | @Builder
863 | @Data
864 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
865 | class Etcd implements ServiceConfig {
866 | /**
867 | * <p>certificate authority file path</p>
868 | * <p>default is None</p>
869 | */
870 | public final String caPath;
871 | /**
872 | * <p>cert path</p>
873 | * <p>default is None</p>
874 | */
875 | public final String certPath;
876 | /**
877 | * <p>network address of the Etcd services.
878 | * If use https, must set TLS options: <code>ca_path</code>, <code>cert_path</code>, <code>key_path</code>.
879 | * e.g. "127.0.0.1:23790,127.0.0.1:23791,127.0.0.1:23792" or "http://127.0.0.1:23790,http://127.0.0.1:23791,http://127.0.0.1:23792" or "https://127.0.0.1:23790,https://127.0.0.1:23791,https://127.0.0.1:23792"</p>
880 | * <p>default is "http://127.0.0.1:2379"</p>
881 | */
882 | public final String endpoints;
883 | /**
884 | * <p>key path</p>
885 | * <p>default is None</p>
886 | */
887 | public final String keyPath;
888 | /**
889 | * <p>the password for authentication</p>
890 | * <p>default is None</p>
891 | */
892 | public final String password;
893 | /**
894 | * <p>the working directory of the etcd service. Can be "/path/to/dir"</p>
895 | * <p>default is "/"</p>
896 | */
897 | public final String root;
898 | /**
899 | * <p>the username to connect etcd service.</p>
900 | * <p>default is None</p>
901 | */
902 | public final String username;
903 |
904 | @Override
905 | public String scheme() {
906 | return "etcd";
907 | }
908 |
909 | @Override
910 | public Map<String, String> configMap() {
911 | final HashMap<String, String> map = new HashMap<>();
912 | if (caPath != null) {
913 | map.put("ca_path", caPath);
914 | }
915 | if (certPath != null) {
916 | map.put("cert_path", certPath);
917 | }
918 | if (endpoints != null) {
919 | map.put("endpoints", endpoints);
920 | }
921 | if (keyPath != null) {
922 | map.put("key_path", keyPath);
923 | }
924 | if (password != null) {
925 | map.put("password", password);
926 | }
927 | if (root != null) {
928 | map.put("root", root);
929 | }
930 | if (username != null) {
931 | map.put("username", username);
932 | }
933 | return map;
934 | }
935 | }
936 |
937 | /**
938 | * Configuration for service fs.
939 | */
940 | @Builder
941 | @Data
942 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
943 | class Fs implements ServiceConfig {
944 | /**
945 | * <p>tmp dir for atomic write</p>
946 | */
947 | public final String atomicWriteDir;
948 | /**
949 | * <p>root dir for backend</p>
950 | */
951 | public final String root;
952 |
953 | @Override
954 | public String scheme() {
955 | return "fs";
956 | }
957 |
958 | @Override
959 | public Map<String, String> configMap() {
960 | final HashMap<String, String> map = new HashMap<>();
961 | if (atomicWriteDir != null) {
962 | map.put("atomic_write_dir", atomicWriteDir);
963 | }
964 | if (root != null) {
965 | map.put("root", root);
966 | }
967 | return map;
968 | }
969 | }
970 |
971 | /**
972 | * Configuration for service gcs.
973 | */
974 | @Builder
975 | @Data
976 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
977 | class Gcs implements ServiceConfig {
978 | /**
979 | * <p>Allow opendal to send requests without signing when credentials are not
980 | * loaded.</p>
981 | */
982 | public final Boolean allowAnonymous;
983 | /**
984 | * <p>bucket name</p>
985 | */
986 | public final @NonNull String bucket;
987 | /**
988 | * <p>Credentials string for GCS service OAuth2 authentication.</p>
989 | */
990 | public final String credential;
991 | /**
992 | * <p>Local path to credentials file for GCS service OAuth2 authentication.</p>
993 | */
994 | public final String credentialPath;
995 | /**
996 | * <p>The default storage class used by gcs.</p>
997 | */
998 | public final String defaultStorageClass;
999 | /**
1000 | * <p>Disable loading configuration from the environment.</p>
1001 | */
1002 | public final Boolean disableConfigLoad;
1003 | /**
1004 | * <p>Disable attempting to load credentials from the GCE metadata server when
1005 | * running within Google Cloud.</p>
1006 | */
1007 | public final Boolean disableVmMetadata;
1008 | /**
1009 | * <p>endpoint URI of GCS service,
1010 | * default is <code>https://storage.googleapis.com</code></p>
1011 | */
1012 | public final String endpoint;
1013 | /**
1014 | * <p>The predefined acl for GCS.</p>
1015 | */
1016 | public final String predefinedAcl;
1017 | /**
1018 | * <p>root URI, all operations happens under <code>root</code></p>
1019 | */
1020 | public final String root;
1021 | /**
1022 | * <p>Scope for gcs.</p>
1023 | */
1024 | public final String scope;
1025 | /**
1026 | * <p>Service Account for gcs.</p>
1027 | */
1028 | public final String serviceAccount;
1029 | /**
1030 | * <p>A Google Cloud OAuth2 token.</p>
1031 | * <p>Takes precedence over <code>credential</code> and <code>credential_path</code>.</p>
1032 | */
1033 | public final String token;
1034 |
1035 | @Override
1036 | public String scheme() {
1037 | return "gcs";
1038 | }
1039 |
1040 | @Override
1041 | public Map<String, String> configMap() {
1042 | final HashMap<String, String> map = new HashMap<>();
1043 | if (allowAnonymous != null) {
1044 | map.put("allow_anonymous", String.valueOf(allowAnonymous));
1045 | }
1046 | map.put("bucket", bucket);
1047 | if (credential != null) {
1048 | map.put("credential", credential);
1049 | }
1050 | if (credentialPath != null) {
1051 | map.put("credential_path", credentialPath);
1052 | }
1053 | if (defaultStorageClass != null) {
1054 | map.put("default_storage_class", defaultStorageClass);
1055 | }
1056 | if (disableConfigLoad != null) {
1057 | map.put("disable_config_load", String.valueOf(disableConfigLoad));
1058 | }
1059 | if (disableVmMetadata != null) {
1060 | map.put("disable_vm_metadata", String.valueOf(disableVmMetadata));
1061 | }
1062 | if (endpoint != null) {
1063 | map.put("endpoint", endpoint);
1064 | }
1065 | if (predefinedAcl != null) {
1066 | map.put("predefined_acl", predefinedAcl);
1067 | }
1068 | if (root != null) {
1069 | map.put("root", root);
1070 | }
1071 | if (scope != null) {
1072 | map.put("scope", scope);
1073 | }
1074 | if (serviceAccount != null) {
1075 | map.put("service_account", serviceAccount);
1076 | }
1077 | if (token != null) {
1078 | map.put("token", token);
1079 | }
1080 | return map;
1081 | }
1082 | }
1083 |
1084 | /**
1085 | * Configuration for service gdrive.
1086 | */
1087 | @Builder
1088 | @Data
1089 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1090 | class Gdrive implements ServiceConfig {
1091 | /**
1092 | * <p>Access token for gdrive.</p>
1093 | */
1094 | public final String accessToken;
1095 | /**
1096 | * <p>Client id for gdrive.</p>
1097 | */
1098 | public final String clientId;
1099 | /**
1100 | * <p>Client secret for gdrive.</p>
1101 | */
1102 | public final String clientSecret;
1103 | /**
1104 | * <p>Refresh token for gdrive.</p>
1105 | */
1106 | public final String refreshToken;
1107 | /**
1108 | * <p>The root for gdrive</p>
1109 | */
1110 | public final String root;
1111 |
1112 | @Override
1113 | public String scheme() {
1114 | return "gdrive";
1115 | }
1116 |
1117 | @Override
1118 | public Map<String, String> configMap() {
1119 | final HashMap<String, String> map = new HashMap<>();
1120 | if (accessToken != null) {
1121 | map.put("access_token", accessToken);
1122 | }
1123 | if (clientId != null) {
1124 | map.put("client_id", clientId);
1125 | }
1126 | if (clientSecret != null) {
1127 | map.put("client_secret", clientSecret);
1128 | }
1129 | if (refreshToken != null) {
1130 | map.put("refresh_token", refreshToken);
1131 | }
1132 | if (root != null) {
1133 | map.put("root", root);
1134 | }
1135 | return map;
1136 | }
1137 | }
1138 |
1139 | /**
1140 | * Configuration for service ghac.
1141 | */
1142 | @Builder
1143 | @Data
1144 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1145 | class Ghac implements ServiceConfig {
1146 | /**
1147 | * <p>The endpoint for ghac service.</p>
1148 | */
1149 | public final String endpoint;
1150 | /**
1151 | * <p>The root path for ghac.</p>
1152 | */
1153 | public final String root;
1154 | /**
1155 | * <p>The runtime token for ghac service.</p>
1156 | */
1157 | public final String runtimeToken;
1158 | /**
1159 | * <p>The version that used by cache.</p>
1160 | */
1161 | public final String version;
1162 |
1163 | @Override
1164 | public String scheme() {
1165 | return "ghac";
1166 | }
1167 |
1168 | @Override
1169 | public Map<String, String> configMap() {
1170 | final HashMap<String, String> map = new HashMap<>();
1171 | if (endpoint != null) {
1172 | map.put("endpoint", endpoint);
1173 | }
1174 | if (root != null) {
1175 | map.put("root", root);
1176 | }
1177 | if (runtimeToken != null) {
1178 | map.put("runtime_token", runtimeToken);
1179 | }
1180 | if (version != null) {
1181 | map.put("version", version);
1182 | }
1183 | return map;
1184 | }
1185 | }
1186 |
1187 | /**
1188 | * Configuration for service github.
1189 | */
1190 | @Builder
1191 | @Data
1192 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1193 | class Github implements ServiceConfig {
1194 | /**
1195 | * <p>GitHub repo owner.</p>
1196 | * <p>required.</p>
1197 | */
1198 | public final @NonNull String owner;
1199 | /**
1200 | * <p>GitHub repo name.</p>
1201 | * <p>required.</p>
1202 | */
1203 | public final @NonNull String repo;
1204 | /**
1205 | * <p>root of this backend.</p>
1206 | * <p>All operations will happen under this root.</p>
1207 | */
1208 | public final String root;
1209 | /**
1210 | * <p>GitHub access_token.</p>
1211 | * <p>optional.
1212 | * If not provided, the backend will only support read operations for public repositories.
1213 | * And rate limit will be limited to 60 requests per hour.</p>
1214 | */
1215 | public final String token;
1216 |
1217 | @Override
1218 | public String scheme() {
1219 | return "github";
1220 | }
1221 |
1222 | @Override
1223 | public Map<String, String> configMap() {
1224 | final HashMap<String, String> map = new HashMap<>();
1225 | map.put("owner", owner);
1226 | map.put("repo", repo);
1227 | if (root != null) {
1228 | map.put("root", root);
1229 | }
1230 | if (token != null) {
1231 | map.put("token", token);
1232 | }
1233 | return map;
1234 | }
1235 | }
1236 |
1237 | /**
1238 | * Configuration for service gridfs.
1239 | */
1240 | @Builder
1241 | @Data
1242 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1243 | class Gridfs implements ServiceConfig {
1244 | /**
1245 | * <p>The bucket name of the MongoDB GridFs service to read/write.</p>
1246 | */
1247 | public final String bucket;
1248 | /**
1249 | * <p>The chunk size of the MongoDB GridFs service used to break the user file into chunks.</p>
1250 | */
1251 | public final Integer chunkSize;
1252 | /**
1253 | * <p>The connection string of the MongoDB service.</p>
1254 | */
1255 | public final String connectionString;
1256 | /**
1257 | * <p>The database name of the MongoDB GridFs service to read/write.</p>
1258 | */
1259 | public final String database;
1260 | /**
1261 | * <p>The working directory, all operations will be performed under it.</p>
1262 | */
1263 | public final String root;
1264 |
1265 | @Override
1266 | public String scheme() {
1267 | return "gridfs";
1268 | }
1269 |
1270 | @Override
1271 | public Map<String, String> configMap() {
1272 | final HashMap<String, String> map = new HashMap<>();
1273 | if (bucket != null) {
1274 | map.put("bucket", bucket);
1275 | }
1276 | if (chunkSize != null) {
1277 | map.put("chunk_size", String.valueOf(chunkSize));
1278 | }
1279 | if (connectionString != null) {
1280 | map.put("connection_string", connectionString);
1281 | }
1282 | if (database != null) {
1283 | map.put("database", database);
1284 | }
1285 | if (root != null) {
1286 | map.put("root", root);
1287 | }
1288 | return map;
1289 | }
1290 | }
1291 |
1292 | /**
1293 | * Configuration for service hdfs_native.
1294 | */
1295 | @Builder
1296 | @Data
1297 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1298 | class HdfsNative implements ServiceConfig {
1299 | /**
1300 | * <p>enable the append capacity</p>
1301 | */
1302 | public final Boolean enableAppend;
1303 | /**
1304 | * <p>name_node of this backend</p>
1305 | */
1306 | public final String nameNode;
1307 | /**
1308 | * <p>work dir of this backend</p>
1309 | */
1310 | public final String root;
1311 |
1312 | @Override
1313 | public String scheme() {
1314 | return "hdfs_native";
1315 | }
1316 |
1317 | @Override
1318 | public Map<String, String> configMap() {
1319 | final HashMap<String, String> map = new HashMap<>();
1320 | if (enableAppend != null) {
1321 | map.put("enable_append", String.valueOf(enableAppend));
1322 | }
1323 | if (nameNode != null) {
1324 | map.put("name_node", nameNode);
1325 | }
1326 | if (root != null) {
1327 | map.put("root", root);
1328 | }
1329 | return map;
1330 | }
1331 | }
1332 |
1333 | /**
1334 | * Configuration for service http.
1335 | */
1336 | @Builder
1337 | @Data
1338 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1339 | class Http implements ServiceConfig {
1340 | /**
1341 | * <p>endpoint of this backend</p>
1342 | */
1343 | public final String endpoint;
1344 | /**
1345 | * <p>password of this backend</p>
1346 | */
1347 | public final String password;
1348 | /**
1349 | * <p>root of this backend</p>
1350 | */
1351 | public final String root;
1352 | /**
1353 | * <p>token of this backend</p>
1354 | */
1355 | public final String token;
1356 | /**
1357 | * <p>username of this backend</p>
1358 | */
1359 | public final String username;
1360 |
1361 | @Override
1362 | public String scheme() {
1363 | return "http";
1364 | }
1365 |
1366 | @Override
1367 | public Map<String, String> configMap() {
1368 | final HashMap<String, String> map = new HashMap<>();
1369 | if (endpoint != null) {
1370 | map.put("endpoint", endpoint);
1371 | }
1372 | if (password != null) {
1373 | map.put("password", password);
1374 | }
1375 | if (root != null) {
1376 | map.put("root", root);
1377 | }
1378 | if (token != null) {
1379 | map.put("token", token);
1380 | }
1381 | if (username != null) {
1382 | map.put("username", username);
1383 | }
1384 | return map;
1385 | }
1386 | }
1387 |
1388 | /**
1389 | * Configuration for service huggingface.
1390 | */
1391 | @Builder
1392 | @Data
1393 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1394 | class Huggingface implements ServiceConfig {
1395 | /**
1396 | * <p>Repo id of this backend.</p>
1397 | * <p>This is required.</p>
1398 | */
1399 | public final String repoId;
1400 | /**
1401 | * <p>Repo type of this backend. Default is model.</p>
1402 | * <p>Available values:</p>
1403 | * <ul>
1404 | * <li>model</li>
1405 | * <li>dataset</li>
1406 | * </ul>
1407 | */
1408 | public final String repoType;
1409 | /**
1410 | * <p>Revision of this backend.</p>
1411 | * <p>Default is main.</p>
1412 | */
1413 | public final String revision;
1414 | /**
1415 | * <p>Root of this backend. Can be "/path/to/dir".</p>
1416 | * <p>Default is "/".</p>
1417 | */
1418 | public final String root;
1419 | /**
1420 | * <p>Token of this backend.</p>
1421 | * <p>This is optional.</p>
1422 | */
1423 | public final String token;
1424 |
1425 | @Override
1426 | public String scheme() {
1427 | return "huggingface";
1428 | }
1429 |
1430 | @Override
1431 | public Map<String, String> configMap() {
1432 | final HashMap<String, String> map = new HashMap<>();
1433 | if (repoId != null) {
1434 | map.put("repo_id", repoId);
1435 | }
1436 | if (repoType != null) {
1437 | map.put("repo_type", repoType);
1438 | }
1439 | if (revision != null) {
1440 | map.put("revision", revision);
1441 | }
1442 | if (root != null) {
1443 | map.put("root", root);
1444 | }
1445 | if (token != null) {
1446 | map.put("token", token);
1447 | }
1448 | return map;
1449 | }
1450 | }
1451 |
1452 | /**
1453 | * Configuration for service ipfs.
1454 | */
1455 | @Builder
1456 | @Data
1457 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1458 | class Ipfs implements ServiceConfig {
1459 | /**
1460 | * <p>IPFS gateway endpoint.</p>
1461 | */
1462 | public final String endpoint;
1463 | /**
1464 | * <p>IPFS root.</p>
1465 | */
1466 | public final String root;
1467 |
1468 | @Override
1469 | public String scheme() {
1470 | return "ipfs";
1471 | }
1472 |
1473 | @Override
1474 | public Map<String, String> configMap() {
1475 | final HashMap<String, String> map = new HashMap<>();
1476 | if (endpoint != null) {
1477 | map.put("endpoint", endpoint);
1478 | }
1479 | if (root != null) {
1480 | map.put("root", root);
1481 | }
1482 | return map;
1483 | }
1484 | }
1485 |
1486 | /**
1487 | * Configuration for service ipmfs.
1488 | */
1489 | @Builder
1490 | @Data
1491 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1492 | class Ipmfs implements ServiceConfig {
1493 | /**
1494 | * <p>Endpoint for ipfs.</p>
1495 | */
1496 | public final String endpoint;
1497 | /**
1498 | * <p>Root for ipfs.</p>
1499 | */
1500 | public final String root;
1501 |
1502 | @Override
1503 | public String scheme() {
1504 | return "ipmfs";
1505 | }
1506 |
1507 | @Override
1508 | public Map<String, String> configMap() {
1509 | final HashMap<String, String> map = new HashMap<>();
1510 | if (endpoint != null) {
1511 | map.put("endpoint", endpoint);
1512 | }
1513 | if (root != null) {
1514 | map.put("root", root);
1515 | }
1516 | return map;
1517 | }
1518 | }
1519 |
1520 | /**
1521 | * Configuration for service koofr.
1522 | */
1523 | @Builder
1524 | @Data
1525 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1526 | class Koofr implements ServiceConfig {
1527 | /**
1528 | * <p>Koofr email.</p>
1529 | */
1530 | public final @NonNull String email;
1531 | /**
1532 | * <p>Koofr endpoint.</p>
1533 | */
1534 | public final @NonNull String endpoint;
1535 | /**
1536 | * <p>password of this backend. (Must be the application password)</p>
1537 | */
1538 | public final String password;
1539 | /**
1540 | * <p>root of this backend.</p>
1541 | * <p>All operations will happen under this root.</p>
1542 | */
1543 | public final String root;
1544 |
1545 | @Override
1546 | public String scheme() {
1547 | return "koofr";
1548 | }
1549 |
1550 | @Override
1551 | public Map<String, String> configMap() {
1552 | final HashMap<String, String> map = new HashMap<>();
1553 | map.put("email", email);
1554 | map.put("endpoint", endpoint);
1555 | if (password != null) {
1556 | map.put("password", password);
1557 | }
1558 | if (root != null) {
1559 | map.put("root", root);
1560 | }
1561 | return map;
1562 | }
1563 | }
1564 |
1565 | /**
1566 | * Configuration for service lakefs.
1567 | */
1568 | @Builder
1569 | @Data
1570 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1571 | class Lakefs implements ServiceConfig {
1572 | /**
1573 | * <p>Name of the branch or a commit ID. Default is main.</p>
1574 | * <p>This is optional.</p>
1575 | */
1576 | public final String branch;
1577 | /**
1578 | * <p>Base url.</p>
1579 | * <p>This is required.</p>
1580 | */
1581 | public final String endpoint;
1582 | /**
1583 | * <p>Password for Lakefs basic authentication.</p>
1584 | * <p>This is required.</p>
1585 | */
1586 | public final String password;
1587 | /**
1588 | * <p>The repository name</p>
1589 | * <p>This is required.</p>
1590 | */
1591 | public final String repository;
1592 | /**
1593 | * <p>Root of this backend. Can be "/path/to/dir".</p>
1594 | * <p>Default is "/".</p>
1595 | */
1596 | public final String root;
1597 | /**
1598 | * <p>Username for Lakefs basic authentication.</p>
1599 | * <p>This is required.</p>
1600 | */
1601 | public final String username;
1602 |
1603 | @Override
1604 | public String scheme() {
1605 | return "lakefs";
1606 | }
1607 |
1608 | @Override
1609 | public Map<String, String> configMap() {
1610 | final HashMap<String, String> map = new HashMap<>();
1611 | if (branch != null) {
1612 | map.put("branch", branch);
1613 | }
1614 | if (endpoint != null) {
1615 | map.put("endpoint", endpoint);
1616 | }
1617 | if (password != null) {
1618 | map.put("password", password);
1619 | }
1620 | if (repository != null) {
1621 | map.put("repository", repository);
1622 | }
1623 | if (root != null) {
1624 | map.put("root", root);
1625 | }
1626 | if (username != null) {
1627 | map.put("username", username);
1628 | }
1629 | return map;
1630 | }
1631 | }
1632 |
1633 | /**
1634 | * Configuration for service memcached.
1635 | */
1636 | @Builder
1637 | @Data
1638 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1639 | class Memcached implements ServiceConfig {
1640 | /**
1641 | * <p>The maximum number of connections allowed.</p>
1642 | * <p>default is 10</p>
1643 | */
1644 | public final Integer connectionPoolMaxSize;
1645 | /**
1646 | * <p>The default ttl for put operations.</p>
1647 | */
1648 | public final Duration defaultTtl;
1649 | /**
1650 | * <p>network address of the memcached service.</p>
1651 | * <p>For example: "tcp://localhost:11211"</p>
1652 | */
1653 | public final String endpoint;
1654 | /**
1655 | * <p>Memcached password, optional.</p>
1656 | */
1657 | public final String password;
1658 | /**
1659 | * <p>the working directory of the service. Can be "/path/to/dir"</p>
1660 | * <p>default is "/"</p>
1661 | */
1662 | public final String root;
1663 | /**
1664 | * <p>Memcached username, optional.</p>
1665 | */
1666 | public final String username;
1667 |
1668 | @Override
1669 | public String scheme() {
1670 | return "memcached";
1671 | }
1672 |
1673 | @Override
1674 | public Map<String, String> configMap() {
1675 | final HashMap<String, String> map = new HashMap<>();
1676 | if (connectionPoolMaxSize != null) {
1677 | map.put("connection_pool_max_size", String.valueOf(connectionPoolMaxSize));
1678 | }
1679 | if (defaultTtl != null) {
1680 | map.put("default_ttl", defaultTtl.toString());
1681 | }
1682 | if (endpoint != null) {
1683 | map.put("endpoint", endpoint);
1684 | }
1685 | if (password != null) {
1686 | map.put("password", password);
1687 | }
1688 | if (root != null) {
1689 | map.put("root", root);
1690 | }
1691 | if (username != null) {
1692 | map.put("username", username);
1693 | }
1694 | return map;
1695 | }
1696 | }
1697 |
1698 | /**
1699 | * Configuration for service memory.
1700 | */
1701 | @Builder
1702 | @Data
1703 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1704 | class Memory implements ServiceConfig {
1705 | /**
1706 | * <p>root of the backend.</p>
1707 | */
1708 | public final String root;
1709 |
1710 | @Override
1711 | public String scheme() {
1712 | return "memory";
1713 | }
1714 |
1715 | @Override
1716 | public Map<String, String> configMap() {
1717 | final HashMap<String, String> map = new HashMap<>();
1718 | if (root != null) {
1719 | map.put("root", root);
1720 | }
1721 | return map;
1722 | }
1723 | }
1724 |
1725 | /**
1726 | * Configuration for service mini_moka.
1727 | */
1728 | @Builder
1729 | @Data
1730 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1731 | class MiniMoka implements ServiceConfig {
1732 | /**
1733 | * <p>Sets the max capacity of the cache.</p>
1734 | * <p>Refer to <a href="https://docs.rs/mini-moka/latest/mini_moka/sync/struct.CacheBuilder.html#method.max_capacity"><code>mini-moka::sync::CacheBuilder::max_capacity</code></a></p>
1735 | */
1736 | public final Long maxCapacity;
1737 | /**
1738 | * <p>root path of this backend</p>
1739 | */
1740 | public final String root;
1741 | /**
1742 | * <p>Sets the time to idle of the cache.</p>
1743 | * <p>Refer to <a href="https://docs.rs/mini-moka/latest/mini_moka/sync/struct.CacheBuilder.html#method.time_to_idle"><code>mini-moka::sync::CacheBuilder::time_to_idle</code></a></p>
1744 | */
1745 | public final String timeToIdle;
1746 | /**
1747 | * <p>Sets the time to live of the cache.</p>
1748 | * <p>Refer to <a href="https://docs.rs/mini-moka/latest/mini_moka/sync/struct.CacheBuilder.html#method.time_to_live"><code>mini-moka::sync::CacheBuilder::time_to_live</code></a></p>
1749 | */
1750 | public final String timeToLive;
1751 |
1752 | @Override
1753 | public String scheme() {
1754 | return "mini_moka";
1755 | }
1756 |
1757 | @Override
1758 | public Map<String, String> configMap() {
1759 | final HashMap<String, String> map = new HashMap<>();
1760 | if (maxCapacity != null) {
1761 | map.put("max_capacity", String.valueOf(maxCapacity));
1762 | }
1763 | if (root != null) {
1764 | map.put("root", root);
1765 | }
1766 | if (timeToIdle != null) {
1767 | map.put("time_to_idle", timeToIdle);
1768 | }
1769 | if (timeToLive != null) {
1770 | map.put("time_to_live", timeToLive);
1771 | }
1772 | return map;
1773 | }
1774 | }
1775 |
1776 | /**
1777 | * Configuration for service moka.
1778 | */
1779 | @Builder
1780 | @Data
1781 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1782 | class Moka implements ServiceConfig {
1783 | /**
1784 | * <p>Sets the max capacity of the cache.</p>
1785 | * <p>Refer to <a href="https://docs.rs/moka/latest/moka/future/struct.CacheBuilder.html#method.max_capacity"><code>moka::future::CacheBuilder::max_capacity</code></a></p>
1786 | */
1787 | public final Long maxCapacity;
1788 | /**
1789 | * <p>Name for this cache instance.</p>
1790 | */
1791 | public final String name;
1792 | /**
1793 | * <p>root path of this backend</p>
1794 | */
1795 | public final String root;
1796 | /**
1797 | * <p>Sets the time to idle of the cache.</p>
1798 | * <p>Refer to <a href="https://docs.rs/moka/latest/moka/future/struct.CacheBuilder.html#method.time_to_idle"><code>moka::future::CacheBuilder::time_to_idle</code></a></p>
1799 | */
1800 | public final String timeToIdle;
1801 | /**
1802 | * <p>Sets the time to live of the cache.</p>
1803 | * <p>Refer to <a href="https://docs.rs/moka/latest/moka/future/struct.CacheBuilder.html#method.time_to_live"><code>moka::future::CacheBuilder::time_to_live</code></a></p>
1804 | */
1805 | public final String timeToLive;
1806 |
1807 | @Override
1808 | public String scheme() {
1809 | return "moka";
1810 | }
1811 |
1812 | @Override
1813 | public Map<String, String> configMap() {
1814 | final HashMap<String, String> map = new HashMap<>();
1815 | if (maxCapacity != null) {
1816 | map.put("max_capacity", String.valueOf(maxCapacity));
1817 | }
1818 | if (name != null) {
1819 | map.put("name", name);
1820 | }
1821 | if (root != null) {
1822 | map.put("root", root);
1823 | }
1824 | if (timeToIdle != null) {
1825 | map.put("time_to_idle", timeToIdle);
1826 | }
1827 | if (timeToLive != null) {
1828 | map.put("time_to_live", timeToLive);
1829 | }
1830 | return map;
1831 | }
1832 | }
1833 |
1834 | /**
1835 | * Configuration for service mongodb.
1836 | */
1837 | @Builder
1838 | @Data
1839 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1840 | class Mongodb implements ServiceConfig {
1841 | /**
1842 | * <p>collection of this backend</p>
1843 | */
1844 | public final String collection;
1845 | /**
1846 | * <p>connection string of this backend</p>
1847 | */
1848 | public final String connectionString;
1849 | /**
1850 | * <p>database of this backend</p>
1851 | */
1852 | public final String database;
1853 | /**
1854 | * <p>key field of this backend</p>
1855 | */
1856 | public final String keyField;
1857 | /**
1858 | * <p>root of this backend</p>
1859 | */
1860 | public final String root;
1861 | /**
1862 | * <p>value field of this backend</p>
1863 | */
1864 | public final String valueField;
1865 |
1866 | @Override
1867 | public String scheme() {
1868 | return "mongodb";
1869 | }
1870 |
1871 | @Override
1872 | public Map<String, String> configMap() {
1873 | final HashMap<String, String> map = new HashMap<>();
1874 | if (collection != null) {
1875 | map.put("collection", collection);
1876 | }
1877 | if (connectionString != null) {
1878 | map.put("connection_string", connectionString);
1879 | }
1880 | if (database != null) {
1881 | map.put("database", database);
1882 | }
1883 | if (keyField != null) {
1884 | map.put("key_field", keyField);
1885 | }
1886 | if (root != null) {
1887 | map.put("root", root);
1888 | }
1889 | if (valueField != null) {
1890 | map.put("value_field", valueField);
1891 | }
1892 | return map;
1893 | }
1894 | }
1895 |
1896 | /**
1897 | * Configuration for service monoiofs.
1898 | */
1899 | @Builder
1900 | @Data
1901 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1902 | class Monoiofs implements ServiceConfig {
1903 | /**
1904 | * <p>The Root of this backend.</p>
1905 | * <p>All operations will happen under this root.</p>
1906 | * <p>Builder::build will return error if not set.</p>
1907 | */
1908 | public final String root;
1909 |
1910 | @Override
1911 | public String scheme() {
1912 | return "monoiofs";
1913 | }
1914 |
1915 | @Override
1916 | public Map<String, String> configMap() {
1917 | final HashMap<String, String> map = new HashMap<>();
1918 | if (root != null) {
1919 | map.put("root", root);
1920 | }
1921 | return map;
1922 | }
1923 | }
1924 |
1925 | /**
1926 | * Configuration for service mysql.
1927 | */
1928 | @Builder
1929 | @Data
1930 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1931 | class Mysql implements ServiceConfig {
1932 | /**
1933 | * <p>This connection string is used to connect to the mysql service. There are url based formats.</p>
1934 | * <p>The format of connect string resembles the url format of the mysql client.
1935 | * The format is: <code>[scheme://][user[:[password]]@]host[:port][/schema][?attribute1=value1&attribute2=value2...</code></p>
1936 | * <ul>
1937 | * <li><code>mysql://user@localhost</code></li>
1938 | * <li><code>mysql://user:password@localhost</code></li>
1939 | * <li><code>mysql://user:password@localhost:3306</code></li>
1940 | * <li><code>mysql://user:password@localhost:3306/db</code></li>
1941 | * </ul>
1942 | * <p>For more information, please refer to <a href="https://docs.rs/sqlx/latest/sqlx/mysql/struct.MySqlConnectOptions.html">https://docs.rs/sqlx/latest/sqlx/mysql/struct.MySqlConnectOptions.html</a>.</p>
1943 | */
1944 | public final String connectionString;
1945 | /**
1946 | * <p>The key field name for mysql.</p>
1947 | */
1948 | public final String keyField;
1949 | /**
1950 | * <p>The root for mysql.</p>
1951 | */
1952 | public final String root;
1953 | /**
1954 | * <p>The table name for mysql.</p>
1955 | */
1956 | public final String table;
1957 | /**
1958 | * <p>The value field name for mysql.</p>
1959 | */
1960 | public final String valueField;
1961 |
1962 | @Override
1963 | public String scheme() {
1964 | return "mysql";
1965 | }
1966 |
1967 | @Override
1968 | public Map<String, String> configMap() {
1969 | final HashMap<String, String> map = new HashMap<>();
1970 | if (connectionString != null) {
1971 | map.put("connection_string", connectionString);
1972 | }
1973 | if (keyField != null) {
1974 | map.put("key_field", keyField);
1975 | }
1976 | if (root != null) {
1977 | map.put("root", root);
1978 | }
1979 | if (table != null) {
1980 | map.put("table", table);
1981 | }
1982 | if (valueField != null) {
1983 | map.put("value_field", valueField);
1984 | }
1985 | return map;
1986 | }
1987 | }
1988 |
1989 | /**
1990 | * Configuration for service obs.
1991 | */
1992 | @Builder
1993 | @Data
1994 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
1995 | class Obs implements ServiceConfig {
1996 | /**
1997 | * <p>Access key id for obs.</p>
1998 | */
1999 | public final String accessKeyId;
2000 | /**
2001 | * <p>Bucket for obs.</p>
2002 | */
2003 | public final String bucket;
2004 | /**
2005 | * <p>Is bucket versioning enabled for this bucket</p>
2006 | */
2007 | public final Boolean enableVersioning;
2008 | /**
2009 | * <p>Endpoint for obs.</p>
2010 | */
2011 | public final String endpoint;
2012 | /**
2013 | * <p>Root for obs.</p>
2014 | */
2015 | public final String root;
2016 | /**
2017 | * <p>Secret access key for obs.</p>
2018 | */
2019 | public final String secretAccessKey;
2020 |
2021 | @Override
2022 | public String scheme() {
2023 | return "obs";
2024 | }
2025 |
2026 | @Override
2027 | public Map<String, String> configMap() {
2028 | final HashMap<String, String> map = new HashMap<>();
2029 | if (accessKeyId != null) {
2030 | map.put("access_key_id", accessKeyId);
2031 | }
2032 | if (bucket != null) {
2033 | map.put("bucket", bucket);
2034 | }
2035 | if (enableVersioning != null) {
2036 | map.put("enable_versioning", String.valueOf(enableVersioning));
2037 | }
2038 | if (endpoint != null) {
2039 | map.put("endpoint", endpoint);
2040 | }
2041 | if (root != null) {
2042 | map.put("root", root);
2043 | }
2044 | if (secretAccessKey != null) {
2045 | map.put("secret_access_key", secretAccessKey);
2046 | }
2047 | return map;
2048 | }
2049 | }
2050 |
2051 | /**
2052 | * Configuration for service onedrive.
2053 | */
2054 | @Builder
2055 | @Data
2056 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2057 | class Onedrive implements ServiceConfig {
2058 | /**
2059 | * <p>Microsoft Graph API (also OneDrive API) access token</p>
2060 | */
2061 | public final String accessToken;
2062 | /**
2063 | * <p>Microsoft Graph API Application (client) ID that is in the Azure's app registration portal</p>
2064 | */
2065 | public final String clientId;
2066 | /**
2067 | * <p>Microsoft Graph API Application client secret that is in the Azure's app registration portal</p>
2068 | */
2069 | public final String clientSecret;
2070 | /**
2071 | * <p>Enabling version support</p>
2072 | */
2073 | public final Boolean enableVersioning;
2074 | /**
2075 | * <p>Microsoft Graph API (also OneDrive API) refresh token</p>
2076 | */
2077 | public final String refreshToken;
2078 | /**
2079 | * <p>The root path for the OneDrive service for the file access</p>
2080 | */
2081 | public final String root;
2082 |
2083 | @Override
2084 | public String scheme() {
2085 | return "onedrive";
2086 | }
2087 |
2088 | @Override
2089 | public Map<String, String> configMap() {
2090 | final HashMap<String, String> map = new HashMap<>();
2091 | if (accessToken != null) {
2092 | map.put("access_token", accessToken);
2093 | }
2094 | if (clientId != null) {
2095 | map.put("client_id", clientId);
2096 | }
2097 | if (clientSecret != null) {
2098 | map.put("client_secret", clientSecret);
2099 | }
2100 | if (enableVersioning != null) {
2101 | map.put("enable_versioning", String.valueOf(enableVersioning));
2102 | }
2103 | if (refreshToken != null) {
2104 | map.put("refresh_token", refreshToken);
2105 | }
2106 | if (root != null) {
2107 | map.put("root", root);
2108 | }
2109 | return map;
2110 | }
2111 | }
2112 |
2113 | /**
2114 | * Configuration for service opfs.
2115 | */
2116 | @Builder
2117 | @Data
2118 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2119 | class Opfs implements ServiceConfig {
2120 |
2121 | @Override
2122 | public String scheme() {
2123 | return "opfs";
2124 | }
2125 |
2126 | @Override
2127 | public Map<String, String> configMap() {
2128 | final HashMap<String, String> map = new HashMap<>();
2129 | return map;
2130 | }
2131 | }
2132 |
2133 | /**
2134 | * Configuration for service oss.
2135 | */
2136 | @Builder
2137 | @Data
2138 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2139 | class Oss implements ServiceConfig {
2140 | /**
2141 | * <p>Access key id for oss.</p>
2142 | * <ul>
2143 | * <li>this field if it's <code>is_some</code></li>
2144 | * <li>env value: [<code>ALIBABA_CLOUD_ACCESS_KEY_ID</code>]</li>
2145 | * </ul>
2146 | */
2147 | public final String accessKeyId;
2148 | /**
2149 | * <p>Access key secret for oss.</p>
2150 | * <ul>
2151 | * <li>this field if it's <code>is_some</code></li>
2152 | * <li>env value: [<code>ALIBABA_CLOUD_ACCESS_KEY_SECRET</code>]</li>
2153 | * </ul>
2154 | */
2155 | public final String accessKeySecret;
2156 | /**
2157 | * <p>Addressing style for oss.</p>
2158 | */
2159 | public final String addressingStyle;
2160 | /**
2161 | * <p>Allow anonymous for oss.</p>
2162 | */
2163 | public final Boolean allowAnonymous;
2164 | /**
2165 | * <p>The size of max batch operations.</p>
2166 | *
2167 | * @deprecated Please use `delete_max_size` instead of `batch_max_operations`
2168 | */
2169 | public final Long batchMaxOperations;
2170 | /**
2171 | * <p>Bucket for oss.</p>
2172 | */
2173 | public final @NonNull String bucket;
2174 | /**
2175 | * <p>The size of max delete operations.</p>
2176 | */
2177 | public final Long deleteMaxSize;
2178 | /**
2179 | * <p>is bucket versioning enabled for this bucket</p>
2180 | */
2181 | public final Boolean enableVersioning;
2182 | /**
2183 | * <p>Endpoint for oss.</p>
2184 | */
2185 | public final String endpoint;
2186 | /**
2187 | * <p><code>oidc_provider_arn</code> will be loaded from</p>
2188 | * <ul>
2189 | * <li>this field if it's <code>is_some</code></li>
2190 | * <li>env value: [<code>ALIBABA_CLOUD_OIDC_PROVIDER_ARN</code>]</li>
2191 | * </ul>
2192 | */
2193 | public final String oidcProviderArn;
2194 | /**
2195 | * <p><code>oidc_token_file</code> will be loaded from</p>
2196 | * <ul>
2197 | * <li>this field if it's <code>is_some</code></li>
2198 | * <li>env value: [<code>ALIBABA_CLOUD_OIDC_TOKEN_FILE</code>]</li>
2199 | * </ul>
2200 | */
2201 | public final String oidcTokenFile;
2202 | /**
2203 | * <p>Pre sign addressing style for oss.</p>
2204 | */
2205 | public final String presignAddressingStyle;
2206 | /**
2207 | * <p>Presign endpoint for oss.</p>
2208 | */
2209 | public final String presignEndpoint;
2210 | /**
2211 | * <p>If <code>role_arn</code> is set, we will use already known config as source
2212 | * credential to assume role with <code>role_arn</code>.</p>
2213 | * <ul>
2214 | * <li>this field if it's <code>is_some</code></li>
2215 | * <li>env value: [<code>ALIBABA_CLOUD_ROLE_ARN</code>]</li>
2216 | * </ul>
2217 | */
2218 | public final String roleArn;
2219 | /**
2220 | * <p>role_session_name for this backend.</p>
2221 | */
2222 | public final String roleSessionName;
2223 | /**
2224 | * <p>Root for oss.</p>
2225 | */
2226 | public final String root;
2227 | /**
2228 | * <p><code>security_token</code> will be loaded from</p>
2229 | * <ul>
2230 | * <li>this field if it's <code>is_some</code></li>
2231 | * <li>env value: [<code>ALIBABA_CLOUD_SECURITY_TOKEN</code>]</li>
2232 | * </ul>
2233 | */
2234 | public final String securityToken;
2235 | /**
2236 | * <p>Server side encryption for oss.</p>
2237 | */
2238 | public final String serverSideEncryption;
2239 | /**
2240 | * <p>Server side encryption key id for oss.</p>
2241 | */
2242 | public final String serverSideEncryptionKeyId;
2243 | /**
2244 | * <p><code>sts_endpoint</code> will be loaded from</p>
2245 | * <ul>
2246 | * <li>this field if it's <code>is_some</code></li>
2247 | * <li>env value: [<code>ALIBABA_CLOUD_STS_ENDPOINT</code>]</li>
2248 | * </ul>
2249 | */
2250 | public final String stsEndpoint;
2251 |
2252 | @Override
2253 | public String scheme() {
2254 | return "oss";
2255 | }
2256 |
2257 | @Override
2258 | public Map<String, String> configMap() {
2259 | final HashMap<String, String> map = new HashMap<>();
2260 | if (accessKeyId != null) {
2261 | map.put("access_key_id", accessKeyId);
2262 | }
2263 | if (accessKeySecret != null) {
2264 | map.put("access_key_secret", accessKeySecret);
2265 | }
2266 | if (addressingStyle != null) {
2267 | map.put("addressing_style", addressingStyle);
2268 | }
2269 | if (allowAnonymous != null) {
2270 | map.put("allow_anonymous", String.valueOf(allowAnonymous));
2271 | }
2272 | if (batchMaxOperations != null) {
2273 | map.put("batch_max_operations", String.valueOf(batchMaxOperations));
2274 | }
2275 | map.put("bucket", bucket);
2276 | if (deleteMaxSize != null) {
2277 | map.put("delete_max_size", String.valueOf(deleteMaxSize));
2278 | }
2279 | if (enableVersioning != null) {
2280 | map.put("enable_versioning", String.valueOf(enableVersioning));
2281 | }
2282 | if (endpoint != null) {
2283 | map.put("endpoint", endpoint);
2284 | }
2285 | if (oidcProviderArn != null) {
2286 | map.put("oidc_provider_arn", oidcProviderArn);
2287 | }
2288 | if (oidcTokenFile != null) {
2289 | map.put("oidc_token_file", oidcTokenFile);
2290 | }
2291 | if (presignAddressingStyle != null) {
2292 | map.put("presign_addressing_style", presignAddressingStyle);
2293 | }
2294 | if (presignEndpoint != null) {
2295 | map.put("presign_endpoint", presignEndpoint);
2296 | }
2297 | if (roleArn != null) {
2298 | map.put("role_arn", roleArn);
2299 | }
2300 | if (roleSessionName != null) {
2301 | map.put("role_session_name", roleSessionName);
2302 | }
2303 | if (root != null) {
2304 | map.put("root", root);
2305 | }
2306 | if (securityToken != null) {
2307 | map.put("security_token", securityToken);
2308 | }
2309 | if (serverSideEncryption != null) {
2310 | map.put("server_side_encryption", serverSideEncryption);
2311 | }
2312 | if (serverSideEncryptionKeyId != null) {
2313 | map.put("server_side_encryption_key_id", serverSideEncryptionKeyId);
2314 | }
2315 | if (stsEndpoint != null) {
2316 | map.put("sts_endpoint", stsEndpoint);
2317 | }
2318 | return map;
2319 | }
2320 | }
2321 |
2322 | /**
2323 | * Configuration for service pcloud.
2324 | */
2325 | @Builder
2326 | @Data
2327 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2328 | class Pcloud implements ServiceConfig {
2329 | /**
2330 | * <p>pCloud endpoint address.</p>
2331 | */
2332 | public final @NonNull String endpoint;
2333 | /**
2334 | * <p>pCloud password.</p>
2335 | */
2336 | public final String password;
2337 | /**
2338 | * <p>root of this backend.</p>
2339 | * <p>All operations will happen under this root.</p>
2340 | */
2341 | public final String root;
2342 | /**
2343 | * <p>pCloud username.</p>
2344 | */
2345 | public final String username;
2346 |
2347 | @Override
2348 | public String scheme() {
2349 | return "pcloud";
2350 | }
2351 |
2352 | @Override
2353 | public Map<String, String> configMap() {
2354 | final HashMap<String, String> map = new HashMap<>();
2355 | map.put("endpoint", endpoint);
2356 | if (password != null) {
2357 | map.put("password", password);
2358 | }
2359 | if (root != null) {
2360 | map.put("root", root);
2361 | }
2362 | if (username != null) {
2363 | map.put("username", username);
2364 | }
2365 | return map;
2366 | }
2367 | }
2368 |
2369 | /**
2370 | * Configuration for service persy.
2371 | */
2372 | @Builder
2373 | @Data
2374 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2375 | class Persy implements ServiceConfig {
2376 | /**
2377 | * <p>That path to the persy data file. The directory in the path must already exist.</p>
2378 | */
2379 | public final String datafile;
2380 | /**
2381 | * <p>That name of the persy index.</p>
2382 | */
2383 | public final String index;
2384 | /**
2385 | * <p>That name of the persy segment.</p>
2386 | */
2387 | public final String segment;
2388 |
2389 | @Override
2390 | public String scheme() {
2391 | return "persy";
2392 | }
2393 |
2394 | @Override
2395 | public Map<String, String> configMap() {
2396 | final HashMap<String, String> map = new HashMap<>();
2397 | if (datafile != null) {
2398 | map.put("datafile", datafile);
2399 | }
2400 | if (index != null) {
2401 | map.put("index", index);
2402 | }
2403 | if (segment != null) {
2404 | map.put("segment", segment);
2405 | }
2406 | return map;
2407 | }
2408 | }
2409 |
2410 | /**
2411 | * Configuration for service postgresql.
2412 | */
2413 | @Builder
2414 | @Data
2415 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2416 | class Postgresql implements ServiceConfig {
2417 | /**
2418 | * <p>The URL should be with a scheme of either <code>postgres://</code> or <code>postgresql://</code>.</p>
2419 | * <ul>
2420 | * <li><code>postgresql://user@localhost</code></li>
2421 | * <li><code>postgresql://user:password@%2Fvar%2Flib%2Fpostgresql/mydb?connect_timeout=10</code></li>
2422 | * <li><code>postgresql://user@host1:1234,host2,host3:5678?target_session_attrs=read-write</code></li>
2423 | * <li><code>postgresql:///mydb?user=user&host=/var/lib/postgresql</code></li>
2424 | * </ul>
2425 | * <p>For more information, please visit <a href="https://docs.rs/sqlx/latest/sqlx/postgres/struct.PgConnectOptions.html">https://docs.rs/sqlx/latest/sqlx/postgres/struct.PgConnectOptions.html</a>.</p>
2426 | */
2427 | public final String connectionString;
2428 | /**
2429 | * <p>the key field of postgresql</p>
2430 | */
2431 | public final String keyField;
2432 | /**
2433 | * <p>Root of this backend.</p>
2434 | * <p>All operations will happen under this root.</p>
2435 | * <p>Default to <code>/</code> if not set.</p>
2436 | */
2437 | public final String root;
2438 | /**
2439 | * <p>the table of postgresql</p>
2440 | */
2441 | public final String table;
2442 | /**
2443 | * <p>the value field of postgresql</p>
2444 | */
2445 | public final String valueField;
2446 |
2447 | @Override
2448 | public String scheme() {
2449 | return "postgresql";
2450 | }
2451 |
2452 | @Override
2453 | public Map<String, String> configMap() {
2454 | final HashMap<String, String> map = new HashMap<>();
2455 | if (connectionString != null) {
2456 | map.put("connection_string", connectionString);
2457 | }
2458 | if (keyField != null) {
2459 | map.put("key_field", keyField);
2460 | }
2461 | if (root != null) {
2462 | map.put("root", root);
2463 | }
2464 | if (table != null) {
2465 | map.put("table", table);
2466 | }
2467 | if (valueField != null) {
2468 | map.put("value_field", valueField);
2469 | }
2470 | return map;
2471 | }
2472 | }
2473 |
2474 | /**
2475 | * Configuration for service redb.
2476 | */
2477 | @Builder
2478 | @Data
2479 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2480 | class Redb implements ServiceConfig {
2481 | /**
2482 | * <p>path to the redb data directory.</p>
2483 | */
2484 | public final String datadir;
2485 | /**
2486 | * <p>The root for redb.</p>
2487 | */
2488 | public final String root;
2489 | /**
2490 | * <p>The table name for redb.</p>
2491 | */
2492 | public final String table;
2493 |
2494 | @Override
2495 | public String scheme() {
2496 | return "redb";
2497 | }
2498 |
2499 | @Override
2500 | public Map<String, String> configMap() {
2501 | final HashMap<String, String> map = new HashMap<>();
2502 | if (datadir != null) {
2503 | map.put("datadir", datadir);
2504 | }
2505 | if (root != null) {
2506 | map.put("root", root);
2507 | }
2508 | if (table != null) {
2509 | map.put("table", table);
2510 | }
2511 | return map;
2512 | }
2513 | }
2514 |
2515 | /**
2516 | * Configuration for service redis.
2517 | */
2518 | @Builder
2519 | @Data
2520 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2521 | class Redis implements ServiceConfig {
2522 | /**
2523 | * <p>network address of the Redis cluster service. Can be "tcp://127.0.0.1:6379,tcp://127.0.0.1:6380,tcp://127.0.0.1:6381", e.g.</p>
2524 | * <p>default is None</p>
2525 | */
2526 | public final String clusterEndpoints;
2527 | /**
2528 | * <p>The maximum number of connections allowed.</p>
2529 | * <p>default is 10</p>
2530 | */
2531 | public final Integer connectionPoolMaxSize;
2532 | /**
2533 | * <p>the number of DBs redis can take is unlimited</p>
2534 | * <p>default is db 0</p>
2535 | */
2536 | public final long db;
2537 | /**
2538 | * <p>The default ttl for put operations.</p>
2539 | */
2540 | public final Duration defaultTtl;
2541 | /**
2542 | * <p>network address of the Redis service. Can be "tcp://127.0.0.1:6379", e.g.</p>
2543 | * <p>default is "tcp://127.0.0.1:6379"</p>
2544 | */
2545 | public final String endpoint;
2546 | /**
2547 | * <p>the password for authentication</p>
2548 | * <p>default is None</p>
2549 | */
2550 | public final String password;
2551 | /**
2552 | * <p>the working directory of the Redis service. Can be "/path/to/dir"</p>
2553 | * <p>default is "/"</p>
2554 | */
2555 | public final String root;
2556 | /**
2557 | * <p>the username to connect redis service.</p>
2558 | * <p>default is None</p>
2559 | */
2560 | public final String username;
2561 |
2562 | @Override
2563 | public String scheme() {
2564 | return "redis";
2565 | }
2566 |
2567 | @Override
2568 | public Map<String, String> configMap() {
2569 | final HashMap<String, String> map = new HashMap<>();
2570 | if (clusterEndpoints != null) {
2571 | map.put("cluster_endpoints", clusterEndpoints);
2572 | }
2573 | if (connectionPoolMaxSize != null) {
2574 | map.put("connection_pool_max_size", String.valueOf(connectionPoolMaxSize));
2575 | }
2576 | map.put("db", String.valueOf(db));
2577 | if (defaultTtl != null) {
2578 | map.put("default_ttl", defaultTtl.toString());
2579 | }
2580 | if (endpoint != null) {
2581 | map.put("endpoint", endpoint);
2582 | }
2583 | if (password != null) {
2584 | map.put("password", password);
2585 | }
2586 | if (root != null) {
2587 | map.put("root", root);
2588 | }
2589 | if (username != null) {
2590 | map.put("username", username);
2591 | }
2592 | return map;
2593 | }
2594 | }
2595 |
2596 | /**
2597 | * Configuration for service s3.
2598 | */
2599 | @Builder
2600 | @Data
2601 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2602 | class S3 implements ServiceConfig {
2603 | /**
2604 | * <p>access_key_id of this backend.</p>
2605 | * <ul>
2606 | * <li>If access_key_id is set, we will take user's input first.</li>
2607 | * <li>If not, we will try to load it from environment.</li>
2608 | * </ul>
2609 | */
2610 | public final String accessKeyId;
2611 | /**
2612 | * <p>Allow anonymous will allow opendal to send request without signing
2613 | * when credential is not loaded.</p>
2614 | */
2615 | public final Boolean allowAnonymous;
2616 | /**
2617 | * <p>Set maximum batch operations of this backend.</p>
2618 | * <p>Some compatible services have a limit on the number of operations in a batch request.
2619 | * For example, R2 could return <code>Internal Error</code> while batch delete 1000 files.</p>
2620 | * <p>Please tune this value based on services' document.</p>
2621 | *
2622 | * @deprecated Please use `delete_max_size` instead of `batch_max_operations`
2623 | */
2624 | public final Long batchMaxOperations;
2625 | /**
2626 | * <p>bucket name of this backend.</p>
2627 | * <p>required.</p>
2628 | */
2629 | public final @NonNull String bucket;
2630 | /**
2631 | * <p>Checksum Algorithm to use when sending checksums in HTTP headers.
2632 | * This is necessary when writing to AWS S3 Buckets with Object Lock enabled for example.</p>
2633 | * <p>Available options:</p>
2634 | * <ul>
2635 | * <li>"crc32c"</li>
2636 | * </ul>
2637 | */
2638 | public final String checksumAlgorithm;
2639 | /**
2640 | * <p>default storage_class for this backend.</p>
2641 | * <p>Available values:</p>
2642 | * <ul>
2643 | * <li><code>DEEP_ARCHIVE</code></li>
2644 | * <li><code>GLACIER</code></li>
2645 | * <li><code>GLACIER_IR</code></li>
2646 | * <li><code>INTELLIGENT_TIERING</code></li>
2647 | * <li><code>ONEZONE_IA</code></li>
2648 | * <li><code>EXPRESS_ONEZONE</code></li>
2649 | * <li><code>OUTPOSTS</code></li>
2650 | * <li><code>REDUCED_REDUNDANCY</code></li>
2651 | * <li><code>STANDARD</code></li>
2652 | * <li><code>STANDARD_IA</code></li>
2653 | * </ul>
2654 | * <p>S3 compatible services don't support all of them</p>
2655 | */
2656 | public final String defaultStorageClass;
2657 | /**
2658 | * <p>Set the maximum delete size of this backend.</p>
2659 | * <p>Some compatible services have a limit on the number of operations in a batch request.
2660 | * For example, R2 could return <code>Internal Error</code> while batch delete 1000 files.</p>
2661 | * <p>Please tune this value based on services' document.</p>
2662 | */
2663 | public final Long deleteMaxSize;
2664 | /**
2665 | * <p>Disable config load so that opendal will not load config from
2666 | * environment.</p>
2667 | * <p>For examples:</p>
2668 | * <ul>
2669 | * <li>envs like <code>AWS_ACCESS_KEY_ID</code></li>
2670 | * <li>files like <code>~/.aws/config</code></li>
2671 | * </ul>
2672 | */
2673 | public final Boolean disableConfigLoad;
2674 | /**
2675 | * <p>Disable load credential from ec2 metadata.</p>
2676 | * <p>This option is used to disable the default behavior of opendal
2677 | * to load credential from ec2 metadata, a.k.a, IMDSv2</p>
2678 | */
2679 | public final Boolean disableEc2Metadata;
2680 | /**
2681 | * <p>OpenDAL uses List Objects V2 by default to list objects.
2682 | * However, some legacy services do not yet support V2.
2683 | * This option allows users to switch back to the older List Objects V1.</p>
2684 | */
2685 | public final Boolean disableListObjectsV2;
2686 | /**
2687 | * <p>Disable stat with override so that opendal will not send stat request with override queries.</p>
2688 | * <p>For example, R2 doesn't support stat with <code>response_content_type</code> query.</p>
2689 | */
2690 | public final Boolean disableStatWithOverride;
2691 | /**
2692 | * <p>Disable write with if match so that opendal will not send write request with if match headers.</p>
2693 | * <p>For example, Ceph RADOS S3 doesn't support write with if match.</p>
2694 | */
2695 | public final Boolean disableWriteWithIfMatch;
2696 | /**
2697 | * <p>Indicates whether the client agrees to pay for the requests made to the S3 bucket.</p>
2698 | */
2699 | public final Boolean enableRequestPayer;
2700 | /**
2701 | * <p>is bucket versioning enabled for this bucket</p>
2702 | */
2703 | public final Boolean enableVersioning;
2704 | /**
2705 | * <p>Enable virtual host style so that opendal will send API requests
2706 | * in virtual host style instead of path style.</p>
2707 | * <ul>
2708 | * <li>By default, opendal will send API to <code>https://s3.us-east-1.amazonaws.com/bucket_name</code></li>
2709 | * <li>Enabled, opendal will send API to <code>https://bucket_name.s3.us-east-1.amazonaws.com</code></li>
2710 | * </ul>
2711 | */
2712 | public final Boolean enableVirtualHostStyle;
2713 | /**
2714 | * <p>Enable write with append so that opendal will send write request with append headers.</p>
2715 | */
2716 | public final Boolean enableWriteWithAppend;
2717 | /**
2718 | * <p>endpoint of this backend.</p>
2719 | * <p>Endpoint must be full uri, e.g.</p>
2720 | * <ul>
2721 | * <li>AWS S3: <code>https://s3.amazonaws.com</code> or <code>https://s3.{region}.amazonaws.com</code></li>
2722 | * <li>Cloudflare R2: <code>https://<ACCOUNT_ID>.r2.cloudflarestorage.com</code></li>
2723 | * <li>Aliyun OSS: <code>https://{region}.aliyuncs.com</code></li>
2724 | * <li>Tencent COS: <code>https://cos.{region}.myqcloud.com</code></li>
2725 | * <li>Minio: <code>http://127.0.0.1:9000</code></li>
2726 | * </ul>
2727 | * <p>If user inputs endpoint without scheme like "s3.amazonaws.com", we
2728 | * will prepend "https://" before it.</p>
2729 | * <ul>
2730 | * <li>If endpoint is set, we will take user's input first.</li>
2731 | * <li>If not, we will try to load it from environment.</li>
2732 | * <li>If still not set, default to <code>https://s3.amazonaws.com</code>.</li>
2733 | * </ul>
2734 | */
2735 | public final String endpoint;
2736 | /**
2737 | * <p>external_id for this backend.</p>
2738 | */
2739 | public final String externalId;
2740 | /**
2741 | * <p>Region represent the signing region of this endpoint. This is required
2742 | * if you are using the default AWS S3 endpoint.</p>
2743 | * <p>If using a custom endpoint,</p>
2744 | * <ul>
2745 | * <li>If region is set, we will take user's input first.</li>
2746 | * <li>If not, we will try to load it from environment.</li>
2747 | * </ul>
2748 | */
2749 | public final String region;
2750 | /**
2751 | * <p>role_arn for this backend.</p>
2752 | * <p>If <code>role_arn</code> is set, we will use already known config as source
2753 | * credential to assume role with <code>role_arn</code>.</p>
2754 | */
2755 | public final String roleArn;
2756 | /**
2757 | * <p>role_session_name for this backend.</p>
2758 | */
2759 | public final String roleSessionName;
2760 | /**
2761 | * <p>root of this backend.</p>
2762 | * <p>All operations will happen under this root.</p>
2763 | * <p>default to <code>/</code> if not set.</p>
2764 | */
2765 | public final String root;
2766 | /**
2767 | * <p>secret_access_key of this backend.</p>
2768 | * <ul>
2769 | * <li>If secret_access_key is set, we will take user's input first.</li>
2770 | * <li>If not, we will try to load it from environment.</li>
2771 | * </ul>
2772 | */
2773 | public final String secretAccessKey;
2774 | /**
2775 | * <p>server_side_encryption for this backend.</p>
2776 | * <p>Available values: <code>AES256</code>, <code>aws:kms</code>.</p>
2777 | */
2778 | public final String serverSideEncryption;
2779 | /**
2780 | * <p>server_side_encryption_aws_kms_key_id for this backend</p>
2781 | * <ul>
2782 | * <li>If <code>server_side_encryption</code> set to <code>aws:kms</code>, and <code>server_side_encryption_aws_kms_key_id</code>
2783 | * is not set, S3 will use aws managed kms key to encrypt data.</li>
2784 | * <li>If <code>server_side_encryption</code> set to <code>aws:kms</code>, and <code>server_side_encryption_aws_kms_key_id</code>
2785 | * is a valid kms key id, S3 will use the provided kms key to encrypt data.</li>
2786 | * <li>If the <code>server_side_encryption_aws_kms_key_id</code> is invalid or not found, an error will be
2787 | * returned.</li>
2788 | * <li>If <code>server_side_encryption</code> is not <code>aws:kms</code>, setting <code>server_side_encryption_aws_kms_key_id</code>
2789 | * is a noop.</li>
2790 | * </ul>
2791 | */
2792 | public final String serverSideEncryptionAwsKmsKeyId;
2793 | /**
2794 | * <p>server_side_encryption_customer_algorithm for this backend.</p>
2795 | * <p>Available values: <code>AES256</code>.</p>
2796 | */
2797 | public final String serverSideEncryptionCustomerAlgorithm;
2798 | /**
2799 | * <p>server_side_encryption_customer_key for this backend.</p>
2800 | * <p>Value: BASE64-encoded key that matches algorithm specified in
2801 | * <code>server_side_encryption_customer_algorithm</code>.</p>
2802 | */
2803 | public final String serverSideEncryptionCustomerKey;
2804 | /**
2805 | * <p>Set server_side_encryption_customer_key_md5 for this backend.</p>
2806 | * <p>Value: MD5 digest of key specified in <code>server_side_encryption_customer_key</code>.</p>
2807 | */
2808 | public final String serverSideEncryptionCustomerKeyMd5;
2809 | /**
2810 | * <p>session_token (aka, security token) of this backend.</p>
2811 | * <p>This token will expire after sometime, it's recommended to set session_token
2812 | * by hand.</p>
2813 | */
2814 | public final String sessionToken;
2815 |
2816 | @Override
2817 | public String scheme() {
2818 | return "s3";
2819 | }
2820 |
2821 | @Override
2822 | public Map<String, String> configMap() {
2823 | final HashMap<String, String> map = new HashMap<>();
2824 | if (accessKeyId != null) {
2825 | map.put("access_key_id", accessKeyId);
2826 | }
2827 | if (allowAnonymous != null) {
2828 | map.put("allow_anonymous", String.valueOf(allowAnonymous));
2829 | }
2830 | if (batchMaxOperations != null) {
2831 | map.put("batch_max_operations", String.valueOf(batchMaxOperations));
2832 | }
2833 | map.put("bucket", bucket);
2834 | if (checksumAlgorithm != null) {
2835 | map.put("checksum_algorithm", checksumAlgorithm);
2836 | }
2837 | if (defaultStorageClass != null) {
2838 | map.put("default_storage_class", defaultStorageClass);
2839 | }
2840 | if (deleteMaxSize != null) {
2841 | map.put("delete_max_size", String.valueOf(deleteMaxSize));
2842 | }
2843 | if (disableConfigLoad != null) {
2844 | map.put("disable_config_load", String.valueOf(disableConfigLoad));
2845 | }
2846 | if (disableEc2Metadata != null) {
2847 | map.put("disable_ec2_metadata", String.valueOf(disableEc2Metadata));
2848 | }
2849 | if (disableListObjectsV2 != null) {
2850 | map.put("disable_list_objects_v2", String.valueOf(disableListObjectsV2));
2851 | }
2852 | if (disableStatWithOverride != null) {
2853 | map.put("disable_stat_with_override", String.valueOf(disableStatWithOverride));
2854 | }
2855 | if (disableWriteWithIfMatch != null) {
2856 | map.put("disable_write_with_if_match", String.valueOf(disableWriteWithIfMatch));
2857 | }
2858 | if (enableRequestPayer != null) {
2859 | map.put("enable_request_payer", String.valueOf(enableRequestPayer));
2860 | }
2861 | if (enableVersioning != null) {
2862 | map.put("enable_versioning", String.valueOf(enableVersioning));
2863 | }
2864 | if (enableVirtualHostStyle != null) {
2865 | map.put("enable_virtual_host_style", String.valueOf(enableVirtualHostStyle));
2866 | }
2867 | if (enableWriteWithAppend != null) {
2868 | map.put("enable_write_with_append", String.valueOf(enableWriteWithAppend));
2869 | }
2870 | if (endpoint != null) {
2871 | map.put("endpoint", endpoint);
2872 | }
2873 | if (externalId != null) {
2874 | map.put("external_id", externalId);
2875 | }
2876 | if (region != null) {
2877 | map.put("region", region);
2878 | }
2879 | if (roleArn != null) {
2880 | map.put("role_arn", roleArn);
2881 | }
2882 | if (roleSessionName != null) {
2883 | map.put("role_session_name", roleSessionName);
2884 | }
2885 | if (root != null) {
2886 | map.put("root", root);
2887 | }
2888 | if (secretAccessKey != null) {
2889 | map.put("secret_access_key", secretAccessKey);
2890 | }
2891 | if (serverSideEncryption != null) {
2892 | map.put("server_side_encryption", serverSideEncryption);
2893 | }
2894 | if (serverSideEncryptionAwsKmsKeyId != null) {
2895 | map.put("server_side_encryption_aws_kms_key_id", serverSideEncryptionAwsKmsKeyId);
2896 | }
2897 | if (serverSideEncryptionCustomerAlgorithm != null) {
2898 | map.put("server_side_encryption_customer_algorithm", serverSideEncryptionCustomerAlgorithm);
2899 | }
2900 | if (serverSideEncryptionCustomerKey != null) {
2901 | map.put("server_side_encryption_customer_key", serverSideEncryptionCustomerKey);
2902 | }
2903 | if (serverSideEncryptionCustomerKeyMd5 != null) {
2904 | map.put("server_side_encryption_customer_key_md5", serverSideEncryptionCustomerKeyMd5);
2905 | }
2906 | if (sessionToken != null) {
2907 | map.put("session_token", sessionToken);
2908 | }
2909 | return map;
2910 | }
2911 | }
2912 |
2913 | /**
2914 | * Configuration for service seafile.
2915 | */
2916 | @Builder
2917 | @Data
2918 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2919 | class Seafile implements ServiceConfig {
2920 | /**
2921 | * <p>endpoint address of this backend.</p>
2922 | */
2923 | public final String endpoint;
2924 | /**
2925 | * <p>password of this backend.</p>
2926 | */
2927 | public final String password;
2928 | /**
2929 | * <p>repo_name of this backend.</p>
2930 | * <p>required.</p>
2931 | */
2932 | public final @NonNull String repoName;
2933 | /**
2934 | * <p>root of this backend.</p>
2935 | * <p>All operations will happen under this root.</p>
2936 | */
2937 | public final String root;
2938 | /**
2939 | * <p>username of this backend.</p>
2940 | */
2941 | public final String username;
2942 |
2943 | @Override
2944 | public String scheme() {
2945 | return "seafile";
2946 | }
2947 |
2948 | @Override
2949 | public Map<String, String> configMap() {
2950 | final HashMap<String, String> map = new HashMap<>();
2951 | if (endpoint != null) {
2952 | map.put("endpoint", endpoint);
2953 | }
2954 | if (password != null) {
2955 | map.put("password", password);
2956 | }
2957 | map.put("repo_name", repoName);
2958 | if (root != null) {
2959 | map.put("root", root);
2960 | }
2961 | if (username != null) {
2962 | map.put("username", username);
2963 | }
2964 | return map;
2965 | }
2966 | }
2967 |
2968 | /**
2969 | * Configuration for service sftp.
2970 | */
2971 | @Builder
2972 | @Data
2973 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
2974 | class Sftp implements ServiceConfig {
2975 | /**
2976 | * <p>enable_copy of this backend</p>
2977 | */
2978 | public final Boolean enableCopy;
2979 | /**
2980 | * <p>endpoint of this backend</p>
2981 | */
2982 | public final String endpoint;
2983 | /**
2984 | * <p>key of this backend</p>
2985 | */
2986 | public final String key;
2987 | /**
2988 | * <p>known_hosts_strategy of this backend</p>
2989 | */
2990 | public final String knownHostsStrategy;
2991 | /**
2992 | * <p>root of this backend</p>
2993 | */
2994 | public final String root;
2995 | /**
2996 | * <p>user of this backend</p>
2997 | */
2998 | public final String user;
2999 |
3000 | @Override
3001 | public String scheme() {
3002 | return "sftp";
3003 | }
3004 |
3005 | @Override
3006 | public Map<String, String> configMap() {
3007 | final HashMap<String, String> map = new HashMap<>();
3008 | if (enableCopy != null) {
3009 | map.put("enable_copy", String.valueOf(enableCopy));
3010 | }
3011 | if (endpoint != null) {
3012 | map.put("endpoint", endpoint);
3013 | }
3014 | if (key != null) {
3015 | map.put("key", key);
3016 | }
3017 | if (knownHostsStrategy != null) {
3018 | map.put("known_hosts_strategy", knownHostsStrategy);
3019 | }
3020 | if (root != null) {
3021 | map.put("root", root);
3022 | }
3023 | if (user != null) {
3024 | map.put("user", user);
3025 | }
3026 | return map;
3027 | }
3028 | }
3029 |
3030 | /**
3031 | * Configuration for service sled.
3032 | */
3033 | @Builder
3034 | @Data
3035 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3036 | class Sled implements ServiceConfig {
3037 | /**
3038 | * <p>That path to the sled data directory.</p>
3039 | */
3040 | public final String datadir;
3041 | /**
3042 | * <p>The root for sled.</p>
3043 | */
3044 | public final String root;
3045 | /**
3046 | * <p>The tree for sled.</p>
3047 | */
3048 | public final String tree;
3049 |
3050 | @Override
3051 | public String scheme() {
3052 | return "sled";
3053 | }
3054 |
3055 | @Override
3056 | public Map<String, String> configMap() {
3057 | final HashMap<String, String> map = new HashMap<>();
3058 | if (datadir != null) {
3059 | map.put("datadir", datadir);
3060 | }
3061 | if (root != null) {
3062 | map.put("root", root);
3063 | }
3064 | if (tree != null) {
3065 | map.put("tree", tree);
3066 | }
3067 | return map;
3068 | }
3069 | }
3070 |
3071 | /**
3072 | * Configuration for service sqlite.
3073 | */
3074 | @Builder
3075 | @Data
3076 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3077 | class Sqlite implements ServiceConfig {
3078 | /**
3079 | * <p>Set the connection_string of the sqlite service.</p>
3080 | * <p>This connection string is used to connect to the sqlite service.</p>
3081 | * <p>The format of connect string resembles the url format of the sqlite client:</p>
3082 | * <ul>
3083 | * <li><code>sqlite::memory:</code></li>
3084 | * <li><code>sqlite:data.db</code></li>
3085 | * <li><code>sqlite://data.db</code></li>
3086 | * </ul>
3087 | * <p>For more information, please visit <a href="https://docs.rs/sqlx/latest/sqlx/sqlite/struct.SqliteConnectOptions.html">https://docs.rs/sqlx/latest/sqlx/sqlite/struct.SqliteConnectOptions.html</a>.</p>
3088 | */
3089 | public final String connectionString;
3090 | /**
3091 | * <p>Set the key field name of the sqlite service to read/write.</p>
3092 | * <p>Default to <code>key</code> if not specified.</p>
3093 | */
3094 | public final String keyField;
3095 | /**
3096 | * <p>set the working directory, all operations will be performed under it.</p>
3097 | * <p>default: "/"</p>
3098 | */
3099 | public final String root;
3100 | /**
3101 | * <p>Set the table name of the sqlite service to read/write.</p>
3102 | */
3103 | public final String table;
3104 | /**
3105 | * <p>Set the value field name of the sqlite service to read/write.</p>
3106 | * <p>Default to <code>value</code> if not specified.</p>
3107 | */
3108 | public final String valueField;
3109 |
3110 | @Override
3111 | public String scheme() {
3112 | return "sqlite";
3113 | }
3114 |
3115 | @Override
3116 | public Map<String, String> configMap() {
3117 | final HashMap<String, String> map = new HashMap<>();
3118 | if (connectionString != null) {
3119 | map.put("connection_string", connectionString);
3120 | }
3121 | if (keyField != null) {
3122 | map.put("key_field", keyField);
3123 | }
3124 | if (root != null) {
3125 | map.put("root", root);
3126 | }
3127 | if (table != null) {
3128 | map.put("table", table);
3129 | }
3130 | if (valueField != null) {
3131 | map.put("value_field", valueField);
3132 | }
3133 | return map;
3134 | }
3135 | }
3136 |
3137 | /**
3138 | * Configuration for service surrealdb.
3139 | */
3140 | @Builder
3141 | @Data
3142 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3143 | class Surrealdb implements ServiceConfig {
3144 | /**
3145 | * <p>The connection string for surrealdb.</p>
3146 | */
3147 | public final String connectionString;
3148 | /**
3149 | * <p>The database for surrealdb.</p>
3150 | */
3151 | public final String database;
3152 | /**
3153 | * <p>The key field for surrealdb.</p>
3154 | */
3155 | public final String keyField;
3156 | /**
3157 | * <p>The namespace for surrealdb.</p>
3158 | */
3159 | public final String namespace;
3160 | /**
3161 | * <p>The password for surrealdb.</p>
3162 | */
3163 | public final String password;
3164 | /**
3165 | * <p>The root for surrealdb.</p>
3166 | */
3167 | public final String root;
3168 | /**
3169 | * <p>The table for surrealdb.</p>
3170 | */
3171 | public final String table;
3172 | /**
3173 | * <p>The username for surrealdb.</p>
3174 | */
3175 | public final String username;
3176 | /**
3177 | * <p>The value field for surrealdb.</p>
3178 | */
3179 | public final String valueField;
3180 |
3181 | @Override
3182 | public String scheme() {
3183 | return "surrealdb";
3184 | }
3185 |
3186 | @Override
3187 | public Map<String, String> configMap() {
3188 | final HashMap<String, String> map = new HashMap<>();
3189 | if (connectionString != null) {
3190 | map.put("connection_string", connectionString);
3191 | }
3192 | if (database != null) {
3193 | map.put("database", database);
3194 | }
3195 | if (keyField != null) {
3196 | map.put("key_field", keyField);
3197 | }
3198 | if (namespace != null) {
3199 | map.put("namespace", namespace);
3200 | }
3201 | if (password != null) {
3202 | map.put("password", password);
3203 | }
3204 | if (root != null) {
3205 | map.put("root", root);
3206 | }
3207 | if (table != null) {
3208 | map.put("table", table);
3209 | }
3210 | if (username != null) {
3211 | map.put("username", username);
3212 | }
3213 | if (valueField != null) {
3214 | map.put("value_field", valueField);
3215 | }
3216 | return map;
3217 | }
3218 | }
3219 |
3220 | /**
3221 | * Configuration for service swift.
3222 | */
3223 | @Builder
3224 | @Data
3225 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3226 | class Swift implements ServiceConfig {
3227 | /**
3228 | * <p>The container for Swift.</p>
3229 | */
3230 | public final String container;
3231 | /**
3232 | * <p>The endpoint for Swift.</p>
3233 | */
3234 | public final String endpoint;
3235 | /**
3236 | * <p>The root for Swift.</p>
3237 | */
3238 | public final String root;
3239 | /**
3240 | * <p>The token for Swift.</p>
3241 | */
3242 | public final String token;
3243 |
3244 | @Override
3245 | public String scheme() {
3246 | return "swift";
3247 | }
3248 |
3249 | @Override
3250 | public Map<String, String> configMap() {
3251 | final HashMap<String, String> map = new HashMap<>();
3252 | if (container != null) {
3253 | map.put("container", container);
3254 | }
3255 | if (endpoint != null) {
3256 | map.put("endpoint", endpoint);
3257 | }
3258 | if (root != null) {
3259 | map.put("root", root);
3260 | }
3261 | if (token != null) {
3262 | map.put("token", token);
3263 | }
3264 | return map;
3265 | }
3266 | }
3267 |
3268 | /**
3269 | * Configuration for service upyun.
3270 | */
3271 | @Builder
3272 | @Data
3273 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3274 | class Upyun implements ServiceConfig {
3275 | /**
3276 | * <p>bucket address of this backend.</p>
3277 | */
3278 | public final @NonNull String bucket;
3279 | /**
3280 | * <p>username of this backend.</p>
3281 | */
3282 | public final String operator;
3283 | /**
3284 | * <p>password of this backend.</p>
3285 | */
3286 | public final String password;
3287 | /**
3288 | * <p>root of this backend.</p>
3289 | * <p>All operations will happen under this root.</p>
3290 | */
3291 | public final String root;
3292 |
3293 | @Override
3294 | public String scheme() {
3295 | return "upyun";
3296 | }
3297 |
3298 | @Override
3299 | public Map<String, String> configMap() {
3300 | final HashMap<String, String> map = new HashMap<>();
3301 | map.put("bucket", bucket);
3302 | if (operator != null) {
3303 | map.put("operator", operator);
3304 | }
3305 | if (password != null) {
3306 | map.put("password", password);
3307 | }
3308 | if (root != null) {
3309 | map.put("root", root);
3310 | }
3311 | return map;
3312 | }
3313 | }
3314 |
3315 | /**
3316 | * Configuration for service vercel_artifacts.
3317 | */
3318 | @Builder
3319 | @Data
3320 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3321 | class VercelArtifacts implements ServiceConfig {
3322 | /**
3323 | * <p>The access token for Vercel.</p>
3324 | */
3325 | public final String accessToken;
3326 |
3327 | @Override
3328 | public String scheme() {
3329 | return "vercel_artifacts";
3330 | }
3331 |
3332 | @Override
3333 | public Map<String, String> configMap() {
3334 | final HashMap<String, String> map = new HashMap<>();
3335 | if (accessToken != null) {
3336 | map.put("access_token", accessToken);
3337 | }
3338 | return map;
3339 | }
3340 | }
3341 |
3342 | /**
3343 | * Configuration for service vercel_blob.
3344 | */
3345 | @Builder
3346 | @Data
3347 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3348 | class VercelBlob implements ServiceConfig {
3349 | /**
3350 | * <p>root of this backend.</p>
3351 | * <p>All operations will happen under this root.</p>
3352 | */
3353 | public final String root;
3354 | /**
3355 | * <p>vercel blob token.</p>
3356 | */
3357 | public final String token;
3358 |
3359 | @Override
3360 | public String scheme() {
3361 | return "vercel_blob";
3362 | }
3363 |
3364 | @Override
3365 | public Map<String, String> configMap() {
3366 | final HashMap<String, String> map = new HashMap<>();
3367 | if (root != null) {
3368 | map.put("root", root);
3369 | }
3370 | if (token != null) {
3371 | map.put("token", token);
3372 | }
3373 | return map;
3374 | }
3375 | }
3376 |
3377 | /**
3378 | * Configuration for service webdav.
3379 | */
3380 | @Builder
3381 | @Data
3382 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3383 | class Webdav implements ServiceConfig {
3384 | /**
3385 | * <p>WebDAV Service doesn't support copy.</p>
3386 | */
3387 | public final Boolean disableCopy;
3388 | /**
3389 | * <p>endpoint of this backend</p>
3390 | */
3391 | public final String endpoint;
3392 | /**
3393 | * <p>password of this backend</p>
3394 | */
3395 | public final String password;
3396 | /**
3397 | * <p>root of this backend</p>
3398 | */
3399 | public final String root;
3400 | /**
3401 | * <p>token of this backend</p>
3402 | */
3403 | public final String token;
3404 | /**
3405 | * <p>username of this backend</p>
3406 | */
3407 | public final String username;
3408 |
3409 | @Override
3410 | public String scheme() {
3411 | return "webdav";
3412 | }
3413 |
3414 | @Override
3415 | public Map<String, String> configMap() {
3416 | final HashMap<String, String> map = new HashMap<>();
3417 | if (disableCopy != null) {
3418 | map.put("disable_copy", String.valueOf(disableCopy));
3419 | }
3420 | if (endpoint != null) {
3421 | map.put("endpoint", endpoint);
3422 | }
3423 | if (password != null) {
3424 | map.put("password", password);
3425 | }
3426 | if (root != null) {
3427 | map.put("root", root);
3428 | }
3429 | if (token != null) {
3430 | map.put("token", token);
3431 | }
3432 | if (username != null) {
3433 | map.put("username", username);
3434 | }
3435 | return map;
3436 | }
3437 | }
3438 |
3439 | /**
3440 | * Configuration for service webhdfs.
3441 | */
3442 | @Builder
3443 | @Data
3444 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3445 | class Webhdfs implements ServiceConfig {
3446 | /**
3447 | * <p>atomic_write_dir of this backend</p>
3448 | */
3449 | public final String atomicWriteDir;
3450 | /**
3451 | * <p>Delegation token for webhdfs.</p>
3452 | */
3453 | public final String delegation;
3454 | /**
3455 | * <p>Disable batch listing</p>
3456 | */
3457 | public final Boolean disableListBatch;
3458 | /**
3459 | * <p>Endpoint for webhdfs.</p>
3460 | */
3461 | public final String endpoint;
3462 | /**
3463 | * <p>Root for webhdfs.</p>
3464 | */
3465 | public final String root;
3466 | /**
3467 | * <p>Name of the user for webhdfs.</p>
3468 | */
3469 | public final String userName;
3470 |
3471 | @Override
3472 | public String scheme() {
3473 | return "webhdfs";
3474 | }
3475 |
3476 | @Override
3477 | public Map<String, String> configMap() {
3478 | final HashMap<String, String> map = new HashMap<>();
3479 | if (atomicWriteDir != null) {
3480 | map.put("atomic_write_dir", atomicWriteDir);
3481 | }
3482 | if (delegation != null) {
3483 | map.put("delegation", delegation);
3484 | }
3485 | if (disableListBatch != null) {
3486 | map.put("disable_list_batch", String.valueOf(disableListBatch));
3487 | }
3488 | if (endpoint != null) {
3489 | map.put("endpoint", endpoint);
3490 | }
3491 | if (root != null) {
3492 | map.put("root", root);
3493 | }
3494 | if (userName != null) {
3495 | map.put("user_name", userName);
3496 | }
3497 | return map;
3498 | }
3499 | }
3500 |
3501 | /**
3502 | * Configuration for service yandex_disk.
3503 | */
3504 | @Builder
3505 | @Data
3506 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
3507 | class YandexDisk implements ServiceConfig {
3508 | /**
3509 | * <p>yandex disk oauth access_token.</p>
3510 | */
3511 | public final @NonNull String accessToken;
3512 | /**
3513 | * <p>root of this backend.</p>
3514 | * <p>All operations will happen under this root.</p>
3515 | */
3516 | public final String root;
3517 |
3518 | @Override
3519 | public String scheme() {
3520 | return "yandex_disk";
3521 | }
3522 |
3523 | @Override
3524 | public Map<String, String> configMap() {
3525 | final HashMap<String, String> map = new HashMap<>();
3526 | map.put("access_token", accessToken);
3527 | if (root != null) {
3528 | map.put("root", root);
3529 | }
3530 | return map;
3531 | }
3532 | }
3533 | }
3534 |
```