diff --git a/Product_MicroService_Group3/app/controllers/__pycache__/updateProductController.cpython-311.pyc b/Product_MicroService_Group3/app/controllers/__pycache__/updateProductController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a851b605b4771ad33e986818477a8d99267d3c2 Binary files /dev/null and b/Product_MicroService_Group3/app/controllers/__pycache__/updateProductController.cpython-311.pyc differ diff --git a/Product_MicroService_Group3/app/controllers/addReviewController.py b/Product_MicroService_Group3/app/controllers/addReviewController.py index 1a2b5d3518a69fe63d5c920051bdd94e6aa0455f..4f85e35e1ded97b201011a4e17ba815135224f7e 100644 --- a/Product_MicroService_Group3/app/controllers/addReviewController.py +++ b/Product_MicroService_Group3/app/controllers/addReviewController.py @@ -6,7 +6,8 @@ import requests add_review_bp = Blueprint("addReview",__name__) - +#This connects to the user microservice to get username when a user wants to add a review +#It uses a get method to get the product id @add_review_bp.route("/product/<int:productID>/addReview", methods=["GET"]) def get_username_from_user_microservice(productID): diff --git a/Product_MicroService_Group3/app/controllers/getReviewsController.py b/Product_MicroService_Group3/app/controllers/getReviewsController.py new file mode 100644 index 0000000000000000000000000000000000000000..49b5f7c69bf6672aef2169449ab49050d84efac0 --- /dev/null +++ b/Product_MicroService_Group3/app/controllers/getReviewsController.py @@ -0,0 +1,44 @@ +from flask import Blueprint, jsonify, request, json, session +from models.getReviews import get_reviews + +from kafka import KafkaProducer + +#This gets reviews posted by a certain user +get_review_bp = Blueprint("getReview",__name__) + +@get_review_bp.route("/product/getReview", methods=["POST"]) +def get_review(): + + user_id = session.get("user_id") + + if user_id: + if request.method == 'POST': + + #data = request.get_json() + #review = data.get("review") + + get_reviews_by_user = get_reviews(user_id) + + send_review_message(get_reviews_by_user) + + return({"reviews" : get_reviews_by_user}) + + else: + return {"error" : "null"} + + else: + return {"error" : "You need to be logged in to add a review"} + + +producer = KafkaProducer(bootstrap_servers = "localhost:9092") + +def send_review_message(reviews): + metadata =producer.send("customer_reviews", json.dumps(reviews).encode("utf_8")) + try: + record_metadata = metadata.get(timeout=10) + print("Message sent successfully!") + print("Topic:", record_metadata.topic) + print("Partition:", record_metadata.partition) + print("Offset:", record_metadata.offset) + except Exception as e: + print("Failed to send message:", e) \ No newline at end of file diff --git a/Product_MicroService_Group3/app/controllers/updateProductController.py b/Product_MicroService_Group3/app/controllers/updateProductController.py new file mode 100644 index 0000000000000000000000000000000000000000..70d31a74e24364a5ac7a0d7f9e90ede23b20d0b3 --- /dev/null +++ b/Product_MicroService_Group3/app/controllers/updateProductController.py @@ -0,0 +1,54 @@ +from flask import Blueprint, jsonify, request, json, session +from models.updateProduct import update_product_info +from publishers.kafkaPublishers import publish_product_updated_event + +import requests + + +update_product_bp = Blueprint("updateProduct",__name__) + + +@update_product_bp.route("/product/updateProduct", methods=["POST"]) +def update_product(): + + user_id = session.get("user_id") + + if user_id: + if request.method == 'POST': + + data = request.get_json() + price = data.get("price") + quantity = data.get("quantity") + product_id = data.get("product_id") + #username = session.get('username') + + if isinstance(data.get("price"), (int, float)): + + if isinstance(data.get("quantity"), int): + info = { + "quantity" : quantity, + "price" : price, + "product_id" : product_id + } + + update = update_product_info(info) + if "message" in update: + event_data = {"quantity" : quantity, "price" : price, "product_id" : product_id} + publish_product_updated_event(event_data) + + return {"Update Status": update} + else: + return {"error" : "error"} + else: + + return {"error" : "Quantity should be int"} + else: + return{"error" : "Price should be a number"} + + + + else: + return {"error" : "null"} + + else: + return {"error" : "You need to be logged in to add a review"} \ No newline at end of file diff --git a/Product_MicroService_Group3/app/index.py b/Product_MicroService_Group3/app/index.py index 79afca3d4836e65a64c37d47fb3141e77acb26ea..676b86d8db8a3ab0bfc301378d4f1af0abc75a89 100644 --- a/Product_MicroService_Group3/app/index.py +++ b/Product_MicroService_Group3/app/index.py @@ -11,7 +11,8 @@ import subscribers from controllers.getProductController import display_product_bp from controllers.addReviewController import add_review_bp from controllers.productHomeController import product_home_bp -from controllers.getReviews import get_review_bp +from controllers.getReviewsController import get_review_bp +from controllers.updateProductController import update_product_bp @@ -49,6 +50,7 @@ app.register_blueprint(display_product_bp) app.register_blueprint(add_review_bp) app.register_blueprint(product_home_bp) app.register_blueprint(get_review_bp) +app.register_blueprint(update_product_bp) diff --git a/Product_MicroService_Group3/app/models/__pycache__/updateProduct.cpython-311.pyc b/Product_MicroService_Group3/app/models/__pycache__/updateProduct.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68e89d2ebd24e81165e2c46e12cb0eb9b6280211 Binary files /dev/null and b/Product_MicroService_Group3/app/models/__pycache__/updateProduct.cpython-311.pyc differ diff --git a/Product_MicroService_Group3/app/models/updateProduct.py b/Product_MicroService_Group3/app/models/updateProduct.py new file mode 100644 index 0000000000000000000000000000000000000000..4ad88367ed92d9a0bcd10de2e7b7cc8eab2053c8 --- /dev/null +++ b/Product_MicroService_Group3/app/models/updateProduct.py @@ -0,0 +1,45 @@ +import pyodbc +from flask import jsonify +from models.database_connection import connect_db + + + +def update_product_info(data): + + try: #error handling + + connection = connect_db() + cursor = connection.cursor() + + + #insert data into reviews and ratings table + update_product_query = '''UPDATE dbo.ProductCatalog +SET + Price = CASE WHEN ? IS NOT NULL THEN ? ELSE Price END, + StockQuantity = CASE WHEN ? IS NOT NULL THEN ? ELSE StockQuantity END +WHERE + ProductID = ?;''' + cursor.execute(update_product_query, (data["price"], data["price"], data["quantity"], data["quantity"], data["product_id"])) + + + + #commit changes to database if no errors + connection.commit() + + return {"message" : "Product updated successfully"} + + except pyodbc.Error as e: #more error handling + print(f"Database error in add_review: {e}") + connection.rollback() + return {"Error" : "Database error"} + + except Exception as e: #more error handling + print(f"Unexpected error occured in add_review: {e}") + connection.rollback() + return {"Error" : "Unexpected error"} + + finally: + if cursor: + cursor.close() + if connection: + connection.close() \ No newline at end of file diff --git a/Product_MicroService_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-311.pyc b/Product_MicroService_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0dc8ca0740bb9e53a5d54a2c55ad96fb36f17dbe Binary files /dev/null and b/Product_MicroService_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-311.pyc differ diff --git a/Product_MicroService_Group3/app/publishers/kafkaPublishers.py b/Product_MicroService_Group3/app/publishers/kafkaPublishers.py new file mode 100644 index 0000000000000000000000000000000000000000..20018a03a2dfd3dd9ffb2be582a4263f85ebdae1 --- /dev/null +++ b/Product_MicroService_Group3/app/publishers/kafkaPublishers.py @@ -0,0 +1,44 @@ +from kafka import KafkaProducer +from kafka.admin import KafkaAdminClient, NewTopic + +import json + +producer = KafkaProducer(bootstrap_servers="localhost:9092") + + +#Creates the topic +def create_product_updated_topic(): + # Create KafkaAdminClient instance + admin_client = KafkaAdminClient(bootstrap_servers="localhost:9092") + + # Define the topic name and configuration + topic_name = "product_updated_topic" + num_partitions = 1 + replication_factor = 1 + + # Retrieve the list of existing topics + topic_metadata = admin_client.list_topics() + + # Check if the topic already exists + if topic_name not in topic_metadata: + # Define the configuration for the new topic + new_topic = NewTopic(name=topic_name, num_partitions=num_partitions, replication_factor=replication_factor) + # Create the new topic + admin_client.create_topics(new_topics=[new_topic], validate_only=False) + + +#Function is called in updateProfileControllers.py +def publish_product_updated_event(event_data): + # Serialize the event data to JSON + event_json = json.dumps(event_data) + # Publish the event to the Kafka topic + data_to_send = producer.send("product_updated_topic", value=event_json.encode("utf-8")) + try: + record_metadata = data_to_send.get(timeout=10) + print("Message sent successfully!") + print("Topic:", record_metadata.topic) + print("Partition:", record_metadata.partition) + print("Offset:", record_metadata.offset) + except Exception as e: + print("Failed to send message:", e) + producer.flush() \ No newline at end of file