Skip to content

Commit 7fa29bc

Browse files
Merge branch 'master' into add-s3-acl-to-cli
2 parents 94d2d1c + d71d811 commit 7fa29bc

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from .file_system import FileSystemMessagingIntegration
2+
from .slack_webhook import SlackWebhookMessagingIntegration
3+
from .teams_webhook import TeamsWebhookMessagingIntegration
4+
5+
__all__ = [
6+
"FileSystemMessagingIntegration",
7+
"TeamsWebhookMessagingIntegration",
8+
"SlackWebhookMessagingIntegration",
9+
]
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import json
2+
from datetime import datetime
3+
from pathlib import Path
4+
5+
from elementary.messages.message_body import MessageBody
6+
from elementary.messages.messaging_integrations.base_messaging_integration import (
7+
BaseMessagingIntegration,
8+
MessageSendResult,
9+
)
10+
from elementary.messages.messaging_integrations.empty_message_context import (
11+
EmptyMessageContext,
12+
)
13+
from elementary.messages.messaging_integrations.exceptions import (
14+
MessagingIntegrationError,
15+
)
16+
from elementary.utils.log import get_logger
17+
18+
logger = get_logger(__name__)
19+
20+
21+
class FileSystemMessagingIntegration(
22+
BaseMessagingIntegration[str, EmptyMessageContext]
23+
):
24+
def __init__(self, directory: str, create_if_missing: bool = True) -> None:
25+
self.directory = Path(directory).expanduser().resolve()
26+
self._create_if_missing = create_if_missing
27+
28+
if not self.directory.exists():
29+
if self._create_if_missing:
30+
logger.info(
31+
f"Creating directory for FileSystemMessagingIntegration: {self.directory}"
32+
)
33+
self.directory.mkdir(parents=True, exist_ok=True)
34+
else:
35+
raise MessagingIntegrationError(
36+
f"Directory {self.directory} does not exist and create_if_missing is False"
37+
)
38+
39+
def supports_reply(self) -> bool:
40+
return False
41+
42+
def send_message(
43+
self, destination: str, body: MessageBody
44+
) -> MessageSendResult[EmptyMessageContext]:
45+
channel_dir = self.directory / destination
46+
if not channel_dir.exists():
47+
if self._create_if_missing:
48+
channel_dir.mkdir(parents=True, exist_ok=True)
49+
else:
50+
raise MessagingIntegrationError(
51+
f"Channel directory {channel_dir} does not exist and create_if_missing is False"
52+
)
53+
54+
filename = datetime.utcnow().strftime("%Y%m%dT%H%M%S_%fZ.json")
55+
file_path = channel_dir / filename
56+
57+
try:
58+
json_str = json.dumps(body.dict(), indent=2)
59+
file_path.write_text(json_str, encoding="utf-8")
60+
except Exception as exc:
61+
logger.error(
62+
f"Failed to write alert message to file {file_path}: {exc}",
63+
exc_info=True,
64+
)
65+
raise MessagingIntegrationError(
66+
f"Failed writing alert message to file {file_path}"
67+
) from exc
68+
69+
return MessageSendResult(
70+
timestamp=datetime.utcnow(),
71+
message_format="json",
72+
message_context=EmptyMessageContext(),
73+
)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import json
2+
from pathlib import Path
3+
4+
import pytest
5+
6+
from elementary.messages.blocks import LineBlock, LinesBlock, TextBlock
7+
from elementary.messages.message_body import MessageBody
8+
from elementary.messages.messaging_integrations.exceptions import (
9+
MessagingIntegrationError,
10+
)
11+
from elementary.messages.messaging_integrations.file_system import (
12+
FileSystemMessagingIntegration,
13+
)
14+
15+
16+
def _build_body() -> MessageBody:
17+
return MessageBody(
18+
blocks=[LinesBlock(lines=[LineBlock(inlines=[TextBlock(text="hello")])])]
19+
)
20+
21+
22+
def test_send_message_creates_file_in_channel_dir(tmp_path: Path) -> None:
23+
root_dir = tmp_path / "alerts"
24+
integ = FileSystemMessagingIntegration(directory=str(root_dir))
25+
body = _build_body()
26+
27+
integ.send_message("channel", body)
28+
29+
channel_dir = root_dir / "channel"
30+
files = list(channel_dir.glob("*.json"))
31+
assert len(files) == 1, "Expected exactly one file in the channel directory"
32+
33+
message_json = files[0].read_text()
34+
assert json.loads(message_json) == json.loads(body.json())
35+
36+
37+
def test_send_multiple_messages_creates_multiple_files(tmp_path: Path) -> None:
38+
root_dir = tmp_path / "alerts"
39+
integ = FileSystemMessagingIntegration(directory=str(root_dir))
40+
body1 = _build_body()
41+
body2 = _build_body()
42+
43+
integ.send_message("channel", body1)
44+
integ.send_message("channel", body2)
45+
46+
channel_dir = root_dir / "channel"
47+
files = sorted(channel_dir.glob("*.json"))
48+
49+
assert len(files) == 2
50+
assert json.loads(files[0].read_text()) == json.loads(body1.json())
51+
assert json.loads(files[1].read_text()) == json.loads(body2.json())
52+
53+
54+
def test_send_message_no_create_flag(tmp_path: Path) -> None:
55+
directory = tmp_path / "alerts-no-create"
56+
with pytest.raises(MessagingIntegrationError):
57+
FileSystemMessagingIntegration(
58+
directory=str(directory), create_if_missing=False
59+
)

0 commit comments

Comments
 (0)