diff --git a/.github/workflows/review-requested.yml b/.github/workflows/review-requested.yml index 94523bc..4f7e0a5 100644 --- a/.github/workflows/review-requested.yml +++ b/.github/workflows/review-requested.yml @@ -2,12 +2,23 @@ name: Review Requested on: pull_request: + types: [review_requested] paths: # the following should match `path:` declaration below - example/** jobs: + diag: + runs-on: ubuntu-latest + steps: + - name: reviewer + run: | + echo REVIEWER $REVIEWER + env: + REVIEWER: ${{ github.event.requested_reviewer.login }} + vale: + if: github.event.requested_reviewer.login == 'tech-comm-team-couchbase' uses: couchbaselabs/docs-runner/.github/workflows/vale-review.yml@main with: path: example diff --git a/example/modules/ROOT/pages/cbl-android-p2p.adoc b/example/modules/ROOT/pages/cbl-android-p2p.adoc new file mode 100644 index 0000000..134ef70 --- /dev/null +++ b/example/modules/ROOT/pages/cbl-android-p2p.adoc @@ -0,0 +1,350 @@ += Integrate a Custom Built Listener +:page-aliases: learn/java-android-p2psync-custom.adoc +ifdef::show_edition[:page-edition: Enterprise Edition] +:page-role: +:description: Couchbase Lite database peer-to-peer sync- integrate a custom built listener + + +:source-language: Java + + +:source-language: Kotlin + + +// :param-name: kotlin +// :param-title: Android +// :param-module: android + + +[abstract] +-- +Description -- _{description}_ + +Related Content -- https://docs.couchbase.com/mobile/{major}.{minor}.{maintenance-android}{empty}/couchbase-lite-android/[API Reference] | xref:android:p2psync-websocket.adoc[Peer-to-Peer] | xref:android:p2psync-custom.adoc[Integrate Custom Listener] +-- + +[#overview] +== Overview + +.Enterprise Edition only +IMPORTANT: Peer-to-Peer Synchronization is an https://www.couchbase.com/products/editions[Enterprise Edition] feature. +You must purchase the Enterprise License, which includes official https://www.couchbase.com/support-policy[Couchbase Support]. +To use it in production (also see the https://www.couchbase.com/licensing-and-support-faq[FAQ]). + +This content covers how to integrate a custom __MessageEndpointListener__ solution with Couchbase Lite to handle the data transfer, which is the sending and receiving of data. +Where applicable, we discuss how to integrate Couchbase Lite into the workflow. + +The following sections describe a typical Peer-to-Peer workflow. + +[#peer-discovery] +== Peer Discovery + +Peer discovery is the first step. +The communication framework will generally include a Peer discovery API for devices to advertise themselves on the network and to browse for other Peers. + +image::ROOT:discovery.png[] + +[#active-peer] +=== Active Peer + +The first step is to initialize the Couchbase Lite database. + +[#passive-peer] +=== Passive Peer + +In addition to initializing the database, the Passive Peer must initialize the `MessageEndpointListener`. +The `MessageEndpointListener` acts as a Listener for incoming connections. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=listener,indent=0] +---- + +[#peer-selection-and-connection-setup] +== Peer Selection and Connection Setup + + +Once a Peer device is found, the application code must decide whether it should establish a connection with that Peer. +This step includes inviting a Peer to a session and Peer authentication. + +This is handled by the Communication Framework. + +image::ROOT:selection.png[] + +Once the remote Peer has been authenticated, the next step is to connect with that Peer and initialize the Message Endpoint API. + + +[#replication-setup] +== Replication Setup + + +image::ROOT:connection.png[] + +[#active-peer-2] +=== Active Peer + +When the connection is established, the active Peer must instantiate a `MessageEndpoint` object corresponding to the remote Peer. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=message-endpoint,indent=0] +---- + +The `MessageEndpoint` initializer takes the following arguments. + +. `uid`: a unique ID that represents the remote active Peer. +. `target`: This represents the remote passive Peer and could be any suitable representation of the remote Peer. +It could be an Id, URL etc. +If using the MultiPeerConnectivity Framework, this could be the MCPeerID. +. `protocolType`: specifies the kind of transport you intend to implement. +There are two options. + ** The default (`MessageStream`) means that you want to "send a series of messages", or in other words the Communication Framework will control the formatting of messages so that there are clear boundaries between messages. + ** The alternative (`ByteStream`) means that you just want to send raw bytes over the stream and Couchbase should format for you to ensure that messages get delivered in full. ++ +Typically, the Communication Framework will handle message assembly and disassembly so you would use the `MessageType` option in most cases. + +. `delegate`: the delegate that will implement the `MessageEndpointDelegate` protocol, which is a factory for `MessageEndpointConnection`. + +Then, a `Replicator` is instantiated with the initialized `MessageEndpoint` as the target. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=message-endpoint-replicator,indent=0] +---- + +Next, Couchbase Lite will call back the application code through the `MessageEndpointDelegate.createConnection` interface method. +When the application receives the callback, it must create an instance of `MessageEndpointConnection` and return it. + + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=create-connection,indent=0] +---- +Next, Couchbase Lite will call back the application code through the `MessageEndpointConnection.open` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=active-peer-open,indent=0] +---- + +The connection argument is then set on an instance variable. +The application code must keep track of every `ReplicatorConnection` associated with every `MessageEndpointConnection`. + +The `MessageError` argument in the completion block specifies whether the error is recoverable or not. +If it is a recoverable error, the replicator will begin a retry process, creating a new `MessageEndpointConnection` instance. + +[#passive-peer-2] +=== Passive Peer + +After connection establishment on the Passive Peer, the first step is to initialize a new `MessageEndpointConnection` and pass it to the listener. +This message tells the listener to accept incoming data from that Peer. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=advertizer-accept,indent=0] +---- + +`messageEndpointListener` is the instance of the `MessageEndpointListener` that was created in the first step (<>) + +Couchbase Lite will call the application code back through the `MessageEndpointConnection.open` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=passive-peer-open,indent=0] +---- + +The `connection` argument is then set on an instance variable. +The application code must keep track of every `ReplicatorConnection` associated with every `MessageEndpointConnection`. + +At this point, the connection is established, and both Peers are ready to exchange data. + + +[#pushpull-replication] +== Push/Pull Replication + +Typically, an application needs to send data and receive data. +The directionality of the replication could be any of the following. + +* *Push only:* The data is pushed from the local database to the remote database. + +* *Pull only:* The data is pulled from the remote database to the local database. + +* *Push and Pull:* The data is exchanged both ways. + +Typically, the remote is a Sync Gateway database identified through a URL. +In Peer-to-Peer syncing, the remote is another Couchbase Lite database. + +image::ROOT:replication.png[] + +The replication lifecycle is handled through the `MessageEndpointConnection`. + +[#active-peer-3] +=== Active Peer + +When Couchbase Lite calls back the application code through the `MessageEndpointConnection.send` method, you should send that data to the other Peer using the communication framework. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=active-peer-send,indent=0] +---- + +Once the data is sent, call the completion block to acknowledge the completion. +You can use the `MessageError` in the completion block to specify whether the error is recoverable. +If it is a recoverable error, the replicator will begin a retry process, creating a new `MessageEndpointConnection`. + + +When data is received from the passive Peer via the Communication Framework, you call the `ReplicatorConnection.receive` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=active-peer-receive,indent=0] +---- + +The replication connection's `receive` method is called. Which then processes the data to persist to the local database. + +[#passive-peer-3] +=== Passive Peer + +As in the case of the active Peer, the passive Peer must implement the `MessageEndpointConnection.send` method to send data to the other Peer. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=passive-peer-send,indent=0] +---- + +Once the data is sent, call the completion block to acknowledge the completion. +You can use the `MessageError` in the completion block to specify whether the error is recoverable. +If it is a recoverable error, the replicator will begin a retry process, creating a new `MessageEndpointConnection`. + +When data is received from the active Peer via the Communication Framework, you call the `ReplicatorConnection.receive` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=passive-peer-receive,indent=0] +---- + +[#connection-teardown] +== Connection Teardown + +When a Peer disconnects from a Peer-to-Peer network, all connected Peers are notified. +The disconnect notification is a good opportunity to close and remove a replication connection. +The steps to Teardown the connection are slightly different depending on whether the active or passive Peer disconnects first. +We will cover each case below. + +[#initiated-by-active-peer] +=== Initiated by Active Peer + +image::ROOT:dis-active.png[] + +[#active-peer-4] +=== Active Peer + +When an active Peer disconnects, it must call the `ReplicatorConnection.close` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=active-replicator-close,indent=0] +---- + +Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=active-peer-close,indent=0] +---- + +[#passive-peer-4] +=== Passive Peer + +When the passive Peer receives the corresponding disconnect notification from the Communication Framework, it must call the `ReplicatorConnection.close` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=passive-replicator-close,indent=0] +---- + +Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=passive-peer-close,indent=0] +---- + +[#initiated-by-passive-peer] +=== Initiated by Passive Peer + +image::ROOT:dis-passive.png[] + +[#passive-peer-5] +=== Passive Peer + +When the passive disconnects, it must class the `MessageEndpointListener.closeAll` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=passive-stop-listener,indent=0] +---- + +Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=passive-peer-close,indent=0] +---- + +[#active-peer-5] +=== Active Peer + +When the active Peer receives the corresponding disconnect notification from the Communication Framework, it must call the `ReplicatorConnection.close` method. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=active-replicator-close,indent=0] +---- + +Then, Couchbase Lite will call back your code through the `MessageEndpointConnection.close` to allow the application to disconnect with the Communication Framework. + +[source] +---- +include::android:example$codesnippet_collection.kt[tag=active-peer-close,indent=0] +---- + +[#related-content] +== Related Content +++++ +
+++++ + +[.column] +=== {empty} +.How to +* xref:android:p2psync-websocket-using-passive.adoc[Passive Peer] +* xref:android:p2psync-websocket-using-active.adoc[Active Peer] + + +. + +[.column] +=== {empty} +.Concepts +* xref:android:landing-p2psync.adoc[Peer-to-Peer Sync] + +* https://docs.couchbase.com/mobile/{major}.{minor}.{maintenance-android}{empty}/couchbase-lite-android/[API References] + +. + + +[.column] +=== {empty} +.Community Resources ... +https://forums.couchbase.com/c/mobile/14[Mobile Forum] | +https://blog.couchbase.com/[Blog] | +https://docs.couchbase.com/tutorials/[Tutorials] + +. +xref:tutorials:cbl-p2p-sync-websockets:swift/cbl-p2p-sync-websockets.adoc[Getting Started with Peer-to-Peer Synchronization] + + +++++ +
+++++ + diff --git a/example/modules/ROOT/pages/intro.adoc b/example/modules/ROOT/pages/intro.adoc index 336a3d2..090f44c 100644 --- a/example/modules/ROOT/pages/intro.adoc +++ b/example/modules/ROOT/pages/intro.adoc @@ -1,7 +1,32 @@ -= This is an example +# This is an example +:description: pass:q[Roles grant users access to one or more resources.] + +Note that this role does not grant the ability to back up or restore users. Here is a test example. +A second line on this example. + +This page is about what is so good about couchbase server. And about couchbase capella. + +[#table_backup_admin_role,cols="1,2,2,hrows=2"] +|=== +5+^| Role: XDCR Admin (`replication_admin`) +3+^| Role: Backup Full Admin (`backup_admin`) +|=== + +A list: + +* of items +** like this +** and this +** Users that are explicitly registered on Couchbase Server as _external_; as supported either by _LDAP_, _Security Assertion Markup Language (SAML)_, or _PAM_. -Adding a line for testing. +Roles grant access to databases. +It's important not to access the database directly. +Database access is great! +Role based access controls are awesome! +Look at xref:couchbase.adoc[] for more information about Couchbase Server. +She sells seashells by the seashore. +NOTE: We recommend keeping residentRatio above 10 to avoid issues like index build failures.