Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import json
from typing import Dict, Optional

import requests

from ravendb import RavenCommand, ServerNode
from ravendb.documents.operations.definitions import MaintenanceOperation
from ravendb.documents.operations.etl.configuration import RavenConnectionString
from ravendb.documents.operations.etl.olap import OlapConnectionString
from ravendb.documents.operations.etl.sql import SqlConnectionString
from ravendb.serverwide.server_operation_executor import ConnectionStringType


class GetConnectionStringsResult:
def __init__(
self,
raven_connection_strings: Dict[str, RavenConnectionString] = None,
sql_connection_strings: Dict[str, SqlConnectionString] = None,
olap_connection_strings: Dict[str, OlapConnectionString] = None,
):
self.raven_connection_strings = raven_connection_strings
self.sql_connection_strings = sql_connection_strings
self.olap_connection_strings = olap_connection_strings

def to_json(self) -> Dict:
return {
"RavenConnectionStrings": self._raven_connection_strings,
"SqlConnectionStrings": self._sql_connection_strings,
"OlapConnectionStrings": self._olap_connection_strings,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

last thing - shouldn't you call to_json on each connection string object from this collection? like this

Suggested change
"OlapConnectionStrings": self._olap_connection_strings,
"OlapConnectionStrings": [olap_cs.to_json() for olap_cs in self._olap_connection_strings],

also in from_json - you need to call from_json on each dict in json_dict["RavenConnectionString"]

}

@classmethod
def from_json(cls, json_dict: Dict) -> "GetConnectionStringsResult":
return cls(
raven_connection_strings=json_dict["RavenConnectionStrings"],
sql_connection_strings=json_dict["SqlConnectionStrings"],
olap_connection_strings=json_dict["OlapConnectionStrings"],
)


class GetConnectionStringsOperation(MaintenanceOperation[GetConnectionStringsResult]):
def __init__(self, connection_string_name: str = None, connection_string_type: ConnectionStringType = None):
self._connection_string_name = connection_string_name
self._type = connection_string_type

def get_command(self, conventions: "DocumentConventions") -> "RavenCommand[GetConnectionStringsResult]":
return self.GetConnectionStringsCommand(self._connection_string_name, self._type)

class GetConnectionStringsCommand(RavenCommand[GetConnectionStringsResult]):
def __init__(self, connection_string_name: str = None, connection_string_type: ConnectionStringType = None):
super().__init__(GetConnectionStringsResult)
self._connection_string_name = connection_string_name
self._type = connection_string_type

def is_read_request(self) -> bool:
return True

def create_request(self, node: ServerNode) -> requests.Request:
url = f"{node.url}/databases/{node.database}/admin/connection-strings"

if self._connection_string_name:
url += f"?connectionStringName={self._connection_string_name}&type={self._type.value}"

request = requests.Request("GET")
request.url = url

return request

def set_response(self, response: Optional[str], from_cache: bool) -> None:
if response is None:
self._throw_invalid_response()

self.result = GetConnectionStringsResult.from_json(json.loads(response))
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import json
from typing import Dict

import requests

from ravendb import ConnectionString, RavenCommand, ServerNode, RaftCommand
from ravendb.documents.conventions import DocumentConventions
from ravendb.documents.operations.definitions import MaintenanceOperation
from ravendb.documents.operations.etl.configuration import RavenConnectionString
from ravendb.documents.operations.etl.olap import OlapConnectionString
from ravendb.documents.operations.etl.sql import SqlConnectionString
from ravendb.serverwide.server_operation_executor import ConnectionStringType
from ravendb.util.util import RaftIdGenerator


class PutConnectionStringResult:
def __init__(self, raft_command_index: int = None):
self.raft_command_index = raft_command_index

def to_json(self) -> Dict:
return {"RaftCommandIndex": self.raft_command_index}

@classmethod
def from_json(cls, json_dict: Dict) -> "PutConnectionStringResult":
return cls(json_dict["RaftCommandIndex"])


class PutConnectionStringOperation(MaintenanceOperation[PutConnectionStringResult]):
def __init__(self, connection_string: ConnectionString = None):
self._connection_string = connection_string

def get_command(self, conventions: "DocumentConventions") -> "RavenCommand[PutConnectionStringResult]":
return self.PutConnectionStringCommand(conventions, self._connection_string)

class PutConnectionStringCommand(RavenCommand[PutConnectionStringResult], RaftCommand):
def __init__(
self, document_conventions: DocumentConventions = None, connection_string: ConnectionString = None
):
super().__init__(PutConnectionStringResult)

if connection_string is None:
raise ValueError("Connection string cannot be None")

self._document_conventions = document_conventions
self._connection_string = connection_string

def _to_data(self) -> Dict:
if isinstance(self._connection_string, RavenConnectionString):
return {
"Name": self._connection_string.name,
"Database": self._connection_string.database,
"TopologyDiscoveryUrls": self._connection_string.topology_discovery_urls,
"Type": ConnectionStringType.RAVEN,
}

if isinstance(self._connection_string, SqlConnectionString):
return {
"Name": self._connection_string.name,
"ConnectionString": self._connection_string.connection_string,
"FactoryName": self._connection_string.factory_name,
"Type": ConnectionStringType.SQL,
}

if isinstance(self._connection_string, OlapConnectionString):
return {
"Name": self._connection_string.name,
"LocalSettings": self._connection_string.local_settings,
"S3Settings": self._connection_string.s3_settings,
"AzureSettings": self._connection_string.azure_settings,
"GlacierSettings": self._connection_string.glacier_settings,
"GoogleCloudSettings": self._connection_string.google_cloud_settings,
"FtpSettings": self._connection_string.ftp_settings,
"Type": ConnectionStringType.OLAP,
}

return None

def is_read_request(self) -> bool:
return False

def create_request(self, node: ServerNode) -> requests.Request:
url = f"{node.url}/databases/{node.database}/admin/connection-strings"

request = requests.Request("PUT")
request.url = url
request.data = self._to_data()

return request

def set_response(self, response: str, from_cache: bool) -> None:
if response is None:
self._throw_invalid_response()

self.result = PutConnectionStringResult.from_json(json.loads(response))

def get_raft_unique_request_id(self) -> str:
return RaftIdGenerator.new_id()
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import json
import urllib
from typing import Dict

import requests

from ravendb import RavenCommand, RaftCommand, ConnectionString, ServerNode
from ravendb.documents.operations.definitions import MaintenanceOperation
from ravendb.util.util import RaftIdGenerator


class RemoveConnectionStringResult:
def __init__(self, raft_command_index: int = None):
self.raft_command_index = raft_command_index

def to_json(self) -> Dict:
return {"RaftCommandIndex": self.raft_command_index}

@classmethod
def from_json(cls, json_dict: Dict) -> "PutConnectionStringResult":
return cls(json_dict["RaftCommandIndex"])


class RemoveConnectionStringOperation(MaintenanceOperation[RemoveConnectionStringResult]):
def __init__(self, connection_string: ConnectionString = None):
self._connection_string = connection_string

def get_command(self, conventions: "DocumentConventions") -> "RavenCommand[_T]":
return self.RemoveConnectionStringCommand(self._connection_string)

class RemoveConnectionStringCommand(RavenCommand[RemoveConnectionStringResult], RaftCommand):
def __init__(self, connection_string: ConnectionString = None):
super().__init__(RemoveConnectionStringResult)
self._connection_string = connection_string

def is_read_request(self) -> bool:
return False

def create_request(self, node: ServerNode) -> requests.Request:
url = f"{node.url}/databases/{node.database}/admin/connection-strings?connectionString={urllib.parse.quote(self._connection_string.name)}&type={self._connection_string.get_type}"

request = requests.Request("DELETE")
request.url = url

return request

def set_response(self, response: str, from_cache: bool) -> None:
if response is None:
self._throw_invalid_response()

self.result = RemoveConnectionStringResult.from_json(json.loads(response))

def get_raft_unique_request_id(self) -> str:
return RaftIdGenerator.new_id()
Empty file.
4 changes: 2 additions & 2 deletions ravendb/documents/operations/etl/configuration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Optional, Generic, TypeVar, List

from ravendb.documents.operations.connection_strings import ConnectionString
import ravendb.serverwide
import ravendb.serverwide.server_operation_executor

_T = TypeVar("_T")

Expand All @@ -14,7 +14,7 @@ def __init__(self, name: str, database: Optional[str] = None, topology_discovery

@property
def get_type(self):
return ravendb.serverwide.ConnectionStringType.RAVEN
return ravendb.serverwide.server_operation_executor.ConnectionStringType.RAVEN.value


# todo: implement
Expand Down
4 changes: 2 additions & 2 deletions ravendb/documents/operations/etl/olap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
FtpSettings,
)
from ravendb.documents.operations.connection_strings import ConnectionString
import ravendb.serverwide
import ravendb.serverwide.server_operation_executor
from ravendb.documents.operations.etl.configuration import EtlConfiguration


Expand All @@ -34,7 +34,7 @@ def __init__(

@property
def get_type(self):
return ravendb.serverwide.ConnectionStringType.OLAP
return ravendb.serverwide.server_operation_executor.ConnectionStringType.OLAP.value


# todo: implement
Expand Down
4 changes: 2 additions & 2 deletions ravendb/documents/operations/etl/sql/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Optional

from ravendb.documents.operations.connection_strings import ConnectionString
import ravendb.serverwide
import ravendb.serverwide.server_operation_executor
from ravendb.documents.operations.etl.configuration import EtlConfiguration


Expand All @@ -13,7 +13,7 @@ def __init__(self, name: str, connection_string: Optional[str] = None, factory_n

@property
def get_type(self):
return ravendb.serverwide.ConnectionStringType.SQL
return ravendb.serverwide.server_operation_executor.ConnectionStringType.SQL.value


# todo: implement
Expand Down
8 changes: 4 additions & 4 deletions ravendb/serverwide/server_operation_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@


class ConnectionStringType(enum.Enum):
NONE = "NONE"
RAVEN = "RAVEN"
SQL = "SQL"
OLAP = "OLAP"
NONE = "None"
RAVEN = "Raven"
SQL = "Sql"
OLAP = "Olap"


class ServerOperationExecutor:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from ravendb import FtpSettings
from ravendb.documents.operations.connection_string.GetConnectionStringOperation import GetConnectionStringsOperation
from ravendb.documents.operations.connection_string.PutConnectionStringOperation import (
PutConnectionStringOperation,
PutConnectionStringResult,
)
from ravendb.documents.operations.connection_string.RemoveConnectionStringOperation import (
RemoveConnectionStringOperation,
)
from ravendb.documents.operations.etl.configuration import RavenConnectionString
from ravendb.documents.operations.etl.olap import OlapConnectionString
from ravendb.documents.operations.etl.sql import SqlConnectionString
from ravendb.serverwide.server_operation_executor import ConnectionStringType
from ravendb.tests.test_base import TestBase


class TestConnectionString(TestBase):
def setUp(self):
super().setUp()

def test_can_create_get_and_delete_connection_strings(self):
raven_connection_string_1 = RavenConnectionString("r1", self.store.database, self.store.urls)
sql_connection_string_1 = SqlConnectionString("s1", "test", "MySql.Data.MySqlClient")
olap_connection_string_1 = OlapConnectionString("o1", ftp_settings=FtpSettings(url=self.store.urls[0]))

put_result: PutConnectionStringResult = self.store.maintenance.send(
PutConnectionStringOperation(raven_connection_string_1)
)
self.assertGreater(put_result.raft_command_index, 0)

put_result: PutConnectionStringResult = self.store.maintenance.send(
PutConnectionStringOperation(sql_connection_string_1)
)
self.assertGreater(put_result.raft_command_index, 0)

put_result: PutConnectionStringResult = self.store.maintenance.send(
PutConnectionStringOperation(olap_connection_string_1)
)
self.assertGreater(put_result.raft_command_index, 0)

connection_strings = self.store.maintenance.send(GetConnectionStringsOperation())

self.assertIn("r1", connection_strings.raven_connection_strings)
self.assertEqual(1, len(connection_strings.raven_connection_strings))

self.assertIn("s1", connection_strings.sql_connection_strings)
self.assertEqual(1, len(connection_strings.sql_connection_strings))

self.assertIn("o1", connection_strings.olap_connection_strings)
self.assertEqual(1, len(connection_strings.olap_connection_strings))

raven_only = self.store.maintenance.send(GetConnectionStringsOperation("r1", ConnectionStringType.RAVEN))
self.assertIn("r1", raven_only.raven_connection_strings)
self.assertEqual(1, len(raven_only.raven_connection_strings))
self.assertIsNone(raven_only.sql_connection_strings)

sql_only = self.store.maintenance.send(GetConnectionStringsOperation("s1", ConnectionStringType.SQL))
self.assertIn("s1", sql_only.sql_connection_strings)
self.assertEqual(1, len(sql_only.sql_connection_strings))
self.assertIsNone(sql_only.raven_connection_strings)

olap_only = self.store.maintenance.send(GetConnectionStringsOperation("o1", ConnectionStringType.OLAP))
self.assertIn("o1", olap_only.olap_connection_strings)
self.assertEqual(1, len(olap_only.olap_connection_strings))
self.assertIsNone(olap_only.raven_connection_strings)

remove_result = self.store.maintenance.send(RemoveConnectionStringOperation(sql_connection_string_1))
self.assertGreater(remove_result.raft_command_index, 0)

after_delete = self.store.maintenance.send(GetConnectionStringsOperation("s1", ConnectionStringType.SQL))
self.assertIsNone(after_delete.raven_connection_strings)
self.assertIsNone(after_delete.sql_connection_strings)