1__all__ = ["Replication"] 2 3from typing import Optional, Sequence 4 5from arango.api import ApiGroup 6from arango.exceptions import ( 7 ReplicationApplierConfigError, 8 ReplicationApplierConfigSetError, 9 ReplicationApplierStartError, 10 ReplicationApplierStateError, 11 ReplicationApplierStopError, 12 ReplicationClusterInventoryError, 13 ReplicationDumpBatchCreateError, 14 ReplicationDumpBatchDeleteError, 15 ReplicationDumpBatchExtendError, 16 ReplicationDumpError, 17 ReplicationInventoryError, 18 ReplicationLoggerFirstTickError, 19 ReplicationLoggerStateError, 20 ReplicationMakeSlaveError, 21 ReplicationServerIDError, 22 ReplicationSyncError, 23) 24from arango.formatter import ( 25 format_replication_applier_config, 26 format_replication_applier_state, 27 format_replication_header, 28 format_replication_inventory, 29 format_replication_logger_state, 30 format_replication_sync, 31) 32from arango.request import Request 33from arango.response import Response 34from arango.result import Result 35from arango.typings import Json, Params 36 37 38class Replication(ApiGroup): 39 def inventory( 40 self, 41 batch_id: str, 42 include_system: Optional[bool] = None, 43 all_databases: Optional[bool] = None, 44 ) -> Result[Json]: 45 """Return an overview of collections and indexes. 46 47 :param batch_id: Batch ID. 48 :type batch_id: str 49 :param include_system: Include system collections in the result. 50 Default value is True. 51 :type include_system: bool | None 52 :param all_databases: Include all databases. Only works on "_system" 53 database. Default value is False. 54 :type all_databases: bool | None 55 :return: Overview of collections and indexes. 56 :rtype: dict 57 :raise arango.exceptions.ReplicationInventoryError: If retrieval fails. 58 """ 59 params: Params = {"batchId": batch_id} 60 if include_system is not None: 61 params["includeSystem"] = include_system 62 if all_databases is not None: 63 params["global"] = all_databases 64 65 request = Request( 66 method="get", endpoint="/_api/replication/inventory", params=params 67 ) 68 69 def response_handler(resp: Response) -> Json: 70 if resp.is_success: 71 return format_replication_inventory(resp.body) 72 raise ReplicationInventoryError(resp, request) 73 74 return self._execute(request, response_handler) 75 76 def create_dump_batch(self, ttl: Optional[int] = None) -> Result[Json]: 77 """Create a new dump batch. 78 79 :param ttl: Time-to-live for the new batch in seconds. 80 :type ttl: int | None 81 :return: ID of the batch. 82 :rtype: dict 83 :raise arango.exceptions.ReplicationDumpBatchCreateError: If create fails. 84 """ 85 request = Request( 86 method="post", endpoint="/_api/replication/batch", data={"ttl": ttl} 87 ) 88 89 def response_handler(resp: Response) -> Json: 90 if resp.is_success: 91 return {"id": resp.body["id"], "last_tick": resp.body["lastTick"]} 92 raise ReplicationDumpBatchCreateError(resp, request) 93 94 return self._execute(request, response_handler) 95 96 def delete_dump_batch(self, batch_id: str) -> Result[bool]: 97 """Delete a dump batch. 98 99 :param batch_id: Dump batch ID. 100 :type batch_id: str 101 :return: True if deletion was successful. 102 :rtype: bool 103 :raise arango.exceptions.ReplicationDumpBatchDeleteError: If delete fails. 104 """ 105 request = Request( 106 method="delete", 107 endpoint=f"/_api/replication/batch/{batch_id}", 108 deserialize=False, 109 ) 110 111 def response_handler(resp: Response) -> bool: 112 if resp.is_success: 113 return True 114 raise ReplicationDumpBatchDeleteError(resp, request) 115 116 return self._execute(request, response_handler) 117 118 def extend_dump_batch(self, batch_id: str, ttl: int) -> Result[bool]: 119 """Extend a dump batch. 120 121 :param batch_id: Dump batch ID. 122 :type batch_id: str 123 :param ttl: Time-to-live for the new batch in seconds. 124 :type ttl: int 125 :return: True if operation was successful. 126 :rtype: bool 127 :raise arango.exceptions.ReplicationDumpBatchExtendError: If dump fails. 128 """ 129 request = Request( 130 method="put", 131 endpoint=f"/_api/replication/batch/{batch_id}", 132 data={"ttl": ttl}, 133 deserialize=False, 134 ) 135 136 def response_handler(resp: Response) -> bool: 137 if resp.is_success: 138 return True 139 raise ReplicationDumpBatchExtendError(resp, request) 140 141 return self._execute(request, response_handler) 142 143 def dump( 144 self, 145 collection: str, 146 batch_id: Optional[str] = None, 147 chunk_size: Optional[int] = None, 148 deserialize: bool = False, 149 ) -> Result[Json]: 150 """Return the events data of one collection. 151 152 :param collection: Name or ID of the collection to dump. 153 :type collection: str 154 :param batch_id: Batch ID. 155 :type batch_id: str | None 156 :param chunk_size: Size of the result in bytes. This value is honored 157 approximately only. 158 :type chunk_size: int | None 159 :param deserialize: Deserialize the response content. Default is False. 160 :type deserialize: bool 161 :return: Collection events data. 162 :rtype: str | [dict] 163 :raise arango.exceptions.ReplicationDumpError: If retrieval fails. 164 """ 165 params: Params = {"collection": collection} 166 167 if chunk_size is not None: 168 params["chunkSize"] = chunk_size 169 if batch_id is not None: 170 params["batchId"] = batch_id 171 172 request = Request( 173 method="get", 174 endpoint="/_api/replication/dump", 175 params=params, 176 deserialize=False, 177 ) 178 179 def response_handler(resp: Response) -> Json: 180 if resp.is_success: 181 result = format_replication_header(resp.headers) 182 result["content"] = [ 183 [ 184 self._conn.deserialize(line) 185 for line in resp.body.split("\n") 186 if line 187 ] 188 if deserialize 189 else resp.body 190 ] 191 return result 192 193 raise ReplicationDumpError(resp, request) 194 195 return self._execute(request, response_handler) 196 197 def synchronize( 198 self, 199 endpoint: str, 200 database: Optional[str] = None, 201 username: Optional[str] = None, 202 password: Optional[str] = None, 203 include_system: Optional[bool] = None, 204 incremental: Optional[bool] = None, 205 restrict_type: Optional[str] = None, 206 restrict_collections: Optional[Sequence[str]] = None, 207 initial_sync_wait_time: Optional[int] = None, 208 ) -> Result[Json]: # pragma: no cover 209 """Synchronize data from a remote endpoint. 210 211 :param endpoint: Master endpoint (e.g. "tcp://192.168.173.13:8529"). 212 :type endpoint: str 213 :param database: Database name. 214 :type database: str | None 215 :param username: Username. 216 :type username: str | None 217 :param password: Password. 218 :type password: str | None 219 :param include_system: Whether to include system collection operations. 220 :type include_system: bool | None 221 :param incremental: If set to True, then an incremental synchronization 222 method is used for synchronizing data in collections. This 223 method is useful when collections already exist locally, and only 224 the remaining differences need to be transferred from the remote 225 endpoint. In this case, the incremental synchronization can be 226 faster than a full synchronization. Default value is False, meaning 227 complete data is transferred. 228 :type incremental: bool | None 229 :param restrict_type: Optional string value for collection filtering. 230 Allowed values are "include" or "exclude". 231 :type restrict_type: str | None 232 :param restrict_collections: Optional list of collections for use with 233 argument **restrict_type**. If **restrict_type** set to "include", 234 only the specified collections are synchronised. Otherwise, all but 235 the specified ones are synchronized. 236 :type restrict_collections: [str] | None 237 :param initial_sync_wait_time: Maximum wait time in seconds that the 238 initial synchronization will wait for a response from master when 239 fetching collection data. This can be used to control after what 240 time the initial synchronization will give up waiting for response 241 and fail. Value is ignored if set to 0. 242 :type initial_sync_wait_time: int | None 243 :return: Collections transferred and last log tick. 244 :rtype: dict 245 :raise arango.exceptions.ReplicationSyncError: If sync fails. 246 """ 247 data: Json = {"endpoint": endpoint} 248 249 if database is not None: 250 data["database"] = database 251 if username is not None: 252 data["username"] = username 253 if password is not None: 254 data["password"] = password 255 if include_system is not None: 256 data["includeSystem"] = include_system 257 if incremental is not None: 258 data["incremental"] = incremental 259 if restrict_type is not None: 260 data["restrictType"] = restrict_type 261 if restrict_collections is not None: 262 data["restrictCollections"] = restrict_collections 263 if initial_sync_wait_time is not None: 264 data["initialSyncMaxWaitTime"] = initial_sync_wait_time 265 266 request = Request(method="put", endpoint="/_api/replication/sync", data=data) 267 268 def response_handler(resp: Response) -> Json: 269 if resp.is_success: 270 return format_replication_sync(resp.body) 271 raise ReplicationSyncError(resp, request) 272 273 return self._execute(request, response_handler) 274 275 def cluster_inventory(self, include_system: Optional[bool] = None) -> Result[Json]: 276 """Return an overview of collections and indexes in a cluster. 277 278 :param include_system: Include system collections in the result. 279 Default value is True. 280 :type include_system: bool 281 :return: Overview of collections and indexes on the cluster. 282 :rtype: dict 283 :raise arango.exceptions.ReplicationClusterInventoryError: If retrieval fails. 284 """ 285 params: Params = {} 286 if include_system is not None: 287 params["includeSystem"] = include_system 288 289 request = Request( 290 method="get", endpoint="/_api/replication/clusterInventory", params=params 291 ) 292 293 def response_handler(resp: Response) -> Json: 294 if resp.is_success: # pragma: no cover 295 return format_replication_inventory(resp.body) 296 raise ReplicationClusterInventoryError(resp, request) 297 298 return self._execute(request, response_handler) 299 300 def logger_state(self) -> Result[Json]: 301 """Return the state of the replication logger. 302 303 :return: Logger state. 304 :rtype: dict 305 :raise arango.exceptions.ReplicationLoggerStateError: If retrieval fails. 306 """ 307 request = Request( 308 method="get", 309 endpoint="/_api/replication/logger-state", 310 ) 311 312 def response_handler(resp: Response) -> Json: 313 if resp.is_success: 314 return format_replication_logger_state(resp.body) 315 raise ReplicationLoggerStateError(resp, request) 316 317 return self._execute(request, response_handler) 318 319 def logger_first_tick(self) -> Result[str]: 320 """Return the first available tick value from the server. 321 322 :return: First tick value. 323 :rtype: str 324 :raise arango.exceptions.ReplicationLoggerFirstTickError: If retrieval fails. 325 """ 326 request = Request( 327 method="get", 328 endpoint="/_api/replication/logger-first-tick", 329 ) 330 331 def response_handler(resp: Response) -> str: 332 if resp.is_success: 333 return str(resp.body["firstTick"]) 334 raise ReplicationLoggerFirstTickError(resp, request) 335 336 return self._execute(request, response_handler) 337 338 def applier_config(self) -> Result[Json]: 339 """Return the configuration of the replication applier. 340 341 :return: Configuration of the replication applier. 342 :rtype: dict 343 :raise arango.exceptions.ReplicationApplierConfigError: If retrieval fails. 344 """ 345 request = Request( 346 method="get", 347 endpoint="/_api/replication/applier-config", 348 ) 349 350 def response_handler(resp: Response) -> Json: 351 if resp.is_success: 352 return format_replication_applier_config(resp.body) 353 raise ReplicationApplierConfigError(resp, request) 354 355 return self._execute(request, response_handler) 356 357 def set_applier_config( 358 self, 359 endpoint: str, 360 database: Optional[str] = None, 361 username: Optional[str] = None, 362 password: Optional[str] = None, 363 max_connect_retries: Optional[int] = None, 364 connect_timeout: Optional[int] = None, 365 request_timeout: Optional[int] = None, 366 chunk_size: Optional[int] = None, 367 auto_start: Optional[bool] = None, 368 adaptive_polling: Optional[bool] = None, 369 include_system: Optional[bool] = None, 370 auto_resync: Optional[bool] = None, 371 auto_resync_retries: Optional[int] = None, 372 initial_sync_max_wait_time: Optional[int] = None, 373 connection_retry_wait_time: Optional[int] = None, 374 idle_min_wait_time: Optional[int] = None, 375 idle_max_wait_time: Optional[int] = None, 376 require_from_present: Optional[bool] = None, 377 verbose: Optional[bool] = None, 378 restrict_type: Optional[str] = None, 379 restrict_collections: Optional[Sequence[str]] = None, 380 ) -> Result[Json]: 381 """Set configuration values of the replication applier. 382 383 :param endpoint: Server endpoint (e.g. "tcp://192.168.173.13:8529"). 384 :type endpoint: str 385 :param database: Database name. 386 :type database: str | None 387 :param username: Username. 388 :type username: str | None 389 :param password: Password. 390 :type password: str | None 391 :param max_connect_retries: Maximum number of connection attempts the 392 applier makes in a row before stopping itself. 393 :type max_connect_retries: int | None 394 :param connect_timeout: Timeout in seconds when attempting to connect 395 to the endpoint. This value is used for each connection attempt. 396 :type connect_timeout: int | None 397 :param request_timeout: Timeout in seconds for individual requests to 398 the endpoint. 399 :type request_timeout: int | None 400 :param chunk_size: Requested maximum size in bytes for log transfer 401 packets when the endpoint is contacted. 402 :type chunk_size: int | None 403 :param auto_start: Whether to auto-start the replication applier on 404 (next and following) server starts. 405 :type auto_start: bool | None 406 :param adaptive_polling: If set to True, replication applier sleeps 407 for an increasingly long period in case the logger server at the 408 endpoint has no replication events to apply. Using adaptive polling 409 reduces the amount of work done by both the applier and the logger 410 server when there are infrequent changes. The downside is that it 411 might take longer for the replication applier to detect new events. 412 :type adaptive_polling: bool | None 413 :param include_system: Whether system collection operations are 414 applied. 415 :type include_system: bool | None 416 :param auto_resync: Whether the slave should perform a full automatic 417 resynchronization with the master in case the master cannot serve 418 log data requested by the slave, or when the replication is started 419 and no tick value can be found. 420 :type auto_resync: bool | None 421 :param auto_resync_retries: Max number of resynchronization retries. 422 Setting this to 0 disables it. 423 :type auto_resync_retries: int | None 424 :param initial_sync_max_wait_time: Max wait time in seconds the initial 425 synchronization waits for master on collection data. This value 426 is relevant even for continuous replication when **auto_resync** is 427 set to True because this may re-start the initial synchronization 428 when master cannot provide log data slave requires. This value is 429 ignored if set to 0. 430 :type initial_sync_max_wait_time: int | None 431 :param connection_retry_wait_time: Time in seconds the applier idles 432 before trying to connect to master in case of connection problems. 433 This value is ignored if set to 0. 434 :type connection_retry_wait_time: int | None 435 :param idle_min_wait_time: Minimum wait time in seconds the applier 436 idles before fetching more log data from the master in case the 437 master has already sent all its log data. This wait time can be 438 used to control the frequency with which the replication applier 439 sends HTTP log fetch requests to the master in case there is no 440 write activity on the master. This value is ignored if set to 0. 441 :type idle_min_wait_time: int | None 442 :param idle_max_wait_time: Maximum wait time in seconds the applier 443 idles before fetching more log data from the master in case the 444 master has already sent all its log data. This wait time can be 445 used to control the maximum frequency with which the replication 446 applier sends HTTP log fetch requests to the master in case there 447 is no write activity on the master. Applies only when argument 448 **adaptive_polling** is set to True. This value is ignored if set 449 to 0. 450 :type idle_max_wait_time: int | None 451 :param require_from_present: If set to True, replication applier checks 452 at start whether the start tick from which it starts or resumes 453 replication is still present on the master. If not, then there 454 would be data loss. If set to True, the replication applier aborts 455 with an appropriate error message. If set to False, the applier 456 still starts and ignores the data loss. 457 :type require_from_present: bool | None 458 :param verbose: If set to True, a log line is emitted for all 459 operations performed by the replication applier. This should be 460 used for debugging replication problems only. 461 :type verbose: bool | None 462 :param restrict_type: Optional string value for collection filtering. 463 Allowed values are "include" or "exclude". 464 :type restrict_type: str | None 465 :param restrict_collections: Optional list of collections for use with 466 argument **restrict_type**. If **restrict_type** set to "include", 467 only the specified collections are included. Otherwise, only the 468 specified collections are excluded. 469 :type restrict_collections: [str] | None 470 :return: Updated configuration. 471 :rtype: dict 472 :raise arango.exceptions.ReplicationApplierConfigSetError: If update fails. 473 """ 474 data: Json = {"endpoint": endpoint} 475 476 if database is not None: 477 data["database"] = database 478 if username is not None: 479 data["username"] = username 480 if password is not None: 481 data["password"] = password 482 if max_connect_retries is not None: 483 data["maxConnectRetries"] = max_connect_retries 484 if connect_timeout is not None: 485 data["connectTimeout"] = connect_timeout 486 if request_timeout is not None: 487 data["requestTimeout"] = request_timeout 488 if chunk_size is not None: 489 data["chunkSize"] = chunk_size 490 if auto_start is not None: 491 data["autoStart"] = auto_start 492 if adaptive_polling is not None: 493 data["adaptivePolling"] = adaptive_polling 494 if include_system is not None: 495 data["includeSystem"] = include_system 496 if auto_resync is not None: 497 data["autoResync"] = auto_resync 498 if auto_resync_retries is not None: 499 data["autoResyncRetries"] = auto_resync_retries 500 if initial_sync_max_wait_time is not None: 501 data["initialSyncMaxWaitTime"] = initial_sync_max_wait_time 502 if connection_retry_wait_time is not None: 503 data["connectionRetryWaitTime"] = connection_retry_wait_time 504 if idle_min_wait_time is not None: 505 data["idleMinWaitTime"] = idle_min_wait_time 506 if idle_max_wait_time is not None: 507 data["idleMaxWaitTime"] = idle_max_wait_time 508 if require_from_present is not None: 509 data["requireFromPresent"] = require_from_present 510 if verbose is not None: 511 data["verbose"] = verbose 512 if restrict_type is not None: 513 data["restrictType"] = restrict_type 514 if restrict_collections is not None: 515 data["restrictCollections"] = restrict_collections 516 517 request = Request( 518 method="put", endpoint="/_api/replication/applier-config", data=data 519 ) 520 521 def response_handler(resp: Response) -> Json: 522 if resp.is_success: 523 return format_replication_applier_config(resp.body) 524 raise ReplicationApplierConfigSetError(resp, request) 525 526 return self._execute(request, response_handler) 527 528 def applier_state(self) -> Result[Json]: 529 """Return the state of the replication applier 530 531 :return: Applier state and details. 532 :rtype: dict 533 :raise arango.exceptions.ReplicationApplierStateError: If retrieval fails. 534 """ 535 request = Request( 536 method="get", 537 endpoint="/_api/replication/applier-state", 538 ) 539 540 def response_handler(resp: Response) -> Json: 541 if resp.is_success: 542 return format_replication_applier_state(resp.body) 543 raise ReplicationApplierStateError(resp, request) 544 545 return self._execute(request, response_handler) 546 547 def start_applier(self, last_tick: Optional[str] = None) -> Result[Json]: 548 """Start the replication applier. 549 550 :param last_tick: The remote last log tick value from which to start 551 applying replication. If not specified, the last saved tick from 552 the previous applier run is used. If there is no previous applier 553 state saved, the applier starts at the beginning of the logger 554 server's log. 555 :type last_tick: str 556 :return: Applier state and details. 557 :rtype: dict 558 :raise arango.exceptions.ReplicationApplierStartError: If operation fails. 559 """ 560 request = Request( 561 method="put", 562 endpoint="/_api/replication/applier-start", 563 params={} if last_tick is None else {"from": last_tick}, 564 ) 565 566 def response_handler(resp: Response) -> Json: 567 if resp.is_success: 568 return format_replication_applier_state(resp.body) 569 raise ReplicationApplierStartError(resp, request) 570 571 return self._execute(request, response_handler) 572 573 def stop_applier(self) -> Result[Json]: 574 """Stop the replication applier. 575 576 :return: Applier state and details. 577 :rtype: dict 578 :raise arango.exceptions.ReplicationApplierStopError: If operation fails. 579 """ 580 request = Request( 581 method="put", 582 endpoint="/_api/replication/applier-stop", 583 ) 584 585 def response_handler(resp: Response) -> Json: 586 if resp.is_success: 587 return format_replication_applier_state(resp.body) 588 raise ReplicationApplierStopError(resp, request) 589 590 return self._execute(request, response_handler) 591 592 def make_slave( 593 self, 594 endpoint: str, 595 database: Optional[str] = None, 596 username: Optional[str] = None, 597 password: Optional[str] = None, 598 restrict_type: Optional[str] = None, 599 restrict_collections: Optional[Sequence[str]] = None, 600 include_system: Optional[bool] = None, 601 max_connect_retries: Optional[int] = None, 602 connect_timeout: Optional[int] = None, 603 request_timeout: Optional[int] = None, 604 chunk_size: Optional[int] = None, 605 adaptive_polling: Optional[bool] = None, 606 auto_resync: Optional[bool] = None, 607 auto_resync_retries: Optional[int] = None, 608 initial_sync_max_wait_time: Optional[int] = None, 609 connection_retry_wait_time: Optional[int] = None, 610 idle_min_wait_time: Optional[int] = None, 611 idle_max_wait_time: Optional[int] = None, 612 require_from_present: Optional[bool] = None, 613 verbose: Optional[bool] = None, 614 ) -> Result[Json]: # pragma: no cover 615 """Change the server role to slave. 616 617 :param endpoint: Master endpoint (e.g. "tcp://192.168.173.13:8529"). 618 :type endpoint: str 619 :param database: Database name. 620 :type database: str | None 621 :param username: Username. 622 :type username: str | None 623 :param password: Password. 624 :type password: str | None 625 :param restrict_type: Optional string value for collection filtering. 626 Allowed values are "include" or "exclude". 627 :type restrict_type: str | None 628 :param restrict_collections: Optional list of collections for use with 629 argument **restrict_type**. If **restrict_type** set to "include", 630 only the specified collections are included. Otherwise, only the 631 specified collections are excluded. 632 :type restrict_collections: [str] | None 633 :param include_system: Whether system collection operations are 634 applied. 635 :type include_system: bool | None 636 :param max_connect_retries: Maximum number of connection attempts the 637 applier makes in a row before stopping itself. 638 :type max_connect_retries: int | None 639 :param connect_timeout: Timeout in seconds when attempting to connect 640 to the endpoint. This value is used for each connection attempt. 641 :type connect_timeout: int | None 642 :param request_timeout: Timeout in seconds for individual requests to 643 the endpoint. 644 :type request_timeout: int | None 645 :param chunk_size: Requested maximum size in bytes for log transfer 646 packets when the endpoint is contacted. 647 :type chunk_size: int | None 648 :param adaptive_polling: If set to True, replication applier sleeps 649 for an increasingly long period in case the logger server at the 650 endpoint has no replication events to apply. Using adaptive polling 651 reduces the amount of work done by both the applier and the logger 652 server when there are infrequent changes. The downside is that it 653 might take longer for the replication applier to detect new events. 654 :type adaptive_polling: bool | None 655 :param auto_resync: Whether the slave should perform a full automatic 656 resynchronization with the master in case the master cannot serve 657 log data requested by the slave, or when the replication is started 658 and no tick value can be found. 659 :type auto_resync: bool | None 660 :param auto_resync_retries: Max number of resynchronization retries. 661 Setting this to 0 disables it. 662 :type auto_resync_retries: int | None 663 :param initial_sync_max_wait_time: Max wait time in seconds the initial 664 synchronization waits for master on collection data. This value 665 is relevant even for continuous replication when **auto_resync** is 666 set to True because this may restart the initial synchronization 667 when master cannot provide log data slave requires. This value is 668 ignored if set to 0. 669 :type initial_sync_max_wait_time: int | None 670 :param connection_retry_wait_time: Time in seconds the applier idles 671 before trying to connect to master in case of connection problems. 672 This value is ignored if set to 0. 673 :type connection_retry_wait_time: int | None 674 :param idle_min_wait_time: Minimum wait time in seconds the applier 675 idles before fetching more log data from the master in case the 676 master has already sent all its log data. This wait time can be 677 used to control the frequency with which the replication applier 678 sends HTTP log fetch requests to the master in case there is no 679 write activity on the master. This value is ignored if set to 0. 680 :type idle_min_wait_time: int | None 681 :param idle_max_wait_time: Maximum wait time in seconds the applier 682 idles before fetching more log data from the master in case the 683 master has already sent all its log data. This wait time can be 684 used to control the maximum frequency with which the replication 685 applier sends HTTP log fetch requests to the master in case there 686 is no write activity on the master. Applies only when argument 687 **adaptive_polling** is set to True. This value is ignored if set 688 to 0. 689 :type idle_max_wait_time: int | None 690 :param require_from_present: If set to True, replication applier checks 691 at start whether the start tick from which it starts or resumes 692 replication is still present on the master. If not, then there 693 would be data loss. If set to True, the replication applier aborts 694 with an appropriate error message. If set to False, the applier 695 still starts and ignores the data loss. 696 :type require_from_present: bool | None 697 :param verbose: If set to True, a log line is emitted for all 698 operations performed by the replication applier. This should be 699 used for debugging replication problems only. 700 :type verbose: bool | None 701 :return: Replication details. 702 :rtype: dict 703 :raise arango.exceptions.ReplicationApplierStopError: If operation fails. 704 """ 705 data: Json = {"endpoint": endpoint} 706 707 if database is not None: 708 data["database"] = database 709 if username is not None: 710 data["username"] = username 711 if password is not None: 712 data["password"] = password 713 if restrict_type is not None: 714 data["restrictType"] = restrict_type 715 if restrict_collections is not None: 716 data["restrictCollections"] = restrict_collections 717 if include_system is not None: 718 data["includeSystem"] = include_system 719 if max_connect_retries is not None: 720 data["maxConnectRetries"] = max_connect_retries 721 if connect_timeout is not None: 722 data["connectTimeout"] = connect_timeout 723 if request_timeout is not None: 724 data["requestTimeout"] = request_timeout 725 if chunk_size is not None: 726 data["chunkSize"] = chunk_size 727 if adaptive_polling is not None: 728 data["adaptivePolling"] = adaptive_polling 729 if auto_resync is not None: 730 data["autoResync"] = auto_resync 731 if auto_resync_retries is not None: 732 data["autoResyncRetries"] = auto_resync_retries 733 if initial_sync_max_wait_time is not None: 734 data["initialSyncMaxWaitTime"] = initial_sync_max_wait_time 735 if connection_retry_wait_time is not None: 736 data["connectionRetryWaitTime"] = connection_retry_wait_time 737 if idle_min_wait_time is not None: 738 data["idleMinWaitTime"] = idle_min_wait_time 739 if idle_max_wait_time is not None: 740 data["idleMaxWaitTime"] = idle_max_wait_time 741 if require_from_present is not None: 742 data["requireFromPresent"] = require_from_present 743 if verbose is not None: 744 data["verbose"] = verbose 745 746 request = Request( 747 method="put", endpoint="/_api/replication/make-slave", data=data 748 ) 749 750 def response_handler(resp: Response) -> Json: 751 if resp.is_success: 752 return format_replication_applier_state(resp.body) 753 raise ReplicationMakeSlaveError(resp, request) 754 755 return self._execute(request, response_handler) 756 757 def server_id(self) -> Result[str]: 758 """Return this server's ID. 759 760 :return: Server ID. 761 :rtype: str 762 :raise arango.exceptions.ReplicationServerIDError: If retrieval fails. 763 """ 764 request = Request( 765 method="get", 766 endpoint="/_api/replication/server-id", 767 ) 768 769 def response_handler(resp: Response) -> str: 770 if resp.is_success: 771 return str(resp.body["serverId"]) 772 raise ReplicationServerIDError(resp, request) 773 774 return self._execute(request, response_handler) 775