{"id":31658387,"url":"https://github.com/couchbase/java-dcp-client","last_synced_at":"2025-10-07T15:21:13.660Z","repository":{"id":52522810,"uuid":"62625088","full_name":"couchbase/java-dcp-client","owner":"couchbase","description":"Couchbase Java DCP Client","archived":false,"fork":false,"pushed_at":"2025-08-13T20:39:05.000Z","size":2175,"stargazers_count":55,"open_issues_count":0,"forks_count":19,"subscribers_count":44,"default_branch":"master","last_synced_at":"2025-08-13T22:23:35.799Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/couchbase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.adoc","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-07-05T09:50:21.000Z","updated_at":"2025-08-13T20:39:09.000Z","dependencies_parsed_at":"2024-04-10T22:22:47.787Z","dependency_job_id":"c9bf4591-715f-438e-8b8a-b9852b84951c","html_url":"https://github.com/couchbase/java-dcp-client","commit_stats":null,"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"purl":"pkg:github/couchbase/java-dcp-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fjava-dcp-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fjava-dcp-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fjava-dcp-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fjava-dcp-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/couchbase","download_url":"https://codeload.github.com/couchbase/java-dcp-client/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fjava-dcp-client/sbom","scorecard":{"id":305922,"data":{"date":"2025-08-11","repo":{"name":"github.com/couchbase/java-dcp-client","commit":"662437cd512cca5210168d7f4355f28b7648e903"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.1,"checks":[{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":10,"reason":"14 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/deploy-snapshot.yml:24","Warn: no topLevel permission defined: .github/workflows/deploy-snapshot.yml:1","Warn: no topLevel permission defined: .github/workflows/run-tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy-snapshot.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/couchbase/java-dcp-client/deploy-snapshot.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy-snapshot.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/couchbase/java-dcp-client/deploy-snapshot.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/run-tests.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/couchbase/java-dcp-client/run-tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/run-tests.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/couchbase/java-dcp-client/run-tests.yml/master?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.14.0 not signed: https://api.github.com/repos/couchbase/java-dcp-client/releases/9727471","Warn: release artifact 0.13.0 not signed: https://api.github.com/repos/couchbase/java-dcp-client/releases/9337200","Warn: release artifact 0.12.0 not signed: https://api.github.com/repos/couchbase/java-dcp-client/releases/7610446","Warn: release artifact 0.14.0 does not have provenance: https://api.github.com/repos/couchbase/java-dcp-client/releases/9727471","Warn: release artifact 0.13.0 does not have provenance: https://api.github.com/repos/couchbase/java-dcp-client/releases/9337200","Warn: release artifact 0.12.0 does not have provenance: https://api.github.com/repos/couchbase/java-dcp-client/releases/7610446"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/deploy-snapshot.yml:21"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T22:02:41.910Z","repository_id":52522810,"created_at":"2025-08-17T22:02:41.910Z","updated_at":"2025-08-17T22:02:41.910Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278796327,"owners_count":26047407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-07T15:21:11.353Z","updated_at":"2025-10-07T15:21:13.650Z","avatar_url":"https://github.com/couchbase.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Couchbase Java DCP Client\n\nThis repository contains a pure Java implementation of a Couchbase Database Change Protocol (DCP) client.\n\n**Important:** The `java-dcp-client` is **not officially supported** by Couchbase directly. It is used as a fundamental building block for higher-level (supported) libraries like our Kafka and\nElasticsearch connectors. **Use at your own risk!**\n\n## Compatibility Notes\n\nVersions 0.27.0 through 0.35.0 inclusive are incompatible with Couchbase Server 7.0.2 and later (the client may fail to bootstrap or respond to server cluster topology changes).\nWe recommend all users upgrade to 0.36.0 or later.\n\n## Features\n\n- [x] Low overhead streaming\n- [x] Async from top to bottom\n- [x] Stream specific vbuckets\n- [x] Manual start/stop of streams\n- [x] Noop acknowledgements and dead connection detection\n- [x] Flow control\n- [x] Session management for restartability\n- [x] Rebalance support\n- [x] Export current session state for durability (ships with JSON)\n- [x] Start and restart from specific session state (import durable state)\n- [x] Pausing and restarts\n- [x] Stream up to a specific point in time for a vbucket and then stop\n- [x] Proper shutdown/disconnect and cleanup\n\n## Installation\n\nWe publish the releases (including pre-releases to maven central):\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.couchbase.client\u003c/groupId\u003e\n    \u003cartifactId\u003edcp-client\u003c/artifactId\u003e\n    \u003cversion\u003e${version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nCheck the [tags](https://github.com/couchbase/java-dcp-client/tags) to find the latest version.\n\nIf you want the bleeding edge, you can check\nout the project from github and build it on your own. It is a maven-based\nproject so simply run\n\n```\n$ git clone https://github.com/couchbase/java-dcp-client.git\n$ cd java-dcp-client\n$ mvn install\n```\n\nThis local build will install the `com.couchbase.client:dcp-client` artifact\nwith the next `SNAPSHOT` version. You can then depend on it in your\nproject.\n\n## Basic Usage\n\nThe simplest way is to initiate a stream against `localhost` and open\nall streams available. You always need to attach a callback for both the\nconfig and the data events - in the simplest case all the messages are\njust discarded. **It's important to release the buffers!**\n\nPlease check out the [examples](https://github.com/couchbase/java-dcp-client/tree/master/examples/src/main/java/com/couchbase/client/dcp/examples).\nWe recommend starting with the [HighLevelApi](https://github.com/couchbase/java-dcp-client/blob/master/examples/src/main/java/com/couchbase/client/dcp/examples/HighLevelApi.java) example.\n\nThe following example connects to the `travel-sample` bucket and prints\nout all subsequent mutations and deletions that occur.\n\n```java\n// Connect to localhost and use the travel-sample bucket\nfinal Client client = Client.configure()\n    .hostnames(\"localhost\")\n    .bucket(\"travel-sample\")\n    .build();\n\n// Don't do anything with control events in this example\nclient.controlEventHandler(new ControlEventHandler() {\n    @Override\n    public void onEvent(ChannelFlowController flowController, ByteBuf event) {\n        event.release();\n    }\n});\n\n// Print out Mutations and Deletions\nclient.dataEventHandler(new DataEventHandler() {\n    @Override\n    public void onEvent(ChannelFlowController flowController, ByteBuf event) {\n        if (DcpMutationMessage.is(event)) {\n            System.out.println(\"Mutation: \" + DcpMutationMessage.toString(event));\n            // You can print the content via DcpMutationMessage.content(event).toString(StandardCharsets.UTF_8);\n        } else if (DcpDeletionMessage.is(event)) {\n            System.out.println(\"Deletion: \" + DcpDeletionMessage.toString(event));\n        }\n        event.release();\n    }\n});\n\n// Connect the sockets\nclient.connect().await();\n\n// Initialize the state (start now, never stop)\nclient.initializeState(StreamFrom.NOW, StreamTo.INFINITY).await();\n\n// Start streaming on all partitions\nclient.startStreaming().await();\n\n// Sleep for some time to print the mutations\n// The printing happens on the IO threads!\nThread.sleep(TimeUnit.MINUTES.toMillis(10));\n\n// Once the time is over, shutdown.\nclient.disconnect().await();\n```\n\n### Dealing with Messages and ByteBufs\n\nTo save allocations the actual data you are interacting with are raw\nnetty `ByteBuf`s that may be pooled, depending on the configuration. So\nit is always important to `release()` them when not needed anymore.\n\nSince working with the raw buffers is not fun, the client provides\nflyweights that allow you to extract the information out of the buffers\neasily. Consult the docs for information on which message types to expect\nwhen, but as an example if you want to print the key and content of an\nincoming mutation in the data handler you can do it like this:\n\n```java\nif (DcpMutationMessage.is(event)) {\n    String key = DcpMutationMessage.keyString(event);\n    String content = DcpMutationMessage.content(event).toString(StandardCharsets.UTF_8);\n    System.out.println(\"Found Key \" + key + \" with Content \" + content);\n}\n```\n\n## Advanced Usage\n\n### Flow Control\n\nTo handle slow clients better and to make it possible that the client signals\nbackpressure to the server (that it should stop sending new data when the\nclient is busy processing the previous ones) flow control tuneables are\navailable.\n\nHandling flow control consist of two stages: first, you need to enable\nit during bootstrap and then acknowledge specific message types as soon\nas you are done processing them.\n\n#### Configuring Flow Control\n\nTo activate flow control, the `DcpControl.Names.CONNECTION_BUFFER_SIZE`\ncontrol param needs to be set to a value greater than zero. A reasonable\nstart value to test would be \"10240\" (10K).\n\nNext, you also need to set the `bufferAckWatermark` to a value which is\nequal or smaller than the connection buffer size. Every time a message\nis acknowledged the client accumulates up to the watermark and only if\nthe watermark is exceeded the acknowledgement is sent. This helps with\ncutting down on network traffic and to reduce the workload on the server\nside for accounting.\n\n#### Acknowledging Messages\n\nIf you do not acknowledge the bytes read for specific messages, the server\nwill stop streaming new messages when the `CONNECTION_BUFFER_SIZE` is\nreached.\n\nThe following messages need to be acknowledged by the user:\n\n- `DcpSnapshotMarkerRequest` (on the `ControlEventHandler`)\n- `DcpMutationMessage` (on the `DataEventHandler`)\n- `DcpDeletionMessage` (on the `DataEventHandler`)\n- `DcpExpirationMessage` (on the `DataEventHandler`)\n\nAcknowledging works by calling the `ChannelFlowController#ack` method.\n\nA simple way to do this is the following:\n\n```java\nflowController.ack(event);\n```\n\nThis method extracts the number of readable bytes out of it.\nWhen you already did consume the bytes and the reader index\nof the buffer is not the number of bytes orginally, you can fall back to\nthe lower level API:\n\n```java\nflowController.ack(numBytes);\n```\n\n### SSL (Couchbase Enterprise feature)\n\nRead in details about SSL in Couchbase on\n[our documentation](http://developer.couchbase.com/documentation/server/4.5/sdk/java/managing-connections.html).\nHere we will just post quick start steps:\n\n1. Download and store in file cluster certificate from \"Security\" -\u003e \"Root Certificate\" section on Admin Console.\n2. Import this certificate using keytool:\n\n        keytool -importcert -keystore /tmp/keystore \\\n                            -storepass secret \\\n                            -file /tmp/cluster.cert\n\n3. And update configuration of the DCP client:\n\n    ``` java\n    final Client client = Client.configure()\n            .hostnames(\"localhost\")\n            .bucket(\"travel-sample\")\n            .sslEnabled(true)\n            .sslKeystoreFile(\"/tmp/keystore\")\n            .sslKeystorePassword(\"secret\")\n            .build();\n    ```\n\n### System Events\n\nSince the 0.7.0 release, the client implements a notification service, which allows you to react on events, which are\nnot tied directly to protocol and data transmission. For example, connection errors, or notifications about stream\ncompletion when the end sequence number wasn't set to infinity. The following example subscribes a handler to system\nevents to find out when partition 42 is done with data transmission:\n\n``` java\nclient.systemEventHandler(new SystemEventHandler() {\n    @Override\n    public void onEvent(CouchbaseEvent event) {\n        if (event instanceof StreamEndEvent) {\n            StreamEndEvent streamEnd = (StreamEndEvent) event;\n            if (streamEnd.partition() == 42) {\n                System.out.println(\"Stream for partition 42 has ended (reason: \" + streamEnd.reason() + \")\");\n            }\n        }\n    }\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcouchbase%2Fjava-dcp-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcouchbase%2Fjava-dcp-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcouchbase%2Fjava-dcp-client/lists"}