This is page 53 of 55. Use http://codebase.md/apache/opendal?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
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// DO NOT EDIT IT MANUALLY. This file is generated by opendal/dev/generate/java.rs.
package org.apache.opendal;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
/**
* Service configurations that are mapped from
* <a href="https://docs.rs/opendal/latest/opendal/services/index.html">OpenDAL's services</a>.
*/
@SuppressWarnings("unused") // intended to be used by users
public interface ServiceConfig {
/**
* The scheme of the service.
*
* @return the scheme
*/
String scheme();
/**
* Convert the structured config to a type erased config map.
*
* @return the config map
*/
Map<String, String> configMap();
/**
* Configuration for service aliyun_drive.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class AliyunDrive implements ServiceConfig {
/**
* <p>The access_token of this backend.</p>
* <p>Solution for client-only purpose. #4733</p>
* <p>Required if no client_id, client_secret and refresh_token are provided.</p>
*/
public final String accessToken;
/**
* <p>The client_id of this backend.</p>
* <p>Required if no access_token is provided.</p>
*/
public final String clientId;
/**
* <p>The client_secret of this backend.</p>
* <p>Required if no access_token is provided.</p>
*/
public final String clientSecret;
/**
* <p>The drive_type of this backend.</p>
* <p>All operations will happen under this type of drive.</p>
* <p>Available values are <code>default</code>, <code>backup</code> and <code>resource</code>.</p>
* <p>Fallback to default if not set or no other drives can be found.</p>
*/
public final @NonNull String driveType;
/**
* <p>The refresh_token of this backend.</p>
* <p>Required if no access_token is provided.</p>
*/
public final String refreshToken;
/**
* <p>The Root of this backend.</p>
* <p>All operations will happen under this root.</p>
* <p>Default to <code>/</code> if not set.</p>
*/
public final String root;
@Override
public String scheme() {
return "aliyun_drive";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessToken != null) {
map.put("access_token", accessToken);
}
if (clientId != null) {
map.put("client_id", clientId);
}
if (clientSecret != null) {
map.put("client_secret", clientSecret);
}
map.put("drive_type", driveType);
if (refreshToken != null) {
map.put("refresh_token", refreshToken);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service alluxio.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Alluxio implements ServiceConfig {
/**
* <p>endpoint of this backend.</p>
* <p>Endpoint must be full uri, mostly like <code>http://127.0.0.1:39999</code>.</p>
*/
public final String endpoint;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
* <p>default to <code>/</code> if not set.</p>
*/
public final String root;
@Override
public String scheme() {
return "alluxio";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service azblob.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Azblob implements ServiceConfig {
/**
* <p>The account key of Azblob service backend.</p>
*/
public final String accountKey;
/**
* <p>The account name of Azblob service backend.</p>
*/
public final String accountName;
/**
* <p>The maximum batch operations of Azblob service backend.</p>
*/
public final Long batchMaxOperations;
/**
* <p>The container name of Azblob service backend.</p>
*/
public final @NonNull String container;
/**
* <p>The encryption algorithm of Azblob service backend.</p>
*/
public final String encryptionAlgorithm;
/**
* <p>The encryption key of Azblob service backend.</p>
*/
public final String encryptionKey;
/**
* <p>The encryption key sha256 of Azblob service backend.</p>
*/
public final String encryptionKeySha256;
/**
* <p>The endpoint of Azblob service backend.</p>
* <p>Endpoint must be full uri, e.g.</p>
* <ul>
* <li>Azblob: <code>https://accountname.blob.core.windows.net</code></li>
* <li>Azurite: <code>http://127.0.0.1:10000/devstoreaccount1</code></li>
* </ul>
*/
public final String endpoint;
/**
* <p>The root of Azblob service backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
/**
* <p>The sas token of Azblob service backend.</p>
*/
public final String sasToken;
@Override
public String scheme() {
return "azblob";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accountKey != null) {
map.put("account_key", accountKey);
}
if (accountName != null) {
map.put("account_name", accountName);
}
if (batchMaxOperations != null) {
map.put("batch_max_operations", String.valueOf(batchMaxOperations));
}
map.put("container", container);
if (encryptionAlgorithm != null) {
map.put("encryption_algorithm", encryptionAlgorithm);
}
if (encryptionKey != null) {
map.put("encryption_key", encryptionKey);
}
if (encryptionKeySha256 != null) {
map.put("encryption_key_sha256", encryptionKeySha256);
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (sasToken != null) {
map.put("sas_token", sasToken);
}
return map;
}
}
/**
* Configuration for service azdls.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Azdls implements ServiceConfig {
/**
* <p>Account key of this backend.</p>
* <ul>
* <li>required for shared_key authentication</li>
* </ul>
*/
public final String accountKey;
/**
* <p>Account name of this backend.</p>
*/
public final String accountName;
/**
* <p>authority_host
* The authority host of the service principal.</p>
* <ul>
* <li>required for client_credentials authentication</li>
* <li>default value: <code>https://login.microsoftonline.com</code></li>
* </ul>
*/
public final String authorityHost;
/**
* <p>client_id
* The client id of the service principal.</p>
* <ul>
* <li>required for client_credentials authentication</li>
* </ul>
*/
public final String clientId;
/**
* <p>client_secret
* The client secret of the service principal.</p>
* <ul>
* <li>required for client_credentials authentication</li>
* </ul>
*/
public final String clientSecret;
/**
* <p>Endpoint of this backend.</p>
*/
public final String endpoint;
/**
* <p>Filesystem name of this backend.</p>
*/
public final @NonNull String filesystem;
/**
* <p>Root of this backend.</p>
*/
public final String root;
/**
* <p>sas_token
* The shared access signature token.</p>
* <ul>
* <li>required for sas authentication</li>
* </ul>
*/
public final String sasToken;
/**
* <p>tenant_id
* The tenant id of the service principal.</p>
* <ul>
* <li>required for client_credentials authentication</li>
* </ul>
*/
public final String tenantId;
@Override
public String scheme() {
return "azdls";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accountKey != null) {
map.put("account_key", accountKey);
}
if (accountName != null) {
map.put("account_name", accountName);
}
if (authorityHost != null) {
map.put("authority_host", authorityHost);
}
if (clientId != null) {
map.put("client_id", clientId);
}
if (clientSecret != null) {
map.put("client_secret", clientSecret);
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
map.put("filesystem", filesystem);
if (root != null) {
map.put("root", root);
}
if (sasToken != null) {
map.put("sas_token", sasToken);
}
if (tenantId != null) {
map.put("tenant_id", tenantId);
}
return map;
}
}
/**
* Configuration for service azfile.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Azfile implements ServiceConfig {
/**
* <p>The account key for azfile.</p>
*/
public final String accountKey;
/**
* <p>The account name for azfile.</p>
*/
public final String accountName;
/**
* <p>The endpoint for azfile.</p>
*/
public final String endpoint;
/**
* <p>The root path for azfile.</p>
*/
public final String root;
/**
* <p>The sas token for azfile.</p>
*/
public final String sasToken;
/**
* <p>The share name for azfile.</p>
*/
public final @NonNull String shareName;
@Override
public String scheme() {
return "azfile";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accountKey != null) {
map.put("account_key", accountKey);
}
if (accountName != null) {
map.put("account_name", accountName);
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (sasToken != null) {
map.put("sas_token", sasToken);
}
map.put("share_name", shareName);
return map;
}
}
/**
* Configuration for service b2.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class B2 implements ServiceConfig {
/**
* <p>applicationKey of this backend.</p>
* <ul>
* <li>If application_key is set, we will take user's input first.</li>
* <li>If not, we will try to load it from environment.</li>
* </ul>
*/
public final String applicationKey;
/**
* <p>keyID of this backend.</p>
* <ul>
* <li>If application_key_id is set, we will take user's input first.</li>
* <li>If not, we will try to load it from environment.</li>
* </ul>
*/
public final String applicationKeyId;
/**
* <p>bucket of this backend.</p>
* <p>required.</p>
*/
public final @NonNull String bucket;
/**
* <p>bucket id of this backend.</p>
* <p>required.</p>
*/
public final @NonNull String bucketId;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
@Override
public String scheme() {
return "b2";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (applicationKey != null) {
map.put("application_key", applicationKey);
}
if (applicationKeyId != null) {
map.put("application_key_id", applicationKeyId);
}
map.put("bucket", bucket);
map.put("bucket_id", bucketId);
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service cacache.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Cacache implements ServiceConfig {
/**
* <p>That path to the cacache data directory.</p>
*/
public final String datadir;
@Override
public String scheme() {
return "cacache";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (datadir != null) {
map.put("datadir", datadir);
}
return map;
}
}
/**
* Configuration for service cloudflare_kv.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class CloudflareKv implements ServiceConfig {
/**
* <p>The account ID used to authenticate with CloudFlare. Used as URI path parameter.</p>
*/
public final String accountId;
/**
* <p>The token used to authenticate with CloudFlare.</p>
*/
public final String apiToken;
/**
* <p>The default ttl for write operations.</p>
*/
public final Duration defaultTtl;
/**
* <p>The namespace ID. Used as URI path parameter.</p>
*/
public final String namespaceId;
/**
* <p>Root within this backend.</p>
*/
public final String root;
@Override
public String scheme() {
return "cloudflare_kv";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accountId != null) {
map.put("account_id", accountId);
}
if (apiToken != null) {
map.put("api_token", apiToken);
}
if (defaultTtl != null) {
map.put("default_ttl", defaultTtl.toString());
}
if (namespaceId != null) {
map.put("namespace_id", namespaceId);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service compfs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Compfs implements ServiceConfig {
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
@Override
public String scheme() {
return "compfs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service cos.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Cos implements ServiceConfig {
/**
* <p>Bucket of this backend.</p>
*/
public final String bucket;
/**
* <p>Disable config load so that opendal will not load config from</p>
*/
public final Boolean disableConfigLoad;
/**
* <p>is bucket versioning enabled for this bucket</p>
*/
public final Boolean enableVersioning;
/**
* <p>Endpoint of this backend.</p>
*/
public final String endpoint;
/**
* <p>Root of this backend.</p>
*/
public final String root;
/**
* <p>Secret ID of this backend.</p>
*/
public final String secretId;
/**
* <p>Secret key of this backend.</p>
*/
public final String secretKey;
@Override
public String scheme() {
return "cos";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (bucket != null) {
map.put("bucket", bucket);
}
if (disableConfigLoad != null) {
map.put("disable_config_load", String.valueOf(disableConfigLoad));
}
if (enableVersioning != null) {
map.put("enable_versioning", String.valueOf(enableVersioning));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (secretId != null) {
map.put("secret_id", secretId);
}
if (secretKey != null) {
map.put("secret_key", secretKey);
}
return map;
}
}
/**
* Configuration for service d1.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class D1 implements ServiceConfig {
/**
* <p>Set the account id of cloudflare api.</p>
*/
public final String accountId;
/**
* <p>Set the database id of cloudflare api.</p>
*/
public final String databaseId;
/**
* <p>Set the key field of D1 Database.</p>
*/
public final String keyField;
/**
* <p>Set the working directory of OpenDAL.</p>
*/
public final String root;
/**
* <p>Set the table of D1 Database.</p>
*/
public final String table;
/**
* <p>Set the token of cloudflare api.</p>
*/
public final String token;
/**
* <p>Set the value field of D1 Database.</p>
*/
public final String valueField;
@Override
public String scheme() {
return "d1";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accountId != null) {
map.put("account_id", accountId);
}
if (databaseId != null) {
map.put("database_id", databaseId);
}
if (keyField != null) {
map.put("key_field", keyField);
}
if (root != null) {
map.put("root", root);
}
if (table != null) {
map.put("table", table);
}
if (token != null) {
map.put("token", token);
}
if (valueField != null) {
map.put("value_field", valueField);
}
return map;
}
}
/**
* Configuration for service dashmap.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Dashmap implements ServiceConfig {
/**
* <p>root path of this backend</p>
*/
public final String root;
@Override
public String scheme() {
return "dashmap";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service dbfs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Dbfs implements ServiceConfig {
/**
* <p>The endpoint for dbfs.</p>
*/
public final String endpoint;
/**
* <p>The root for dbfs.</p>
*/
public final String root;
/**
* <p>The token for dbfs.</p>
*/
public final String token;
@Override
public String scheme() {
return "dbfs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (token != null) {
map.put("token", token);
}
return map;
}
}
/**
* Configuration for service dropbox.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Dropbox implements ServiceConfig {
/**
* <p>access token for dropbox.</p>
*/
public final String accessToken;
/**
* <p>client_id for dropbox.</p>
*/
public final String clientId;
/**
* <p>client_secret for dropbox.</p>
*/
public final String clientSecret;
/**
* <p>refresh_token for dropbox.</p>
*/
public final String refreshToken;
/**
* <p>root path for dropbox.</p>
*/
public final String root;
@Override
public String scheme() {
return "dropbox";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessToken != null) {
map.put("access_token", accessToken);
}
if (clientId != null) {
map.put("client_id", clientId);
}
if (clientSecret != null) {
map.put("client_secret", clientSecret);
}
if (refreshToken != null) {
map.put("refresh_token", refreshToken);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service etcd.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Etcd implements ServiceConfig {
/**
* <p>certificate authority file path</p>
* <p>default is None</p>
*/
public final String caPath;
/**
* <p>cert path</p>
* <p>default is None</p>
*/
public final String certPath;
/**
* <p>network address of the Etcd services.
* If use https, must set TLS options: <code>ca_path</code>, <code>cert_path</code>, <code>key_path</code>.
* 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>
* <p>default is "http://127.0.0.1:2379"</p>
*/
public final String endpoints;
/**
* <p>key path</p>
* <p>default is None</p>
*/
public final String keyPath;
/**
* <p>the password for authentication</p>
* <p>default is None</p>
*/
public final String password;
/**
* <p>the working directory of the etcd service. Can be "/path/to/dir"</p>
* <p>default is "/"</p>
*/
public final String root;
/**
* <p>the username to connect etcd service.</p>
* <p>default is None</p>
*/
public final String username;
@Override
public String scheme() {
return "etcd";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (caPath != null) {
map.put("ca_path", caPath);
}
if (certPath != null) {
map.put("cert_path", certPath);
}
if (endpoints != null) {
map.put("endpoints", endpoints);
}
if (keyPath != null) {
map.put("key_path", keyPath);
}
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service fs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Fs implements ServiceConfig {
/**
* <p>tmp dir for atomic write</p>
*/
public final String atomicWriteDir;
/**
* <p>root dir for backend</p>
*/
public final String root;
@Override
public String scheme() {
return "fs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (atomicWriteDir != null) {
map.put("atomic_write_dir", atomicWriteDir);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service gcs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Gcs implements ServiceConfig {
/**
* <p>Allow opendal to send requests without signing when credentials are not
* loaded.</p>
*/
public final Boolean allowAnonymous;
/**
* <p>bucket name</p>
*/
public final @NonNull String bucket;
/**
* <p>Credentials string for GCS service OAuth2 authentication.</p>
*/
public final String credential;
/**
* <p>Local path to credentials file for GCS service OAuth2 authentication.</p>
*/
public final String credentialPath;
/**
* <p>The default storage class used by gcs.</p>
*/
public final String defaultStorageClass;
/**
* <p>Disable loading configuration from the environment.</p>
*/
public final Boolean disableConfigLoad;
/**
* <p>Disable attempting to load credentials from the GCE metadata server when
* running within Google Cloud.</p>
*/
public final Boolean disableVmMetadata;
/**
* <p>endpoint URI of GCS service,
* default is <code>https://storage.googleapis.com</code></p>
*/
public final String endpoint;
/**
* <p>The predefined acl for GCS.</p>
*/
public final String predefinedAcl;
/**
* <p>root URI, all operations happens under <code>root</code></p>
*/
public final String root;
/**
* <p>Scope for gcs.</p>
*/
public final String scope;
/**
* <p>Service Account for gcs.</p>
*/
public final String serviceAccount;
/**
* <p>A Google Cloud OAuth2 token.</p>
* <p>Takes precedence over <code>credential</code> and <code>credential_path</code>.</p>
*/
public final String token;
@Override
public String scheme() {
return "gcs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (allowAnonymous != null) {
map.put("allow_anonymous", String.valueOf(allowAnonymous));
}
map.put("bucket", bucket);
if (credential != null) {
map.put("credential", credential);
}
if (credentialPath != null) {
map.put("credential_path", credentialPath);
}
if (defaultStorageClass != null) {
map.put("default_storage_class", defaultStorageClass);
}
if (disableConfigLoad != null) {
map.put("disable_config_load", String.valueOf(disableConfigLoad));
}
if (disableVmMetadata != null) {
map.put("disable_vm_metadata", String.valueOf(disableVmMetadata));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (predefinedAcl != null) {
map.put("predefined_acl", predefinedAcl);
}
if (root != null) {
map.put("root", root);
}
if (scope != null) {
map.put("scope", scope);
}
if (serviceAccount != null) {
map.put("service_account", serviceAccount);
}
if (token != null) {
map.put("token", token);
}
return map;
}
}
/**
* Configuration for service gdrive.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Gdrive implements ServiceConfig {
/**
* <p>Access token for gdrive.</p>
*/
public final String accessToken;
/**
* <p>Client id for gdrive.</p>
*/
public final String clientId;
/**
* <p>Client secret for gdrive.</p>
*/
public final String clientSecret;
/**
* <p>Refresh token for gdrive.</p>
*/
public final String refreshToken;
/**
* <p>The root for gdrive</p>
*/
public final String root;
@Override
public String scheme() {
return "gdrive";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessToken != null) {
map.put("access_token", accessToken);
}
if (clientId != null) {
map.put("client_id", clientId);
}
if (clientSecret != null) {
map.put("client_secret", clientSecret);
}
if (refreshToken != null) {
map.put("refresh_token", refreshToken);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service ghac.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Ghac implements ServiceConfig {
/**
* <p>The endpoint for ghac service.</p>
*/
public final String endpoint;
/**
* <p>The root path for ghac.</p>
*/
public final String root;
/**
* <p>The runtime token for ghac service.</p>
*/
public final String runtimeToken;
/**
* <p>The version that used by cache.</p>
*/
public final String version;
@Override
public String scheme() {
return "ghac";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (runtimeToken != null) {
map.put("runtime_token", runtimeToken);
}
if (version != null) {
map.put("version", version);
}
return map;
}
}
/**
* Configuration for service github.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Github implements ServiceConfig {
/**
* <p>GitHub repo owner.</p>
* <p>required.</p>
*/
public final @NonNull String owner;
/**
* <p>GitHub repo name.</p>
* <p>required.</p>
*/
public final @NonNull String repo;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
/**
* <p>GitHub access_token.</p>
* <p>optional.
* If not provided, the backend will only support read operations for public repositories.
* And rate limit will be limited to 60 requests per hour.</p>
*/
public final String token;
@Override
public String scheme() {
return "github";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
map.put("owner", owner);
map.put("repo", repo);
if (root != null) {
map.put("root", root);
}
if (token != null) {
map.put("token", token);
}
return map;
}
}
/**
* Configuration for service gridfs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Gridfs implements ServiceConfig {
/**
* <p>The bucket name of the MongoDB GridFs service to read/write.</p>
*/
public final String bucket;
/**
* <p>The chunk size of the MongoDB GridFs service used to break the user file into chunks.</p>
*/
public final Integer chunkSize;
/**
* <p>The connection string of the MongoDB service.</p>
*/
public final String connectionString;
/**
* <p>The database name of the MongoDB GridFs service to read/write.</p>
*/
public final String database;
/**
* <p>The working directory, all operations will be performed under it.</p>
*/
public final String root;
@Override
public String scheme() {
return "gridfs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (bucket != null) {
map.put("bucket", bucket);
}
if (chunkSize != null) {
map.put("chunk_size", String.valueOf(chunkSize));
}
if (connectionString != null) {
map.put("connection_string", connectionString);
}
if (database != null) {
map.put("database", database);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service hdfs_native.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class HdfsNative implements ServiceConfig {
/**
* <p>enable the append capacity</p>
*/
public final Boolean enableAppend;
/**
* <p>name_node of this backend</p>
*/
public final String nameNode;
/**
* <p>work dir of this backend</p>
*/
public final String root;
@Override
public String scheme() {
return "hdfs_native";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (enableAppend != null) {
map.put("enable_append", String.valueOf(enableAppend));
}
if (nameNode != null) {
map.put("name_node", nameNode);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service http.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Http implements ServiceConfig {
/**
* <p>endpoint of this backend</p>
*/
public final String endpoint;
/**
* <p>password of this backend</p>
*/
public final String password;
/**
* <p>root of this backend</p>
*/
public final String root;
/**
* <p>token of this backend</p>
*/
public final String token;
/**
* <p>username of this backend</p>
*/
public final String username;
@Override
public String scheme() {
return "http";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
if (token != null) {
map.put("token", token);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service huggingface.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Huggingface implements ServiceConfig {
/**
* <p>Repo id of this backend.</p>
* <p>This is required.</p>
*/
public final String repoId;
/**
* <p>Repo type of this backend. Default is model.</p>
* <p>Available values:</p>
* <ul>
* <li>model</li>
* <li>dataset</li>
* </ul>
*/
public final String repoType;
/**
* <p>Revision of this backend.</p>
* <p>Default is main.</p>
*/
public final String revision;
/**
* <p>Root of this backend. Can be "/path/to/dir".</p>
* <p>Default is "/".</p>
*/
public final String root;
/**
* <p>Token of this backend.</p>
* <p>This is optional.</p>
*/
public final String token;
@Override
public String scheme() {
return "huggingface";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (repoId != null) {
map.put("repo_id", repoId);
}
if (repoType != null) {
map.put("repo_type", repoType);
}
if (revision != null) {
map.put("revision", revision);
}
if (root != null) {
map.put("root", root);
}
if (token != null) {
map.put("token", token);
}
return map;
}
}
/**
* Configuration for service ipfs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Ipfs implements ServiceConfig {
/**
* <p>IPFS gateway endpoint.</p>
*/
public final String endpoint;
/**
* <p>IPFS root.</p>
*/
public final String root;
@Override
public String scheme() {
return "ipfs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service ipmfs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Ipmfs implements ServiceConfig {
/**
* <p>Endpoint for ipfs.</p>
*/
public final String endpoint;
/**
* <p>Root for ipfs.</p>
*/
public final String root;
@Override
public String scheme() {
return "ipmfs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service koofr.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Koofr implements ServiceConfig {
/**
* <p>Koofr email.</p>
*/
public final @NonNull String email;
/**
* <p>Koofr endpoint.</p>
*/
public final @NonNull String endpoint;
/**
* <p>password of this backend. (Must be the application password)</p>
*/
public final String password;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
@Override
public String scheme() {
return "koofr";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
map.put("email", email);
map.put("endpoint", endpoint);
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service lakefs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Lakefs implements ServiceConfig {
/**
* <p>Name of the branch or a commit ID. Default is main.</p>
* <p>This is optional.</p>
*/
public final String branch;
/**
* <p>Base url.</p>
* <p>This is required.</p>
*/
public final String endpoint;
/**
* <p>Password for Lakefs basic authentication.</p>
* <p>This is required.</p>
*/
public final String password;
/**
* <p>The repository name</p>
* <p>This is required.</p>
*/
public final String repository;
/**
* <p>Root of this backend. Can be "/path/to/dir".</p>
* <p>Default is "/".</p>
*/
public final String root;
/**
* <p>Username for Lakefs basic authentication.</p>
* <p>This is required.</p>
*/
public final String username;
@Override
public String scheme() {
return "lakefs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (branch != null) {
map.put("branch", branch);
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (password != null) {
map.put("password", password);
}
if (repository != null) {
map.put("repository", repository);
}
if (root != null) {
map.put("root", root);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service memcached.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Memcached implements ServiceConfig {
/**
* <p>The maximum number of connections allowed.</p>
* <p>default is 10</p>
*/
public final Integer connectionPoolMaxSize;
/**
* <p>The default ttl for put operations.</p>
*/
public final Duration defaultTtl;
/**
* <p>network address of the memcached service.</p>
* <p>For example: "tcp://localhost:11211"</p>
*/
public final String endpoint;
/**
* <p>Memcached password, optional.</p>
*/
public final String password;
/**
* <p>the working directory of the service. Can be "/path/to/dir"</p>
* <p>default is "/"</p>
*/
public final String root;
/**
* <p>Memcached username, optional.</p>
*/
public final String username;
@Override
public String scheme() {
return "memcached";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (connectionPoolMaxSize != null) {
map.put("connection_pool_max_size", String.valueOf(connectionPoolMaxSize));
}
if (defaultTtl != null) {
map.put("default_ttl", defaultTtl.toString());
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service memory.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Memory implements ServiceConfig {
/**
* <p>root of the backend.</p>
*/
public final String root;
@Override
public String scheme() {
return "memory";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service mini_moka.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class MiniMoka implements ServiceConfig {
/**
* <p>Sets the max capacity of the cache.</p>
* <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>
*/
public final Long maxCapacity;
/**
* <p>root path of this backend</p>
*/
public final String root;
/**
* <p>Sets the time to idle of the cache.</p>
* <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>
*/
public final String timeToIdle;
/**
* <p>Sets the time to live of the cache.</p>
* <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>
*/
public final String timeToLive;
@Override
public String scheme() {
return "mini_moka";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (maxCapacity != null) {
map.put("max_capacity", String.valueOf(maxCapacity));
}
if (root != null) {
map.put("root", root);
}
if (timeToIdle != null) {
map.put("time_to_idle", timeToIdle);
}
if (timeToLive != null) {
map.put("time_to_live", timeToLive);
}
return map;
}
}
/**
* Configuration for service moka.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Moka implements ServiceConfig {
/**
* <p>Sets the max capacity of the cache.</p>
* <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>
*/
public final Long maxCapacity;
/**
* <p>Name for this cache instance.</p>
*/
public final String name;
/**
* <p>root path of this backend</p>
*/
public final String root;
/**
* <p>Sets the time to idle of the cache.</p>
* <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>
*/
public final String timeToIdle;
/**
* <p>Sets the time to live of the cache.</p>
* <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>
*/
public final String timeToLive;
@Override
public String scheme() {
return "moka";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (maxCapacity != null) {
map.put("max_capacity", String.valueOf(maxCapacity));
}
if (name != null) {
map.put("name", name);
}
if (root != null) {
map.put("root", root);
}
if (timeToIdle != null) {
map.put("time_to_idle", timeToIdle);
}
if (timeToLive != null) {
map.put("time_to_live", timeToLive);
}
return map;
}
}
/**
* Configuration for service mongodb.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Mongodb implements ServiceConfig {
/**
* <p>collection of this backend</p>
*/
public final String collection;
/**
* <p>connection string of this backend</p>
*/
public final String connectionString;
/**
* <p>database of this backend</p>
*/
public final String database;
/**
* <p>key field of this backend</p>
*/
public final String keyField;
/**
* <p>root of this backend</p>
*/
public final String root;
/**
* <p>value field of this backend</p>
*/
public final String valueField;
@Override
public String scheme() {
return "mongodb";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (collection != null) {
map.put("collection", collection);
}
if (connectionString != null) {
map.put("connection_string", connectionString);
}
if (database != null) {
map.put("database", database);
}
if (keyField != null) {
map.put("key_field", keyField);
}
if (root != null) {
map.put("root", root);
}
if (valueField != null) {
map.put("value_field", valueField);
}
return map;
}
}
/**
* Configuration for service monoiofs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Monoiofs implements ServiceConfig {
/**
* <p>The Root of this backend.</p>
* <p>All operations will happen under this root.</p>
* <p>Builder::build will return error if not set.</p>
*/
public final String root;
@Override
public String scheme() {
return "monoiofs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service mysql.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Mysql implements ServiceConfig {
/**
* <p>This connection string is used to connect to the mysql service. There are url based formats.</p>
* <p>The format of connect string resembles the url format of the mysql client.
* The format is: <code>[scheme://][user[:[password]]@]host[:port][/schema][?attribute1=value1&attribute2=value2...</code></p>
* <ul>
* <li><code>mysql://user@localhost</code></li>
* <li><code>mysql://user:password@localhost</code></li>
* <li><code>mysql://user:password@localhost:3306</code></li>
* <li><code>mysql://user:password@localhost:3306/db</code></li>
* </ul>
* <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>
*/
public final String connectionString;
/**
* <p>The key field name for mysql.</p>
*/
public final String keyField;
/**
* <p>The root for mysql.</p>
*/
public final String root;
/**
* <p>The table name for mysql.</p>
*/
public final String table;
/**
* <p>The value field name for mysql.</p>
*/
public final String valueField;
@Override
public String scheme() {
return "mysql";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (connectionString != null) {
map.put("connection_string", connectionString);
}
if (keyField != null) {
map.put("key_field", keyField);
}
if (root != null) {
map.put("root", root);
}
if (table != null) {
map.put("table", table);
}
if (valueField != null) {
map.put("value_field", valueField);
}
return map;
}
}
/**
* Configuration for service obs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Obs implements ServiceConfig {
/**
* <p>Access key id for obs.</p>
*/
public final String accessKeyId;
/**
* <p>Bucket for obs.</p>
*/
public final String bucket;
/**
* <p>Is bucket versioning enabled for this bucket</p>
*/
public final Boolean enableVersioning;
/**
* <p>Endpoint for obs.</p>
*/
public final String endpoint;
/**
* <p>Root for obs.</p>
*/
public final String root;
/**
* <p>Secret access key for obs.</p>
*/
public final String secretAccessKey;
@Override
public String scheme() {
return "obs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessKeyId != null) {
map.put("access_key_id", accessKeyId);
}
if (bucket != null) {
map.put("bucket", bucket);
}
if (enableVersioning != null) {
map.put("enable_versioning", String.valueOf(enableVersioning));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (secretAccessKey != null) {
map.put("secret_access_key", secretAccessKey);
}
return map;
}
}
/**
* Configuration for service onedrive.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Onedrive implements ServiceConfig {
/**
* <p>Microsoft Graph API (also OneDrive API) access token</p>
*/
public final String accessToken;
/**
* <p>Microsoft Graph API Application (client) ID that is in the Azure's app registration portal</p>
*/
public final String clientId;
/**
* <p>Microsoft Graph API Application client secret that is in the Azure's app registration portal</p>
*/
public final String clientSecret;
/**
* <p>Enabling version support</p>
*/
public final Boolean enableVersioning;
/**
* <p>Microsoft Graph API (also OneDrive API) refresh token</p>
*/
public final String refreshToken;
/**
* <p>The root path for the OneDrive service for the file access</p>
*/
public final String root;
@Override
public String scheme() {
return "onedrive";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessToken != null) {
map.put("access_token", accessToken);
}
if (clientId != null) {
map.put("client_id", clientId);
}
if (clientSecret != null) {
map.put("client_secret", clientSecret);
}
if (enableVersioning != null) {
map.put("enable_versioning", String.valueOf(enableVersioning));
}
if (refreshToken != null) {
map.put("refresh_token", refreshToken);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service opfs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Opfs implements ServiceConfig {
@Override
public String scheme() {
return "opfs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
return map;
}
}
/**
* Configuration for service oss.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Oss implements ServiceConfig {
/**
* <p>Access key id for oss.</p>
* <ul>
* <li>this field if it's <code>is_some</code></li>
* <li>env value: [<code>ALIBABA_CLOUD_ACCESS_KEY_ID</code>]</li>
* </ul>
*/
public final String accessKeyId;
/**
* <p>Access key secret for oss.</p>
* <ul>
* <li>this field if it's <code>is_some</code></li>
* <li>env value: [<code>ALIBABA_CLOUD_ACCESS_KEY_SECRET</code>]</li>
* </ul>
*/
public final String accessKeySecret;
/**
* <p>Addressing style for oss.</p>
*/
public final String addressingStyle;
/**
* <p>Allow anonymous for oss.</p>
*/
public final Boolean allowAnonymous;
/**
* <p>The size of max batch operations.</p>
*
* @deprecated Please use `delete_max_size` instead of `batch_max_operations`
*/
public final Long batchMaxOperations;
/**
* <p>Bucket for oss.</p>
*/
public final @NonNull String bucket;
/**
* <p>The size of max delete operations.</p>
*/
public final Long deleteMaxSize;
/**
* <p>is bucket versioning enabled for this bucket</p>
*/
public final Boolean enableVersioning;
/**
* <p>Endpoint for oss.</p>
*/
public final String endpoint;
/**
* <p><code>oidc_provider_arn</code> will be loaded from</p>
* <ul>
* <li>this field if it's <code>is_some</code></li>
* <li>env value: [<code>ALIBABA_CLOUD_OIDC_PROVIDER_ARN</code>]</li>
* </ul>
*/
public final String oidcProviderArn;
/**
* <p><code>oidc_token_file</code> will be loaded from</p>
* <ul>
* <li>this field if it's <code>is_some</code></li>
* <li>env value: [<code>ALIBABA_CLOUD_OIDC_TOKEN_FILE</code>]</li>
* </ul>
*/
public final String oidcTokenFile;
/**
* <p>Pre sign addressing style for oss.</p>
*/
public final String presignAddressingStyle;
/**
* <p>Presign endpoint for oss.</p>
*/
public final String presignEndpoint;
/**
* <p>If <code>role_arn</code> is set, we will use already known config as source
* credential to assume role with <code>role_arn</code>.</p>
* <ul>
* <li>this field if it's <code>is_some</code></li>
* <li>env value: [<code>ALIBABA_CLOUD_ROLE_ARN</code>]</li>
* </ul>
*/
public final String roleArn;
/**
* <p>role_session_name for this backend.</p>
*/
public final String roleSessionName;
/**
* <p>Root for oss.</p>
*/
public final String root;
/**
* <p><code>security_token</code> will be loaded from</p>
* <ul>
* <li>this field if it's <code>is_some</code></li>
* <li>env value: [<code>ALIBABA_CLOUD_SECURITY_TOKEN</code>]</li>
* </ul>
*/
public final String securityToken;
/**
* <p>Server side encryption for oss.</p>
*/
public final String serverSideEncryption;
/**
* <p>Server side encryption key id for oss.</p>
*/
public final String serverSideEncryptionKeyId;
/**
* <p><code>sts_endpoint</code> will be loaded from</p>
* <ul>
* <li>this field if it's <code>is_some</code></li>
* <li>env value: [<code>ALIBABA_CLOUD_STS_ENDPOINT</code>]</li>
* </ul>
*/
public final String stsEndpoint;
@Override
public String scheme() {
return "oss";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessKeyId != null) {
map.put("access_key_id", accessKeyId);
}
if (accessKeySecret != null) {
map.put("access_key_secret", accessKeySecret);
}
if (addressingStyle != null) {
map.put("addressing_style", addressingStyle);
}
if (allowAnonymous != null) {
map.put("allow_anonymous", String.valueOf(allowAnonymous));
}
if (batchMaxOperations != null) {
map.put("batch_max_operations", String.valueOf(batchMaxOperations));
}
map.put("bucket", bucket);
if (deleteMaxSize != null) {
map.put("delete_max_size", String.valueOf(deleteMaxSize));
}
if (enableVersioning != null) {
map.put("enable_versioning", String.valueOf(enableVersioning));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (oidcProviderArn != null) {
map.put("oidc_provider_arn", oidcProviderArn);
}
if (oidcTokenFile != null) {
map.put("oidc_token_file", oidcTokenFile);
}
if (presignAddressingStyle != null) {
map.put("presign_addressing_style", presignAddressingStyle);
}
if (presignEndpoint != null) {
map.put("presign_endpoint", presignEndpoint);
}
if (roleArn != null) {
map.put("role_arn", roleArn);
}
if (roleSessionName != null) {
map.put("role_session_name", roleSessionName);
}
if (root != null) {
map.put("root", root);
}
if (securityToken != null) {
map.put("security_token", securityToken);
}
if (serverSideEncryption != null) {
map.put("server_side_encryption", serverSideEncryption);
}
if (serverSideEncryptionKeyId != null) {
map.put("server_side_encryption_key_id", serverSideEncryptionKeyId);
}
if (stsEndpoint != null) {
map.put("sts_endpoint", stsEndpoint);
}
return map;
}
}
/**
* Configuration for service pcloud.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Pcloud implements ServiceConfig {
/**
* <p>pCloud endpoint address.</p>
*/
public final @NonNull String endpoint;
/**
* <p>pCloud password.</p>
*/
public final String password;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
/**
* <p>pCloud username.</p>
*/
public final String username;
@Override
public String scheme() {
return "pcloud";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
map.put("endpoint", endpoint);
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service persy.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Persy implements ServiceConfig {
/**
* <p>That path to the persy data file. The directory in the path must already exist.</p>
*/
public final String datafile;
/**
* <p>That name of the persy index.</p>
*/
public final String index;
/**
* <p>That name of the persy segment.</p>
*/
public final String segment;
@Override
public String scheme() {
return "persy";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (datafile != null) {
map.put("datafile", datafile);
}
if (index != null) {
map.put("index", index);
}
if (segment != null) {
map.put("segment", segment);
}
return map;
}
}
/**
* Configuration for service postgresql.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Postgresql implements ServiceConfig {
/**
* <p>The URL should be with a scheme of either <code>postgres://</code> or <code>postgresql://</code>.</p>
* <ul>
* <li><code>postgresql://user@localhost</code></li>
* <li><code>postgresql://user:password@%2Fvar%2Flib%2Fpostgresql/mydb?connect_timeout=10</code></li>
* <li><code>postgresql://user@host1:1234,host2,host3:5678?target_session_attrs=read-write</code></li>
* <li><code>postgresql:///mydb?user=user&host=/var/lib/postgresql</code></li>
* </ul>
* <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>
*/
public final String connectionString;
/**
* <p>the key field of postgresql</p>
*/
public final String keyField;
/**
* <p>Root of this backend.</p>
* <p>All operations will happen under this root.</p>
* <p>Default to <code>/</code> if not set.</p>
*/
public final String root;
/**
* <p>the table of postgresql</p>
*/
public final String table;
/**
* <p>the value field of postgresql</p>
*/
public final String valueField;
@Override
public String scheme() {
return "postgresql";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (connectionString != null) {
map.put("connection_string", connectionString);
}
if (keyField != null) {
map.put("key_field", keyField);
}
if (root != null) {
map.put("root", root);
}
if (table != null) {
map.put("table", table);
}
if (valueField != null) {
map.put("value_field", valueField);
}
return map;
}
}
/**
* Configuration for service redb.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Redb implements ServiceConfig {
/**
* <p>path to the redb data directory.</p>
*/
public final String datadir;
/**
* <p>The root for redb.</p>
*/
public final String root;
/**
* <p>The table name for redb.</p>
*/
public final String table;
@Override
public String scheme() {
return "redb";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (datadir != null) {
map.put("datadir", datadir);
}
if (root != null) {
map.put("root", root);
}
if (table != null) {
map.put("table", table);
}
return map;
}
}
/**
* Configuration for service redis.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Redis implements ServiceConfig {
/**
* <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>
* <p>default is None</p>
*/
public final String clusterEndpoints;
/**
* <p>The maximum number of connections allowed.</p>
* <p>default is 10</p>
*/
public final Integer connectionPoolMaxSize;
/**
* <p>the number of DBs redis can take is unlimited</p>
* <p>default is db 0</p>
*/
public final long db;
/**
* <p>The default ttl for put operations.</p>
*/
public final Duration defaultTtl;
/**
* <p>network address of the Redis service. Can be "tcp://127.0.0.1:6379", e.g.</p>
* <p>default is "tcp://127.0.0.1:6379"</p>
*/
public final String endpoint;
/**
* <p>the password for authentication</p>
* <p>default is None</p>
*/
public final String password;
/**
* <p>the working directory of the Redis service. Can be "/path/to/dir"</p>
* <p>default is "/"</p>
*/
public final String root;
/**
* <p>the username to connect redis service.</p>
* <p>default is None</p>
*/
public final String username;
@Override
public String scheme() {
return "redis";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (clusterEndpoints != null) {
map.put("cluster_endpoints", clusterEndpoints);
}
if (connectionPoolMaxSize != null) {
map.put("connection_pool_max_size", String.valueOf(connectionPoolMaxSize));
}
map.put("db", String.valueOf(db));
if (defaultTtl != null) {
map.put("default_ttl", defaultTtl.toString());
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service s3.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class S3 implements ServiceConfig {
/**
* <p>access_key_id of this backend.</p>
* <ul>
* <li>If access_key_id is set, we will take user's input first.</li>
* <li>If not, we will try to load it from environment.</li>
* </ul>
*/
public final String accessKeyId;
/**
* <p>Allow anonymous will allow opendal to send request without signing
* when credential is not loaded.</p>
*/
public final Boolean allowAnonymous;
/**
* <p>Set maximum batch operations of this backend.</p>
* <p>Some compatible services have a limit on the number of operations in a batch request.
* For example, R2 could return <code>Internal Error</code> while batch delete 1000 files.</p>
* <p>Please tune this value based on services' document.</p>
*
* @deprecated Please use `delete_max_size` instead of `batch_max_operations`
*/
public final Long batchMaxOperations;
/**
* <p>bucket name of this backend.</p>
* <p>required.</p>
*/
public final @NonNull String bucket;
/**
* <p>Checksum Algorithm to use when sending checksums in HTTP headers.
* This is necessary when writing to AWS S3 Buckets with Object Lock enabled for example.</p>
* <p>Available options:</p>
* <ul>
* <li>"crc32c"</li>
* </ul>
*/
public final String checksumAlgorithm;
/**
* <p>default storage_class for this backend.</p>
* <p>Available values:</p>
* <ul>
* <li><code>DEEP_ARCHIVE</code></li>
* <li><code>GLACIER</code></li>
* <li><code>GLACIER_IR</code></li>
* <li><code>INTELLIGENT_TIERING</code></li>
* <li><code>ONEZONE_IA</code></li>
* <li><code>EXPRESS_ONEZONE</code></li>
* <li><code>OUTPOSTS</code></li>
* <li><code>REDUCED_REDUNDANCY</code></li>
* <li><code>STANDARD</code></li>
* <li><code>STANDARD_IA</code></li>
* </ul>
* <p>S3 compatible services don't support all of them</p>
*/
public final String defaultStorageClass;
/**
* <p>Set the maximum delete size of this backend.</p>
* <p>Some compatible services have a limit on the number of operations in a batch request.
* For example, R2 could return <code>Internal Error</code> while batch delete 1000 files.</p>
* <p>Please tune this value based on services' document.</p>
*/
public final Long deleteMaxSize;
/**
* <p>Disable config load so that opendal will not load config from
* environment.</p>
* <p>For examples:</p>
* <ul>
* <li>envs like <code>AWS_ACCESS_KEY_ID</code></li>
* <li>files like <code>~/.aws/config</code></li>
* </ul>
*/
public final Boolean disableConfigLoad;
/**
* <p>Disable load credential from ec2 metadata.</p>
* <p>This option is used to disable the default behavior of opendal
* to load credential from ec2 metadata, a.k.a, IMDSv2</p>
*/
public final Boolean disableEc2Metadata;
/**
* <p>OpenDAL uses List Objects V2 by default to list objects.
* However, some legacy services do not yet support V2.
* This option allows users to switch back to the older List Objects V1.</p>
*/
public final Boolean disableListObjectsV2;
/**
* <p>Disable stat with override so that opendal will not send stat request with override queries.</p>
* <p>For example, R2 doesn't support stat with <code>response_content_type</code> query.</p>
*/
public final Boolean disableStatWithOverride;
/**
* <p>Disable write with if match so that opendal will not send write request with if match headers.</p>
* <p>For example, Ceph RADOS S3 doesn't support write with if match.</p>
*/
public final Boolean disableWriteWithIfMatch;
/**
* <p>Indicates whether the client agrees to pay for the requests made to the S3 bucket.</p>
*/
public final Boolean enableRequestPayer;
/**
* <p>is bucket versioning enabled for this bucket</p>
*/
public final Boolean enableVersioning;
/**
* <p>Enable virtual host style so that opendal will send API requests
* in virtual host style instead of path style.</p>
* <ul>
* <li>By default, opendal will send API to <code>https://s3.us-east-1.amazonaws.com/bucket_name</code></li>
* <li>Enabled, opendal will send API to <code>https://bucket_name.s3.us-east-1.amazonaws.com</code></li>
* </ul>
*/
public final Boolean enableVirtualHostStyle;
/**
* <p>Enable write with append so that opendal will send write request with append headers.</p>
*/
public final Boolean enableWriteWithAppend;
/**
* <p>endpoint of this backend.</p>
* <p>Endpoint must be full uri, e.g.</p>
* <ul>
* <li>AWS S3: <code>https://s3.amazonaws.com</code> or <code>https://s3.{region}.amazonaws.com</code></li>
* <li>Cloudflare R2: <code>https://<ACCOUNT_ID>.r2.cloudflarestorage.com</code></li>
* <li>Aliyun OSS: <code>https://{region}.aliyuncs.com</code></li>
* <li>Tencent COS: <code>https://cos.{region}.myqcloud.com</code></li>
* <li>Minio: <code>http://127.0.0.1:9000</code></li>
* </ul>
* <p>If user inputs endpoint without scheme like "s3.amazonaws.com", we
* will prepend "https://" before it.</p>
* <ul>
* <li>If endpoint is set, we will take user's input first.</li>
* <li>If not, we will try to load it from environment.</li>
* <li>If still not set, default to <code>https://s3.amazonaws.com</code>.</li>
* </ul>
*/
public final String endpoint;
/**
* <p>external_id for this backend.</p>
*/
public final String externalId;
/**
* <p>Region represent the signing region of this endpoint. This is required
* if you are using the default AWS S3 endpoint.</p>
* <p>If using a custom endpoint,</p>
* <ul>
* <li>If region is set, we will take user's input first.</li>
* <li>If not, we will try to load it from environment.</li>
* </ul>
*/
public final String region;
/**
* <p>role_arn for this backend.</p>
* <p>If <code>role_arn</code> is set, we will use already known config as source
* credential to assume role with <code>role_arn</code>.</p>
*/
public final String roleArn;
/**
* <p>role_session_name for this backend.</p>
*/
public final String roleSessionName;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
* <p>default to <code>/</code> if not set.</p>
*/
public final String root;
/**
* <p>secret_access_key of this backend.</p>
* <ul>
* <li>If secret_access_key is set, we will take user's input first.</li>
* <li>If not, we will try to load it from environment.</li>
* </ul>
*/
public final String secretAccessKey;
/**
* <p>server_side_encryption for this backend.</p>
* <p>Available values: <code>AES256</code>, <code>aws:kms</code>.</p>
*/
public final String serverSideEncryption;
/**
* <p>server_side_encryption_aws_kms_key_id for this backend</p>
* <ul>
* <li>If <code>server_side_encryption</code> set to <code>aws:kms</code>, and <code>server_side_encryption_aws_kms_key_id</code>
* is not set, S3 will use aws managed kms key to encrypt data.</li>
* <li>If <code>server_side_encryption</code> set to <code>aws:kms</code>, and <code>server_side_encryption_aws_kms_key_id</code>
* is a valid kms key id, S3 will use the provided kms key to encrypt data.</li>
* <li>If the <code>server_side_encryption_aws_kms_key_id</code> is invalid or not found, an error will be
* returned.</li>
* <li>If <code>server_side_encryption</code> is not <code>aws:kms</code>, setting <code>server_side_encryption_aws_kms_key_id</code>
* is a noop.</li>
* </ul>
*/
public final String serverSideEncryptionAwsKmsKeyId;
/**
* <p>server_side_encryption_customer_algorithm for this backend.</p>
* <p>Available values: <code>AES256</code>.</p>
*/
public final String serverSideEncryptionCustomerAlgorithm;
/**
* <p>server_side_encryption_customer_key for this backend.</p>
* <p>Value: BASE64-encoded key that matches algorithm specified in
* <code>server_side_encryption_customer_algorithm</code>.</p>
*/
public final String serverSideEncryptionCustomerKey;
/**
* <p>Set server_side_encryption_customer_key_md5 for this backend.</p>
* <p>Value: MD5 digest of key specified in <code>server_side_encryption_customer_key</code>.</p>
*/
public final String serverSideEncryptionCustomerKeyMd5;
/**
* <p>session_token (aka, security token) of this backend.</p>
* <p>This token will expire after sometime, it's recommended to set session_token
* by hand.</p>
*/
public final String sessionToken;
@Override
public String scheme() {
return "s3";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessKeyId != null) {
map.put("access_key_id", accessKeyId);
}
if (allowAnonymous != null) {
map.put("allow_anonymous", String.valueOf(allowAnonymous));
}
if (batchMaxOperations != null) {
map.put("batch_max_operations", String.valueOf(batchMaxOperations));
}
map.put("bucket", bucket);
if (checksumAlgorithm != null) {
map.put("checksum_algorithm", checksumAlgorithm);
}
if (defaultStorageClass != null) {
map.put("default_storage_class", defaultStorageClass);
}
if (deleteMaxSize != null) {
map.put("delete_max_size", String.valueOf(deleteMaxSize));
}
if (disableConfigLoad != null) {
map.put("disable_config_load", String.valueOf(disableConfigLoad));
}
if (disableEc2Metadata != null) {
map.put("disable_ec2_metadata", String.valueOf(disableEc2Metadata));
}
if (disableListObjectsV2 != null) {
map.put("disable_list_objects_v2", String.valueOf(disableListObjectsV2));
}
if (disableStatWithOverride != null) {
map.put("disable_stat_with_override", String.valueOf(disableStatWithOverride));
}
if (disableWriteWithIfMatch != null) {
map.put("disable_write_with_if_match", String.valueOf(disableWriteWithIfMatch));
}
if (enableRequestPayer != null) {
map.put("enable_request_payer", String.valueOf(enableRequestPayer));
}
if (enableVersioning != null) {
map.put("enable_versioning", String.valueOf(enableVersioning));
}
if (enableVirtualHostStyle != null) {
map.put("enable_virtual_host_style", String.valueOf(enableVirtualHostStyle));
}
if (enableWriteWithAppend != null) {
map.put("enable_write_with_append", String.valueOf(enableWriteWithAppend));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (externalId != null) {
map.put("external_id", externalId);
}
if (region != null) {
map.put("region", region);
}
if (roleArn != null) {
map.put("role_arn", roleArn);
}
if (roleSessionName != null) {
map.put("role_session_name", roleSessionName);
}
if (root != null) {
map.put("root", root);
}
if (secretAccessKey != null) {
map.put("secret_access_key", secretAccessKey);
}
if (serverSideEncryption != null) {
map.put("server_side_encryption", serverSideEncryption);
}
if (serverSideEncryptionAwsKmsKeyId != null) {
map.put("server_side_encryption_aws_kms_key_id", serverSideEncryptionAwsKmsKeyId);
}
if (serverSideEncryptionCustomerAlgorithm != null) {
map.put("server_side_encryption_customer_algorithm", serverSideEncryptionCustomerAlgorithm);
}
if (serverSideEncryptionCustomerKey != null) {
map.put("server_side_encryption_customer_key", serverSideEncryptionCustomerKey);
}
if (serverSideEncryptionCustomerKeyMd5 != null) {
map.put("server_side_encryption_customer_key_md5", serverSideEncryptionCustomerKeyMd5);
}
if (sessionToken != null) {
map.put("session_token", sessionToken);
}
return map;
}
}
/**
* Configuration for service seafile.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Seafile implements ServiceConfig {
/**
* <p>endpoint address of this backend.</p>
*/
public final String endpoint;
/**
* <p>password of this backend.</p>
*/
public final String password;
/**
* <p>repo_name of this backend.</p>
* <p>required.</p>
*/
public final @NonNull String repoName;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
/**
* <p>username of this backend.</p>
*/
public final String username;
@Override
public String scheme() {
return "seafile";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (password != null) {
map.put("password", password);
}
map.put("repo_name", repoName);
if (root != null) {
map.put("root", root);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service sftp.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Sftp implements ServiceConfig {
/**
* <p>enable_copy of this backend</p>
*/
public final Boolean enableCopy;
/**
* <p>endpoint of this backend</p>
*/
public final String endpoint;
/**
* <p>key of this backend</p>
*/
public final String key;
/**
* <p>known_hosts_strategy of this backend</p>
*/
public final String knownHostsStrategy;
/**
* <p>root of this backend</p>
*/
public final String root;
/**
* <p>user of this backend</p>
*/
public final String user;
@Override
public String scheme() {
return "sftp";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (enableCopy != null) {
map.put("enable_copy", String.valueOf(enableCopy));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (key != null) {
map.put("key", key);
}
if (knownHostsStrategy != null) {
map.put("known_hosts_strategy", knownHostsStrategy);
}
if (root != null) {
map.put("root", root);
}
if (user != null) {
map.put("user", user);
}
return map;
}
}
/**
* Configuration for service sled.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Sled implements ServiceConfig {
/**
* <p>That path to the sled data directory.</p>
*/
public final String datadir;
/**
* <p>The root for sled.</p>
*/
public final String root;
/**
* <p>The tree for sled.</p>
*/
public final String tree;
@Override
public String scheme() {
return "sled";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (datadir != null) {
map.put("datadir", datadir);
}
if (root != null) {
map.put("root", root);
}
if (tree != null) {
map.put("tree", tree);
}
return map;
}
}
/**
* Configuration for service sqlite.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Sqlite implements ServiceConfig {
/**
* <p>Set the connection_string of the sqlite service.</p>
* <p>This connection string is used to connect to the sqlite service.</p>
* <p>The format of connect string resembles the url format of the sqlite client:</p>
* <ul>
* <li><code>sqlite::memory:</code></li>
* <li><code>sqlite:data.db</code></li>
* <li><code>sqlite://data.db</code></li>
* </ul>
* <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>
*/
public final String connectionString;
/**
* <p>Set the key field name of the sqlite service to read/write.</p>
* <p>Default to <code>key</code> if not specified.</p>
*/
public final String keyField;
/**
* <p>set the working directory, all operations will be performed under it.</p>
* <p>default: "/"</p>
*/
public final String root;
/**
* <p>Set the table name of the sqlite service to read/write.</p>
*/
public final String table;
/**
* <p>Set the value field name of the sqlite service to read/write.</p>
* <p>Default to <code>value</code> if not specified.</p>
*/
public final String valueField;
@Override
public String scheme() {
return "sqlite";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (connectionString != null) {
map.put("connection_string", connectionString);
}
if (keyField != null) {
map.put("key_field", keyField);
}
if (root != null) {
map.put("root", root);
}
if (table != null) {
map.put("table", table);
}
if (valueField != null) {
map.put("value_field", valueField);
}
return map;
}
}
/**
* Configuration for service surrealdb.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Surrealdb implements ServiceConfig {
/**
* <p>The connection string for surrealdb.</p>
*/
public final String connectionString;
/**
* <p>The database for surrealdb.</p>
*/
public final String database;
/**
* <p>The key field for surrealdb.</p>
*/
public final String keyField;
/**
* <p>The namespace for surrealdb.</p>
*/
public final String namespace;
/**
* <p>The password for surrealdb.</p>
*/
public final String password;
/**
* <p>The root for surrealdb.</p>
*/
public final String root;
/**
* <p>The table for surrealdb.</p>
*/
public final String table;
/**
* <p>The username for surrealdb.</p>
*/
public final String username;
/**
* <p>The value field for surrealdb.</p>
*/
public final String valueField;
@Override
public String scheme() {
return "surrealdb";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (connectionString != null) {
map.put("connection_string", connectionString);
}
if (database != null) {
map.put("database", database);
}
if (keyField != null) {
map.put("key_field", keyField);
}
if (namespace != null) {
map.put("namespace", namespace);
}
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
if (table != null) {
map.put("table", table);
}
if (username != null) {
map.put("username", username);
}
if (valueField != null) {
map.put("value_field", valueField);
}
return map;
}
}
/**
* Configuration for service swift.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Swift implements ServiceConfig {
/**
* <p>The container for Swift.</p>
*/
public final String container;
/**
* <p>The endpoint for Swift.</p>
*/
public final String endpoint;
/**
* <p>The root for Swift.</p>
*/
public final String root;
/**
* <p>The token for Swift.</p>
*/
public final String token;
@Override
public String scheme() {
return "swift";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (container != null) {
map.put("container", container);
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (token != null) {
map.put("token", token);
}
return map;
}
}
/**
* Configuration for service upyun.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Upyun implements ServiceConfig {
/**
* <p>bucket address of this backend.</p>
*/
public final @NonNull String bucket;
/**
* <p>username of this backend.</p>
*/
public final String operator;
/**
* <p>password of this backend.</p>
*/
public final String password;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
@Override
public String scheme() {
return "upyun";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
map.put("bucket", bucket);
if (operator != null) {
map.put("operator", operator);
}
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
return map;
}
}
/**
* Configuration for service vercel_artifacts.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class VercelArtifacts implements ServiceConfig {
/**
* <p>The access token for Vercel.</p>
*/
public final String accessToken;
@Override
public String scheme() {
return "vercel_artifacts";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (accessToken != null) {
map.put("access_token", accessToken);
}
return map;
}
}
/**
* Configuration for service vercel_blob.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class VercelBlob implements ServiceConfig {
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
/**
* <p>vercel blob token.</p>
*/
public final String token;
@Override
public String scheme() {
return "vercel_blob";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (root != null) {
map.put("root", root);
}
if (token != null) {
map.put("token", token);
}
return map;
}
}
/**
* Configuration for service webdav.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Webdav implements ServiceConfig {
/**
* <p>WebDAV Service doesn't support copy.</p>
*/
public final Boolean disableCopy;
/**
* <p>endpoint of this backend</p>
*/
public final String endpoint;
/**
* <p>password of this backend</p>
*/
public final String password;
/**
* <p>root of this backend</p>
*/
public final String root;
/**
* <p>token of this backend</p>
*/
public final String token;
/**
* <p>username of this backend</p>
*/
public final String username;
@Override
public String scheme() {
return "webdav";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (disableCopy != null) {
map.put("disable_copy", String.valueOf(disableCopy));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (password != null) {
map.put("password", password);
}
if (root != null) {
map.put("root", root);
}
if (token != null) {
map.put("token", token);
}
if (username != null) {
map.put("username", username);
}
return map;
}
}
/**
* Configuration for service webhdfs.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Webhdfs implements ServiceConfig {
/**
* <p>atomic_write_dir of this backend</p>
*/
public final String atomicWriteDir;
/**
* <p>Delegation token for webhdfs.</p>
*/
public final String delegation;
/**
* <p>Disable batch listing</p>
*/
public final Boolean disableListBatch;
/**
* <p>Endpoint for webhdfs.</p>
*/
public final String endpoint;
/**
* <p>Root for webhdfs.</p>
*/
public final String root;
/**
* <p>Name of the user for webhdfs.</p>
*/
public final String userName;
@Override
public String scheme() {
return "webhdfs";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
if (atomicWriteDir != null) {
map.put("atomic_write_dir", atomicWriteDir);
}
if (delegation != null) {
map.put("delegation", delegation);
}
if (disableListBatch != null) {
map.put("disable_list_batch", String.valueOf(disableListBatch));
}
if (endpoint != null) {
map.put("endpoint", endpoint);
}
if (root != null) {
map.put("root", root);
}
if (userName != null) {
map.put("user_name", userName);
}
return map;
}
}
/**
* Configuration for service yandex_disk.
*/
@Builder
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class YandexDisk implements ServiceConfig {
/**
* <p>yandex disk oauth access_token.</p>
*/
public final @NonNull String accessToken;
/**
* <p>root of this backend.</p>
* <p>All operations will happen under this root.</p>
*/
public final String root;
@Override
public String scheme() {
return "yandex_disk";
}
@Override
public Map<String, String> configMap() {
final HashMap<String, String> map = new HashMap<>();
map.put("access_token", accessToken);
if (root != null) {
map.put("root", root);
}
return map;
}
}
}
```