Skip to content

Commit ddfa9ec

Browse files
authored
Merge pull request #300 from poissoncorp/RDBC-1076-1079-revisions-and-pull-replication-v72
RDBC-1079 + RDBC-1076: Revisions Operations and Pull Replication
2 parents 83165fb + f396fe8 commit ddfa9ec

16 files changed

Lines changed: 1867 additions & 55 deletions

File tree

ravendb/__init__.py

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,50 @@
165165
from ravendb.documents.operations.refresh.configuration import RefreshConfiguration
166166
from ravendb.documents.operations.replication.definitions import (
167167
ExternalReplication,
168+
ExternalReplicationBase,
169+
ReplicationNode,
168170
PullReplicationAsSink,
169171
PullReplicationDefinition,
170-
ReplicationNode,
171-
ExternalReplicationBase,
172+
PullReplicationMode,
173+
PreventDeletionsMode,
174+
ReplicationHubAccess,
175+
DetailedReplicationHubAccess,
176+
ReplicationHubAccessResult,
177+
PullReplicationDefinitionAndCurrentConnections,
178+
)
179+
from ravendb.documents.operations.replication.pull_replication import (
180+
PutPullReplicationAsHubOperation,
181+
UpdatePullReplicationAsSinkOperation,
182+
UpdateExternalReplicationOperation,
183+
RegisterReplicationHubAccessOperation,
184+
UnregisterReplicationHubAccessOperation,
185+
GetReplicationHubAccessOperation,
186+
GetPullReplicationTasksInfoOperation,
187+
)
188+
from ravendb.documents.operations.ongoing_tasks import (
189+
OngoingTaskPullReplicationAsSink,
190+
OngoingTaskPullReplicationAsHub,
172191
)
173192
from ravendb.documents.operations.revisions import (
174193
RevisionsCollectionConfiguration,
175194
RevisionsConfiguration,
195+
RevisionsResult,
196+
ConfigureRevisionsOperation,
197+
ConfigureRevisionsOperationResult,
198+
GetRevisionsOperation,
199+
EnforceRevisionsConfigurationOperation,
200+
AdoptOrphanedRevisionsOperation,
201+
DeleteRevisionsOperation,
202+
RevertRevisionsByIdOperation,
203+
ConfigureRevisionsBinCleanerOperation,
204+
ConfigureRevisionsBinCleanerOperationResult,
205+
RevisionsBinConfiguration,
206+
RevisionsOperationParameters,
207+
RevisionsOperationContinuationParameters,
208+
)
209+
from ravendb.serverwide.operations.revisions import (
210+
ConfigureRevisionsForConflictsOperation,
211+
ConfigureRevisionsForConflictsResult,
176212
)
177213
from ravendb.documents.operations.statistics import (
178214
GetCollectionStatisticsOperation,
@@ -340,7 +376,6 @@
340376

341377
# todo: Serverwide
342378
# ReorderDatabaseMembersOperation
343-
# ConfigureRevisionsForConflictsOperation
344379
# UpdateDatabaseOperation
345380
# GetServerWideBackupConfigurationOperation
346381
# SetDatabaseDynamicDistributionOperation
@@ -395,17 +430,7 @@
395430
# SeedIdentityForOperation
396431
# IOperationProgress
397432
# IOperationResult
398-
# PullReplicationDefinitionAndCurrentConnections
399-
# DetailedReplicationHubAccess
400-
# GetReplicationHubAccessOperation
401-
# PreventDeletionsMode
402-
# PullReplicationMode
403-
# RegisterReplicationHubAccessOperation
404-
# ReplicationHubAccess
405-
# ReplicationHubAccessResult
406433
# ReplicationHubAccessResponse
407-
# UnregisterReplicationHubAccessOperation
408-
# UpdatePullReplicationAsSinkOperation
409434
# GetConflictsCommand
410435
# PutAttachmentCommandHelper
411436
# SetupDocumentBase
@@ -420,9 +445,6 @@
420445
# LazyRevisionOperation
421446
# LazyRevisionOperations
422447
# StreamOperation
423-
# ConfigureRevisionsOperation
424-
# GetRevisionsOperation
425-
# RevisionsResult
426448
# GetConnectionStringsOperation
427449
# RemoveConnectionStringOperation
428450
# SqlEtlTable
@@ -435,9 +457,6 @@
435457
# DisableDatabaseToggleResult
436458
# ConfigureExpirationOperation
437459
# DeleteOngoingTaskOperation
438-
# GetPullReplicationHubTasksInfoOperation
439-
# OngoingTaskPullReplicationAsSink
440-
# OngoingTaskPullReplicationAsHub
441460
# OngoingTaskType
442461
# RunningBackup
443462
# NextBackup

ravendb/documents/operations/ongoing_tasks.py

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ravendb.tools.utils import Utils
1313
from ravendb.util.util import RaftIdGenerator
1414
from ravendb.http.raven_command import RavenCommand
15+
from ravendb.documents.operations.replication.definitions import PullReplicationMode
1516

1617
if TYPE_CHECKING:
1718
from ravendb.documents.conventions import DocumentConventions
@@ -279,6 +280,186 @@ def from_json(cls, json_dict: dict) -> "OngoingTaskEmbeddingsGeneration":
279280
)
280281

281282

283+
class OngoingTaskPullReplicationAsHub(OngoingTask):
284+
"""Ongoing task information for a single pull-replication hub connection."""
285+
286+
def __init__(
287+
self,
288+
task_id: Optional[int] = None,
289+
responsible_node: Optional[NodeId] = None,
290+
task_state: Optional[OngoingTaskState] = None,
291+
task_connection_status: Optional[OngoingTaskConnectionStatus] = None,
292+
task_name: Optional[str] = None,
293+
error: Optional[str] = None,
294+
mentor_node: Optional[str] = None,
295+
pin_to_mentor_node: Optional[bool] = None,
296+
from_to_string: Optional[str] = None,
297+
destination_url: Optional[str] = None,
298+
destination_database: Optional[str] = None,
299+
delay_replication_for=None,
300+
handler_id: Optional[str] = None,
301+
last_accepted_change_vector_from_destination: Optional[str] = None,
302+
source_database_change_vector: Optional[str] = None,
303+
last_sent_etag: Optional[int] = None,
304+
last_database_etag: Optional[int] = None,
305+
):
306+
super().__init__(
307+
task_id=task_id,
308+
task_type=OngoingTaskType.PULL_REPLICATION_AS_HUB,
309+
responsible_node=responsible_node,
310+
task_state=task_state,
311+
task_connection_status=task_connection_status,
312+
task_name=task_name,
313+
error=error,
314+
mentor_node=mentor_node,
315+
pin_to_mentor_node=pin_to_mentor_node,
316+
)
317+
self.from_to_string = from_to_string
318+
self.destination_url = destination_url
319+
self.destination_database = destination_database
320+
self.delay_replication_for = delay_replication_for
321+
self.handler_id = handler_id
322+
self.last_accepted_change_vector_from_destination = last_accepted_change_vector_from_destination
323+
self.source_database_change_vector = source_database_change_vector
324+
self.last_sent_etag = last_sent_etag
325+
self.last_database_etag = last_database_etag
326+
327+
def to_json(self) -> dict:
328+
result = super().to_json()
329+
result["FromToString"] = self.from_to_string
330+
result["DestinationUrl"] = self.destination_url
331+
result["DestinationDatabase"] = self.destination_database
332+
result["DelayReplicationFor"] = (
333+
Utils.timedelta_to_str(self.delay_replication_for) if self.delay_replication_for is not None else None
334+
)
335+
result["HandlerId"] = self.handler_id
336+
result["LastAcceptedChangeVectorFromDestination"] = self.last_accepted_change_vector_from_destination
337+
result["SourceDatabaseChangeVector"] = self.source_database_change_vector
338+
result["LastSentEtag"] = self.last_sent_etag
339+
result["LastDatabaseEtag"] = self.last_database_etag
340+
return result
341+
342+
@classmethod
343+
def from_json(cls, json_dict: dict) -> Optional["OngoingTaskPullReplicationAsHub"]:
344+
if json_dict is None:
345+
return None
346+
task_state_str = json_dict.get("TaskState")
347+
task_connection_status_str = json_dict.get("TaskConnectionStatus")
348+
delay = json_dict.get("DelayReplicationFor")
349+
return cls(
350+
task_id=json_dict.get("TaskId"),
351+
responsible_node=NodeId.from_json(json_dict.get("ResponsibleNode")),
352+
task_state=OngoingTaskState(task_state_str) if task_state_str else None,
353+
task_connection_status=(
354+
OngoingTaskConnectionStatus(task_connection_status_str) if task_connection_status_str else None
355+
),
356+
task_name=json_dict.get("TaskName"),
357+
error=json_dict.get("Error"),
358+
mentor_node=json_dict.get("MentorNode"),
359+
pin_to_mentor_node=json_dict.get("PinToMentorNode"),
360+
from_to_string=json_dict.get("FromToString"),
361+
destination_url=json_dict.get("DestinationUrl"),
362+
destination_database=json_dict.get("DestinationDatabase"),
363+
delay_replication_for=Utils.string_to_timedelta(delay) if delay else None,
364+
handler_id=json_dict.get("HandlerId"),
365+
last_accepted_change_vector_from_destination=json_dict.get("LastAcceptedChangeVectorFromDestination"),
366+
source_database_change_vector=json_dict.get("SourceDatabaseChangeVector"),
367+
last_sent_etag=json_dict.get("LastSentEtag"),
368+
last_database_etag=json_dict.get("LastDatabaseEtag"),
369+
)
370+
371+
372+
class OngoingTaskPullReplicationAsSink(OngoingTask):
373+
"""Ongoing task information for a pull-replication sink task."""
374+
375+
def __init__(
376+
self,
377+
task_id: Optional[int] = None,
378+
responsible_node: Optional[NodeId] = None,
379+
task_state: Optional[OngoingTaskState] = None,
380+
task_connection_status: Optional[OngoingTaskConnectionStatus] = None,
381+
task_name: Optional[str] = None,
382+
error: Optional[str] = None,
383+
mentor_node: Optional[str] = None,
384+
pin_to_mentor_node: Optional[bool] = None,
385+
hub_name: Optional[str] = None,
386+
mode: Optional[PullReplicationMode] = None,
387+
destination_url: Optional[str] = None,
388+
topology_discovery_urls: Optional[list] = None,
389+
destination_database: Optional[str] = None,
390+
connection_string_name: Optional[str] = None,
391+
certificate_public_key: Optional[str] = None,
392+
access_name: Optional[str] = None,
393+
allowed_hub_to_sink_paths: Optional[list] = None,
394+
allowed_sink_to_hub_paths: Optional[list] = None,
395+
):
396+
super().__init__(
397+
task_id=task_id,
398+
task_type=OngoingTaskType.PULL_REPLICATION_AS_SINK,
399+
responsible_node=responsible_node,
400+
task_state=task_state,
401+
task_connection_status=task_connection_status,
402+
task_name=task_name,
403+
error=error,
404+
mentor_node=mentor_node,
405+
pin_to_mentor_node=pin_to_mentor_node,
406+
)
407+
self.hub_name = hub_name
408+
self.mode = mode
409+
self.destination_url = destination_url
410+
self.topology_discovery_urls = topology_discovery_urls
411+
self.destination_database = destination_database
412+
self.connection_string_name = connection_string_name
413+
self.certificate_public_key = certificate_public_key
414+
self.access_name = access_name
415+
self.allowed_hub_to_sink_paths = allowed_hub_to_sink_paths
416+
self.allowed_sink_to_hub_paths = allowed_sink_to_hub_paths
417+
418+
def to_json(self) -> dict:
419+
result = super().to_json()
420+
result["HubName"] = self.hub_name
421+
result["Mode"] = self.mode.value if self.mode else None
422+
result["DestinationUrl"] = self.destination_url
423+
result["TopologyDiscoveryUrls"] = self.topology_discovery_urls
424+
result["DestinationDatabase"] = self.destination_database
425+
result["ConnectionStringName"] = self.connection_string_name
426+
result["CertificatePublicKey"] = self.certificate_public_key
427+
result["AccessName"] = self.access_name
428+
result["AllowedHubToSinkPaths"] = self.allowed_hub_to_sink_paths
429+
result["AllowedSinkToHubPaths"] = self.allowed_sink_to_hub_paths
430+
return result
431+
432+
@classmethod
433+
def from_json(cls, json_dict: dict) -> Optional["OngoingTaskPullReplicationAsSink"]:
434+
if json_dict is None:
435+
return None
436+
task_state_str = json_dict.get("TaskState")
437+
task_connection_status_str = json_dict.get("TaskConnectionStatus")
438+
mode_str = json_dict.get("Mode")
439+
return cls(
440+
task_id=json_dict.get("TaskId"),
441+
responsible_node=NodeId.from_json(json_dict.get("ResponsibleNode")),
442+
task_state=OngoingTaskState(task_state_str) if task_state_str else None,
443+
task_connection_status=(
444+
OngoingTaskConnectionStatus(task_connection_status_str) if task_connection_status_str else None
445+
),
446+
task_name=json_dict.get("TaskName"),
447+
error=json_dict.get("Error"),
448+
mentor_node=json_dict.get("MentorNode"),
449+
pin_to_mentor_node=json_dict.get("PinToMentorNode"),
450+
hub_name=json_dict.get("HubName"),
451+
mode=PullReplicationMode(mode_str) if mode_str else None,
452+
destination_url=json_dict.get("DestinationUrl"),
453+
topology_discovery_urls=json_dict.get("TopologyDiscoveryUrls"),
454+
destination_database=json_dict.get("DestinationDatabase"),
455+
connection_string_name=json_dict.get("ConnectionStringName"),
456+
certificate_public_key=json_dict.get("CertificatePublicKey"),
457+
access_name=json_dict.get("AccessName"),
458+
allowed_hub_to_sink_paths=json_dict.get("AllowedHubToSinkPaths"),
459+
allowed_sink_to_hub_paths=json_dict.get("AllowedSinkToHubPaths"),
460+
)
461+
462+
282463
class ToggleOngoingTaskStateOperation(MaintenanceOperation[ModifyOngoingTaskResult]):
283464
def __init__(
284465
self, task_name_or_id: Union[int, str], type_of_task: Optional[OngoingTaskType], disable: Optional[bool]
@@ -454,6 +635,8 @@ def _deserialize_task(
454635
return OngoingTaskGenAi.from_json(json_dict)
455636
elif self._task_type == OngoingTaskType.EMBEDDINGS_GENERATION:
456637
return OngoingTaskEmbeddingsGeneration.from_json(json_dict)
638+
elif self._task_type == OngoingTaskType.PULL_REPLICATION_AS_SINK:
639+
return OngoingTaskPullReplicationAsSink.from_json(json_dict)
457640
else:
458641
# todo: handle more types of tasks
459642
return OngoingTask.from_json(json_dict)

0 commit comments

Comments
 (0)