diff --git a/.gitignore b/.gitignore index 922c5b0..8d9d204 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +*firebase.json +*firebase_test.json +*google_cloud.json +services/user_service/env/ +services/user_service/__pycache__/ services/api_service/.env.dev key.json services/eventservice/target diff --git a/services/user_service/Dockerfile b/services/user_service/Dockerfile new file mode 100644 index 0000000..b242f9c --- /dev/null +++ b/services/user_service/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.8 + +WORKDIR /user_service + +COPY requirements.txt . + +RUN pip3 install -r requirements.txt + +COPY . . + +CMD ["python3", "main.py"] diff --git a/services/user_service/database_connector.py b/services/user_service/database_connector.py new file mode 100644 index 0000000..fc9ca34 --- /dev/null +++ b/services/user_service/database_connector.py @@ -0,0 +1,110 @@ +import firebase_admin +from firebase_admin.exceptions import FirebaseError +from firebase_admin import credentials +from firebase_admin import db + + +class DatabaseAdmin: + + def __init__(self,databaseURL, credentials_path): + cred = credentials.Certificate(credentials_path) + firebase_admin.initialize_app(cred, + { + 'databaseURL' : databaseURL, + }) + self.__users_ref = db.reference("users") + + def get_all_users(self): + try: + if self.__users_ref.get() is None: + return list() + return self.__users_ref.get() + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + return list() + + + def get_user_by_id(self, id): + try: + if self.__users_ref.child(id).get() is None: + return list() + return self.__users_ref.child(id).get() + except ValueError as e: + print("###EROR received : " + str(e)) + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + return list() + + + def get_user_by_email(self, email): + try: + for user_id in self.get_user_ids(): + if email == self.__users_ref.child(user_id).child("email").get(): + return self.__users_ref.child(user_id).get() + except ValueError as e: + print("###EROR received : " + str(e)) + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + return list() + + def get_user_ids(self): + try: + if self.__users_ref.get() is None: + return list() + ids = [i for i in self.__users_ref.get()] + return ids + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + return list() + + + def save_user(self, user_info): + try: + return self.__users_ref.push(user_info).key + except ValueError as e: + print("###EROR received : " + str(e)) + except TypeError as e: + print("###EROR received : " + str(e)) + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + + + def update_user(self, user_id, user_info): + try: + self.__users_ref.child(user_id).set(user_info) + except ValueError as e: + print("###EROR received : " + str(e)) + except TypeError as e: + print("###EROR received : " + str(e)) + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + + + def delete_user_by_id(self, user_id): + try: + self.__users_ref.child(user_id).delete() + except ValueError as e: + print("###EROR received : " + str(e)) + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + + + def delete_user_by_email(self, email): + try: + for i in self.get_user_ids(): + if email == self.__users_ref.child(i).child("email").get(): + self.delete_user_by_id(i) + except ValueError as e: + print("###EROR received : " + str(e)) + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) + + + def drop_users(self): + try: + for user_id in self.get_user_ids(): + self.__users_ref.child(user_id).delete() + except ValueError as e: + print("###EROR received : " + str(e)) + except FirebaseError as e: + print("###Connection lost. EROR received : " + str(e)) diff --git a/services/user_service/main.py b/services/user_service/main.py new file mode 100644 index 0000000..1a18ae7 --- /dev/null +++ b/services/user_service/main.py @@ -0,0 +1,5 @@ +import subscriber +import publisher +import database_connector + +print("User Service entry point") diff --git a/services/user_service/mocker.py b/services/user_service/mocker.py new file mode 100644 index 0000000..97f8dd6 --- /dev/null +++ b/services/user_service/mocker.py @@ -0,0 +1,28 @@ +import random +from faker import Faker + +images = [ + "https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.vectorstock.com%2Froyalty-free-vector%2Fflat-business-man-user-profile-avatar-icon-vector-4333097&psig=AOvVaw0WMass4DSBWEHhXOqpRWN5&ust=1637053775349000&source=images&cd=vfe&ved=0CAsQjRxqFwoTCNi7qNuCmvQCFQAAAAAdAAAAABAP", + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHL-ELbysJgVyYIJvfLMMbCZFxuLkqKe_iYBtHcvFw1VJX2RjlLA1xXina7Mn75Puo5Yw&usqp=CAU", + "https://www.seekpng.com/png/full/356-3562377_personal-user.png", + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSx7FfWrqJ5ro7SdxlBsnmCo_mwrnRly5mHUg&usqp=CAU" +] + +def get_mocked_users(N = 1): + fake = Faker() + users = list() + for i in range(N): + users.append( + { + "name" : fake.first_name(), + "surname" : fake.last_name(), + "password" : fake.password(), + "email" : fake.email(), + "phone" : fake.phone_number(), + "photo" : random.choice(images), + "age" : random.randint(1, 100), + "description" : fake.text(), + "interests" : fake.words(), + } + ) + return users diff --git a/services/user_service/publisher.py b/services/user_service/publisher.py new file mode 100644 index 0000000..a26175a --- /dev/null +++ b/services/user_service/publisher.py @@ -0,0 +1,22 @@ +import os +import json +from google.cloud import pubsub_v1 + +os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = os.getcwd() + "/google_cloud.json" + + +def test_publisher(): + project_id = "lohfinder-app" + topic_id = "hello_topic" + + publisher = pubsub_v1.PublisherClient() + topic_path = publisher.topic_path(project_id, topic_id) + + data = { + 1: "Data for the first method", + } + + message = json.dumps(data).encode("utf-8") + + res = publisher.publish(topic_path, message) + print(f"published message: {res.result()}") \ No newline at end of file diff --git a/services/user_service/requirements.txt b/services/user_service/requirements.txt new file mode 100644 index 0000000..d3dde28 --- /dev/null +++ b/services/user_service/requirements.txt @@ -0,0 +1,4 @@ +firebase_admin==5.0.3 +google-cloud-pubsub +pytest +faker \ No newline at end of file diff --git a/services/user_service/subscriber.py b/services/user_service/subscriber.py new file mode 100644 index 0000000..cbe373a --- /dev/null +++ b/services/user_service/subscriber.py @@ -0,0 +1,26 @@ +import os +from google.cloud import pubsub_v1 + +os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = os.getcwd() + "/google_cloud.json" + + +def test_subscriber(): + subscriber = pubsub_v1.SubscriberClient() + subscription_path = 'projects/lohyna-user-service/subscriptions/create_user-sub' + + print(f"Listening messages on {subscription_path}") + + def callback(message): + print(f"Received message : {message}") + print(f"Data : {message.data}") + print(type(message)) + message.ack() + + user_pull = subscriber.subscribe(subscription_path, callback = callback) + + with subscriber: + try: + user_pull.result() + except: + user_pull.cancel() + user_pull.result() \ No newline at end of file diff --git a/services/user_service/test_user_service.py b/services/user_service/test_user_service.py new file mode 100644 index 0000000..5ad6dd6 --- /dev/null +++ b/services/user_service/test_user_service.py @@ -0,0 +1,81 @@ + +from database_connector import DatabaseAdmin +import mocker + + +databaseURL = "https://lohyna-user-service-default-rtdb.firebaseio.com/" +credentials_path = "firebase_test.json" +database_manager = DatabaseAdmin(databaseURL, credentials_path) + + +def test_get_all_users(): + print("Running test test_get_all_users") + database_manager.drop_users() + count_of_users = 3 + for i in mocker.get_mocked_users(count_of_users): + database_manager.save_user(i) + print(f"STEP 1: count of the users after clearing table should be equal to COUNT_OF_USERS = {count_of_users}") + assert count_of_users == len(database_manager.get_all_users()) + + +def test_delete_user_by_email(): + print("Running test test_delete_user_by_email") + user = mocker.get_mocked_users()[0] + user_email = user["email"] + database_manager.save_user(user) + print("STEP 1: user has been added into database") + assert database_manager.get_user_by_email(user_email)["email"] == user_email + database_manager.delete_user_by_email(user_email) + print("STEP 2: After deleting by email user is not more stored") + assert database_manager.get_user_by_email(user_email) == [] + + +def test_delete_user_by_id(): + print("Running test test_delete_user_by_id") + user = mocker.get_mocked_users()[0] + user_id = database_manager.save_user(user) + print("STEP 1: User has been saved into database") + assert database_manager.get_user_by_id(user_id) != [] + database_manager.delete_user_by_id(user_id) + print("STEP 2: User has been deleted from database") + assert database_manager.get_user_by_id(user_id) == [] + + +def test_create_user(): + print("Running test test_create_user") + user = mocker.get_mocked_users()[0] + id = database_manager.save_user(user) + print("STEP 1: User has been saved into database") + assert database_manager.get_user_by_id(id) != None + + +def test_update_user(): + print("Running test test_update_user") + user = mocker.get_mocked_users()[0] + id = database_manager.save_user(user) + print("STEP 1: User has been saved into database") + assert database_manager.get_user_by_id(id) != None + user["age"] = 100 + user["email"] = "test@gmail.com" + user["interests"].append("one more thing") + database_manager.update_user(id, user) + updated_user = database_manager.get_user_by_id(id) + print("STEP 2: User age has been changed") + assert updated_user["age"] == 100 + print("STEP 2: User email has been changed") + assert updated_user["email"] == "test@gmail.com" + print("STEP 4: User interests has been changed") + assert "one more thing" in updated_user["interests"] + + +def test_drop_users(): + print("Running test test_drop_users") + count_of_users = 10 + users = mocker.get_mocked_users(count_of_users) + print("STEP 1: Database contains users") + assert database_manager.get_all_users() != [] + for i in users: + database_manager.save_user(i) + database_manager.drop_users() + print(f"STEP 2: After populating {count_of_users} database is cleared") + assert database_manager.get_all_users() == []