diff --git a/notifications_routing/data_source/postgres/postgres_data_source.py b/notifications_routing/data_source/postgres/postgres_data_source.py index 987a8d9be22807f239c4f68748cc0ffb09e86141..f3ceb5011c275991f29aed4e4f82a43686359b59 100644 --- a/notifications_routing/data_source/postgres/postgres_data_source.py +++ b/notifications_routing/data_source/postgres/postgres_data_source.py @@ -1,9 +1,11 @@ """Postgres Data Source Implementation.""" import logging +import uuid from contextlib import contextmanager from typing import Dict, List -from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table, Time, Date, create_engine, or_ +from sqlalchemy import Boolean, Column, Date, ForeignKey, String, Table, Time, create_engine, or_ +from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.ext.automap import automap_base from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.orm.exc import MultipleResultsFound @@ -53,12 +55,13 @@ class PostgresDataSource(DataSource): channel_users = [] with self.session() as session: - channel = self.__get_scalar(session, Channel, primaryKey=channel_id) + channel = self.__get_scalar(session, Channel, id=channel_id) if not channel: - raise NotFoundDataSourceError(Channel, primaryKey=channel_id) + raise NotFoundDataSourceError(Channel, id=channel_id) for member in channel.members: - channel_users.append({DataSource.USER_ID: member.username, DataSource.EMAIL: member.email}) + logging.debug("adding member: %s (%s)", member.id, member.username) + channel_users.append({DataSource.USER_ID: member.id, DataSource.EMAIL: member.email}) return channel_users @@ -67,9 +70,9 @@ class PostgresDataSource(DataSource): groups = [] with self.session() as session: - channel = self.__get_scalar(session, Channel, primaryKey=channel_id) + channel = self.__get_scalar(session, Channel, id=channel_id) if not channel: - raise NotFoundDataSourceError(Channel, primaryKey=channel_id) + raise NotFoundDataSourceError(Channel, id=channel_id) for group in channel.groups: groups.append({DataSource.GROUP_ID: group.id}) @@ -91,19 +94,19 @@ class PostgresDataSource(DataSource): def get_user_preferences(self, user_id: str, channel_id: str, **kwargs) -> Dict[str, List[str]]: """Return a dictionary with preferences of user for a specific channel.""" with self.session() as session: - user = self.__get_scalar(session, User, username=user_id) + user = self.__get_scalar(session, User, id=user_id) if not user: - raise NotFoundDataSourceError(User, username=user_id) + raise NotFoundDataSourceError(User, id=user_id) preferences = ( session.query(Preference) .filter( - Preference.userUsername == user.username, + Preference.userId == user.id, or_( - Preference.targetPrimaryKey == channel_id, - Preference.targetPrimaryKey.is_(None), + Preference.targetId == channel_id, + Preference.targetId.is_(None), ), - ~Preference.disabledChannels.any(Channel.primaryKey == channel_id), + ~Preference.disabledChannels.any(Channel.id == channel_id), ) .all() ) @@ -115,15 +118,15 @@ class PostgresDataSource(DataSource): def get_user_devices(self, user_id: str, **kwargs) -> Dict[str, List[str]]: """Return a dictionary with devices of user.""" with self.session() as session: - user = self.__get_scalar(session, User, username=user_id) + user = self.__get_scalar(session, User, id=user_id) if not user: - raise NotFoundDataSourceError(User, username=user_id) + raise NotFoundDataSourceError(User, id=user_id) devices = ( session.query(Device) .filter( - Device.userUsername == user.username, + Device.userId == user.id, ) .all() ) @@ -144,7 +147,8 @@ class User(PostgresDataSource.Base): __tablename__ = "Users" __table_args__ = {"schema": "push", "extend_existing": True} - username = Column(String, primary_key=True) + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + username = Column(String) email = Column(String) enabled = Column(Boolean) preferences = relationship("Preference") @@ -154,32 +158,32 @@ class User(PostgresDataSource.Base): channel_groups = Table( "channels_groups__groups", PostgresDataSource.Base.metadata, - Column("channelsPrimaryKey", Integer, ForeignKey("push.Channels.primaryKey")), - Column("groupsId", String, ForeignKey("push.Groups.id")), + Column("channelsId", UUID(as_uuid=True), ForeignKey("push.Channels.id")), + Column("groupsId", UUID(as_uuid=True), ForeignKey("push.Groups.id")), schema="push", ) channel_members = Table( "channels_members__users", PostgresDataSource.Base.metadata, - Column("channelsPrimaryKey", Integer, ForeignKey("push.Channels.primaryKey")), - Column("usersUsername", Integer, ForeignKey("push.Users.username")), + Column("channelsId", UUID(as_uuid=True), ForeignKey("push.Channels.id")), + Column("usersId", UUID(as_uuid=True), ForeignKey("push.Users.id")), schema="push", ) preferences_devices = Table( "preferences_devices__devices", PostgresDataSource.Base.metadata, - Column("preferencesId", Integer, ForeignKey("push.Preferences.id")), - Column("devicesId", Integer, ForeignKey("push.Devices.id")), + Column("preferencesId", UUID(as_uuid=True), ForeignKey("push.Preferences.id")), + Column("devicesId", UUID(as_uuid=True), ForeignKey("push.Devices.id")), schema="push", ) preferences_disabled_channels = Table( "preferences_disabled_channels__channels", PostgresDataSource.Base.metadata, - Column("preferencesId", Integer, ForeignKey("push.Preferences.id")), - Column("channelsPrimaryKey", Integer, ForeignKey("push.Channels.primaryKey")), + Column("preferencesId", UUID(as_uuid=True), ForeignKey("push.Preferences.id")), + Column("channelsId", UUID(as_uuid=True), ForeignKey("push.Channels.id")), schema="push", ) @@ -189,9 +193,9 @@ class Device(PostgresDataSource.Base): __tablename__ = "Devices" __table_args__ = {"schema": "push", "extend_existing": True} - id = Column(Integer, primary_key=True) + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column(String) - userUsername = Column(String, ForeignKey("push.Users.username")) + userId = Column(UUID(as_uuid=True), ForeignKey("push.Users.id")) info = Column(String) type = Column(String) subType = Column(String) @@ -203,10 +207,10 @@ class Preference(PostgresDataSource.Base): __tablename__ = "Preferences" __table_args__ = {"schema": "push", "extend_existing": True} - id = Column(Integer, primary_key=True) + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) type = Column(String) - userUsername = Column(String, ForeignKey("push.Users.username")) - targetPrimaryKey = Column(Integer) + userId = Column(UUID(as_uuid=True), ForeignKey("push.Users.id")) + targetId = Column(String) notificationPriority = Column(String) rangeStart = Column(Time) rangeEnd = Column(Time) @@ -219,9 +223,8 @@ class Channel(PostgresDataSource.Base): __tablename__ = "Channels" __table_args__ = {"schema": "push", "extend_existing": True} - - primaryKey = Column(Integer, primary_key=True) - id = Column(String) + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + slug = Column(String) name = Column(String) groups = relationship("Group", secondary=channel_groups) members = relationship("User", secondary=channel_members) @@ -233,7 +236,7 @@ class Group(PostgresDataSource.Base): __tablename__ = "Groups" __table_args__ = {"schema": "push", "extend_existing": True} - id = Column(String, primary_key=True) + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) groupIdentifier = Column(String) @@ -243,8 +246,8 @@ class UserDailyNotification(PostgresDataSource.Base): __tablename__ = "UserDailyNotifications" __table_args__ = {"schema": "push", "extend_existing": True} - userId = Column(String, primary_key=True) - notificationId = Column(Integer) + userId = Column(UUID(as_uuid=True), primary_key=True) + notificationId = Column(UUID(as_uuid=True)) date = Column(Date, primary_key=True) time = Column(Time, primary_key=True) diff --git a/notifications_routing/router.py b/notifications_routing/router.py index 471edf91b218fa2b485bc0d9a0b72078738c2657..abbc1766b188d0bc8a85160cacc0109fe1772c78 100644 --- a/notifications_routing/router.py +++ b/notifications_routing/router.py @@ -66,11 +66,14 @@ class Router(megabus.Listener): return { str(OutputMessageKeys.CHANNEL_ID): message_json[str(InputMessageKeys.TARGET)][ - str(InputMessageKeys.PRIMARYKEY) + str(InputMessageKeys.CHANNEL_ID) ], str(OutputMessageKeys.CHANNEL_NAME): message_json[str(InputMessageKeys.TARGET)][ str(InputMessageKeys.CHANNEL_NAME) ], + str(OutputMessageKeys.CHANNEL_SLUG): message_json[str(InputMessageKeys.TARGET)][ + str(InputMessageKeys.CHANNEL_SLUG) + ], str(OutputMessageKeys.PRIORITY): message_json[str(InputMessageKeys.PRIORITY)], str(OutputMessageKeys.CREATED_TIMESTAMP): message_json[str(InputMessageKeys.SENT_AT)], str(OutputMessageKeys.MESSAGE_BODY): message_json[str(InputMessageKeys.BODY)], @@ -92,6 +95,7 @@ class Router(megabus.Listener): channel_users = get_unique_elements(channel_users, self.data_source.USER_ID) if not channel_users: + logging.debug("no channel_users for channel %s", message[OutputMessageKeys.CHANNEL_ID]) return for user in channel_users: diff --git a/notifications_routing/utils.py b/notifications_routing/utils.py index 8a830cf96a7d8e8fa48b61e0940fe32efa979844..3aaea60d065269d5ac43df0b3864de4555930000 100644 --- a/notifications_routing/utils.py +++ b/notifications_routing/utils.py @@ -16,8 +16,9 @@ class InputMessageKeys(StrEnum): """Incoming message keys.""" TARGET = "target" - PRIMARYKEY = "primaryKey" + CHANNEL_ID = "id" CHANNEL_NAME = "name" + CHANNEL_SLUG = "slug" PRIORITY = "priority" SENT_AT = "sentAt" BODY = "body" @@ -31,6 +32,7 @@ class OutputMessageKeys(StrEnum): CHANNEL_ID = "channel_id" CHANNEL_NAME = "channel_name" + CHANNEL_SLUG = "channel_slug" PRIORITY = "priority" CREATED_TIMESTAMP = "created_timestamp" MESSAGE_BODY = "message_body"