From 3a9b24d065bb78ac896d54988e5539e0bd9a14d0 Mon Sep 17 00:00:00 2001 From: acidmikk Date: Tue, 21 Nov 2023 21:56:09 +0400 Subject: [PATCH 1/7] init commit --- basharin_sevastyan_lab_3/docker-compose.yaml | 43 +++++++++++++++++++ .../message_app/Dockerfile | 8 ++++ basharin_sevastyan_lab_3/message_app/main.py | 0 .../message_app/requirements.txt | 2 + basharin_sevastyan_lab_3/nginx.conf | 28 ++++++++++++ basharin_sevastyan_lab_3/user_app/Dockerfile | 8 ++++ basharin_sevastyan_lab_3/user_app/main.py | 6 +++ .../user_app/requirements.txt | 2 + 8 files changed, 97 insertions(+) create mode 100644 basharin_sevastyan_lab_3/docker-compose.yaml create mode 100644 basharin_sevastyan_lab_3/message_app/Dockerfile create mode 100644 basharin_sevastyan_lab_3/message_app/main.py create mode 100644 basharin_sevastyan_lab_3/message_app/requirements.txt create mode 100644 basharin_sevastyan_lab_3/nginx.conf create mode 100644 basharin_sevastyan_lab_3/user_app/Dockerfile create mode 100644 basharin_sevastyan_lab_3/user_app/main.py create mode 100644 basharin_sevastyan_lab_3/user_app/requirements.txt diff --git a/basharin_sevastyan_lab_3/docker-compose.yaml b/basharin_sevastyan_lab_3/docker-compose.yaml new file mode 100644 index 0000000..1140c63 --- /dev/null +++ b/basharin_sevastyan_lab_3/docker-compose.yaml @@ -0,0 +1,43 @@ +version: '3' + +services: + nginx: + image: nginx:latest + ports: + - 80:80 + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + restart: always + depends_on: + - product-service + - order-service + networks: + - mynetwork + + db: + image: postgres:latest + ports: + - 5432:5432 + environment: + POSTGRES_PASSWORD: admin + POSTGRES_USER: admin + POSTGRES_DB: message-api + volumes: + - ./database.sql:/docker-entrypoint-initdb.d/database.sql + restart: always + networks: + - mynetwork + + user_app: + build: + context: /user_app + dockerfile: Dockerfile + + message_app: + build: + context: /message_app + dockerfile: Dockerfile + +networks: + mynetwork: + driver: bridge \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/message_app/Dockerfile b/basharin_sevastyan_lab_3/message_app/Dockerfile new file mode 100644 index 0000000..77d7b3c --- /dev/null +++ b/basharin_sevastyan_lab_3/message_app/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.9 +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY . . +COPY var/data /var/data +COPY var/result /var/result +CMD ["python", "main.py"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/message_app/main.py b/basharin_sevastyan_lab_3/message_app/main.py new file mode 100644 index 0000000..e69de29 diff --git a/basharin_sevastyan_lab_3/message_app/requirements.txt b/basharin_sevastyan_lab_3/message_app/requirements.txt new file mode 100644 index 0000000..5beea3b --- /dev/null +++ b/basharin_sevastyan_lab_3/message_app/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.0 +Werkzeug==3.0.1 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/nginx.conf b/basharin_sevastyan_lab_3/nginx.conf new file mode 100644 index 0000000..13ebcea --- /dev/null +++ b/basharin_sevastyan_lab_3/nginx.conf @@ -0,0 +1,28 @@ +events { + worker_connections 1024; +} + +http { + + upstream user-service { + server product-service:8080; + } + upstream message-service { + server order-service:8081; + } + + server { + + listen 80; + listen [::]:80; + server_name localhost; + + location /user-service/ { + proxy_pass http://user-service/; + } + + location /message-service/ { + proxy_pass http://message-service/; + } + } +} \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_app/Dockerfile b/basharin_sevastyan_lab_3/user_app/Dockerfile new file mode 100644 index 0000000..77d7b3c --- /dev/null +++ b/basharin_sevastyan_lab_3/user_app/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.9 +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY . . +COPY var/data /var/data +COPY var/result /var/result +CMD ["python", "main.py"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_app/main.py b/basharin_sevastyan_lab_3/user_app/main.py new file mode 100644 index 0000000..46d2a8f --- /dev/null +++ b/basharin_sevastyan_lab_3/user_app/main.py @@ -0,0 +1,6 @@ +from flask import Flask + +app = Flask(__name__) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/basharin_sevastyan_lab_3/user_app/requirements.txt b/basharin_sevastyan_lab_3/user_app/requirements.txt new file mode 100644 index 0000000..5beea3b --- /dev/null +++ b/basharin_sevastyan_lab_3/user_app/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.0 +Werkzeug==3.0.1 \ No newline at end of file -- 2.25.1 From 8ff2a44649e2edc514f4b816d949374ac03ed0a0 Mon Sep 17 00:00:00 2001 From: acidmikk Date: Tue, 21 Nov 2023 23:45:46 +0400 Subject: [PATCH 2/7] ready< not test --- basharin_sevastyan_lab_3/README.md | 71 ++++++++++++ basharin_sevastyan_lab_3/docker-compose.yaml | 58 ++++------ .../message_app/Dockerfile | 8 -- basharin_sevastyan_lab_3/message_app/main.py | 0 .../message_app/requirements.txt | 2 - basharin_sevastyan_lab_3/nginx.conf | 28 ----- basharin_sevastyan_lab_3/nginx/Dockerfile | 4 + basharin_sevastyan_lab_3/nginx/nginx.conf | 19 ++++ .../order_service/Dockerfile | 6 + .../order_service/order_service.py | 60 ++++++++++ .../order_service/requirements.txt | 2 + basharin_sevastyan_lab_3/user_app/Dockerfile | 8 -- basharin_sevastyan_lab_3/user_app/main.py | 6 - .../user_app/requirements.txt | 2 - .../user_service/Dockerfile | 6 + .../user_service/requirements.txt | 2 + .../user_service/user_service.py | 107 ++++++++++++++++++ 17 files changed, 301 insertions(+), 88 deletions(-) create mode 100644 basharin_sevastyan_lab_3/README.md delete mode 100644 basharin_sevastyan_lab_3/message_app/Dockerfile delete mode 100644 basharin_sevastyan_lab_3/message_app/main.py delete mode 100644 basharin_sevastyan_lab_3/message_app/requirements.txt delete mode 100644 basharin_sevastyan_lab_3/nginx.conf create mode 100644 basharin_sevastyan_lab_3/nginx/Dockerfile create mode 100644 basharin_sevastyan_lab_3/nginx/nginx.conf create mode 100644 basharin_sevastyan_lab_3/order_service/Dockerfile create mode 100644 basharin_sevastyan_lab_3/order_service/order_service.py create mode 100644 basharin_sevastyan_lab_3/order_service/requirements.txt delete mode 100644 basharin_sevastyan_lab_3/user_app/Dockerfile delete mode 100644 basharin_sevastyan_lab_3/user_app/main.py delete mode 100644 basharin_sevastyan_lab_3/user_app/requirements.txt create mode 100644 basharin_sevastyan_lab_3/user_service/Dockerfile create mode 100644 basharin_sevastyan_lab_3/user_service/requirements.txt create mode 100644 basharin_sevastyan_lab_3/user_service/user_service.py diff --git a/basharin_sevastyan_lab_3/README.md b/basharin_sevastyan_lab_3/README.md new file mode 100644 index 0000000..e4c6c46 --- /dev/null +++ b/basharin_sevastyan_lab_3/README.md @@ -0,0 +1,71 @@ +``` +basharin_sevastyan_lab_3/ +|-- user_service/ +| |-- Dockerfile +| |-- requirements.txt +| |-- user_service.py +|-- order_service/ +| |-- Dockerfile +| |-- requirements.txt +| |-- order_service.py +|-- nginx/ +| |-- Dockerfile +| |-- nginx.conf +|-- docker-compose.yml +``` + +```yaml +version: '3' + +services: + user-service: + build: + context: ./user_service + ports: + - "5001:5001" + depends_on: + - rabbitmq + + order-service: + build: + context: ./order_service + ports: + - "5002:5002" + depends_on: + - rabbitmq + + rabbitmq: + image: "rabbitmq:management" + ports: + - "5672:5672" + - "15672:15672" + + nginx: + build: + context: ./nginx + ports: + - "80:80" + depends_on: + - user-service + - order-service +``` + +```dockerfile +# user_service/Dockerfile +FROM python:3.11 +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +CMD ["python", "user_service.py"] +``` + +```dockerfile +# user_service/Dockerfile +FROM python:3.11 +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +CMD ["python", "order_service.py"] +``` \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/docker-compose.yaml b/basharin_sevastyan_lab_3/docker-compose.yaml index 1140c63..104c23e 100644 --- a/basharin_sevastyan_lab_3/docker-compose.yaml +++ b/basharin_sevastyan_lab_3/docker-compose.yaml @@ -1,43 +1,33 @@ version: '3' services: - nginx: - image: nginx:latest + user-service: + build: + context: ./user_service ports: - - 80:80 - volumes: - - ./nginx.conf:/etc/nginx/nginx.conf - restart: always + - "5001:5001" depends_on: - - product-service - - order-service - networks: - - mynetwork + - rabbitmq - db: - image: postgres:latest + order-service: + build: + context: ./order_service ports: - - 5432:5432 - environment: - POSTGRES_PASSWORD: admin - POSTGRES_USER: admin - POSTGRES_DB: message-api - volumes: - - ./database.sql:/docker-entrypoint-initdb.d/database.sql - restart: always - networks: - - mynetwork + - "5002:5002" + depends_on: + - rabbitmq - user_app: + rabbitmq: + image: "rabbitmq:management" + ports: + - "5672:5672" + - "15672:15672" + + nginx: build: - context: /user_app - dockerfile: Dockerfile - - message_app: - build: - context: /message_app - dockerfile: Dockerfile - -networks: - mynetwork: - driver: bridge \ No newline at end of file + context: ./nginx + ports: + - "80:80" + depends_on: + - user-service + - order-service diff --git a/basharin_sevastyan_lab_3/message_app/Dockerfile b/basharin_sevastyan_lab_3/message_app/Dockerfile deleted file mode 100644 index 77d7b3c..0000000 --- a/basharin_sevastyan_lab_3/message_app/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM python:3.9 -WORKDIR /app -COPY requirements.txt . -RUN pip install -r requirements.txt -COPY . . -COPY var/data /var/data -COPY var/result /var/result -CMD ["python", "main.py"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/message_app/main.py b/basharin_sevastyan_lab_3/message_app/main.py deleted file mode 100644 index e69de29..0000000 diff --git a/basharin_sevastyan_lab_3/message_app/requirements.txt b/basharin_sevastyan_lab_3/message_app/requirements.txt deleted file mode 100644 index 5beea3b..0000000 --- a/basharin_sevastyan_lab_3/message_app/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Flask==3.0.0 -Werkzeug==3.0.1 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/nginx.conf b/basharin_sevastyan_lab_3/nginx.conf deleted file mode 100644 index 13ebcea..0000000 --- a/basharin_sevastyan_lab_3/nginx.conf +++ /dev/null @@ -1,28 +0,0 @@ -events { - worker_connections 1024; -} - -http { - - upstream user-service { - server product-service:8080; - } - upstream message-service { - server order-service:8081; - } - - server { - - listen 80; - listen [::]:80; - server_name localhost; - - location /user-service/ { - proxy_pass http://user-service/; - } - - location /message-service/ { - proxy_pass http://message-service/; - } - } -} \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/nginx/Dockerfile b/basharin_sevastyan_lab_3/nginx/Dockerfile new file mode 100644 index 0000000..1434a93 --- /dev/null +++ b/basharin_sevastyan_lab_3/nginx/Dockerfile @@ -0,0 +1,4 @@ +FROM nginx +COPY nginx.conf /etc/nginx/nginx.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/basharin_sevastyan_lab_3/nginx/nginx.conf b/basharin_sevastyan_lab_3/nginx/nginx.conf new file mode 100644 index 0000000..2f4ae77 --- /dev/null +++ b/basharin_sevastyan_lab_3/nginx/nginx.conf @@ -0,0 +1,19 @@ +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/order_service/Dockerfile b/basharin_sevastyan_lab_3/order_service/Dockerfile new file mode 100644 index 0000000..46d249e --- /dev/null +++ b/basharin_sevastyan_lab_3/order_service/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11 +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +CMD ["python", "order_service.py"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/order_service/order_service.py b/basharin_sevastyan_lab_3/order_service/order_service.py new file mode 100644 index 0000000..376e354 --- /dev/null +++ b/basharin_sevastyan_lab_3/order_service/order_service.py @@ -0,0 +1,60 @@ +# order_service.py +from flask import Flask, request, jsonify +import pika +import json + +app = Flask(__name__) + +# Конфигурация RabbitMQ +connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) +channel = connection.channel() +channel.exchange_declare(exchange='microservices', exchange_type='direct') + + +# CRUD операции для заказов в order_service оставим здесь, чтобы он мог отправлять сообщения + +# CREATE +@app.route('/orders', methods=['POST']) +def create_order(): + data = request.get_json() + order = {'user_id': data['user_id'], 'product': data['product'], 'action': 'create'} + + # Отправка сообщения о создании заказа + channel.basic_publish(exchange='microservices', routing_key='order', body=json.dumps(order)) + + return jsonify(order), 201 + + +# READ +@app.route('/orders/', methods=['GET']) +def get_order(order_id): + # Реализация READ операции по желанию + return jsonify({'error': 'Read operation not implemented in order service'}), 501 + + +# UPDATE +@app.route('/orders/', methods=['PUT']) +def update_order(order_id): + data = request.get_json() + order = {'user_id': data['user_id'], 'product': data['product'], 'order_id': order_id, 'action': 'update'} + + # Отправка сообщения об обновлении заказа + channel.basic_publish(exchange='microservices', routing_key='order', body=json.dumps(order)) + + return jsonify(order) + + +# DELETE +@app.route('/orders/', methods=['DELETE']) +def delete_order(order_id): + user_id = request.args.get('user_id') + order = {'user_id': user_id, 'order_id': order_id, 'action': 'delete'} + + # Отправка сообщения об удалении заказа + channel.basic_publish(exchange='microservices', routing_key='order', body=json.dumps(order)) + + return jsonify({'result': True}) + + +if __name__ == '__main__': + app.run(port=5002) diff --git a/basharin_sevastyan_lab_3/order_service/requirements.txt b/basharin_sevastyan_lab_3/order_service/requirements.txt new file mode 100644 index 0000000..920c2a7 --- /dev/null +++ b/basharin_sevastyan_lab_3/order_service/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.0 +pika==1.3.2 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_app/Dockerfile b/basharin_sevastyan_lab_3/user_app/Dockerfile deleted file mode 100644 index 77d7b3c..0000000 --- a/basharin_sevastyan_lab_3/user_app/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM python:3.9 -WORKDIR /app -COPY requirements.txt . -RUN pip install -r requirements.txt -COPY . . -COPY var/data /var/data -COPY var/result /var/result -CMD ["python", "main.py"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_app/main.py b/basharin_sevastyan_lab_3/user_app/main.py deleted file mode 100644 index 46d2a8f..0000000 --- a/basharin_sevastyan_lab_3/user_app/main.py +++ /dev/null @@ -1,6 +0,0 @@ -from flask import Flask - -app = Flask(__name__) - -if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000) diff --git a/basharin_sevastyan_lab_3/user_app/requirements.txt b/basharin_sevastyan_lab_3/user_app/requirements.txt deleted file mode 100644 index 5beea3b..0000000 --- a/basharin_sevastyan_lab_3/user_app/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Flask==3.0.0 -Werkzeug==3.0.1 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/Dockerfile b/basharin_sevastyan_lab_3/user_service/Dockerfile new file mode 100644 index 0000000..467cb44 --- /dev/null +++ b/basharin_sevastyan_lab_3/user_service/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11 +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +CMD ["python", "user_service.py"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/requirements.txt b/basharin_sevastyan_lab_3/user_service/requirements.txt new file mode 100644 index 0000000..920c2a7 --- /dev/null +++ b/basharin_sevastyan_lab_3/user_service/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.0 +pika==1.3.2 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/user_service.py b/basharin_sevastyan_lab_3/user_service/user_service.py new file mode 100644 index 0000000..cd6e450 --- /dev/null +++ b/basharin_sevastyan_lab_3/user_service/user_service.py @@ -0,0 +1,107 @@ +# user_service.py +from flask import Flask, request, jsonify +import pika +import json + +app = Flask(__name__) + +# Конфигурация RabbitMQ +connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) +channel = connection.channel() +channel.exchange_declare(exchange='microservices', exchange_type='direct') + +users = [] + + +# Обработка сообщений о заказах +def process_order_message(ch, method, properties, body): + data = json.loads(body) + user_id = data.get('user_id') + + if data['action'] == 'create': + # Создание заказа у пользователя + user = next((user for user in users if user['id'] == user_id), None) + if user: + order_id = len(user.get('orders', [])) + 1 + order = {'id': order_id, 'product': data['product']} + user.setdefault('orders', []).append(order) + print(f"Order created for user {user_id}: {order}") + else: + print(f"User not found for order creation: {user_id}") + + elif data['action'] == 'update': + # Обновление заказа у пользователя + user = next((user for user in users if user['id'] == user_id), None) + if user: + order_id = data.get('order_id') + order = next((order for order in user['orders'] if order['id'] == order_id), None) + if order: + order['product'] = data['product'] + print(f"Order updated for user {user_id}: {order}") + else: + print(f"Order not found for update: {order_id}") + else: + print(f"User not found for order update: {user_id}") + + elif data['action'] == 'delete': + # Удаление заказа у пользователя + user = next((user for user in users if user['id'] == user_id), None) + if user: + order_id = data.get('order_id') + user['orders'] = [order for order in user.get('orders', []) if order['id'] != order_id] + print(f"Order deleted for user {user_id}: {order_id}") + else: + print(f"User not found for order deletion: {user_id}") + + +# Начало прослушивания сообщений о заказах +channel.queue_declare(queue='order_service', durable=True) +channel.queue_bind(exchange='microservices', queue='order_service', routing_key='order') +channel.basic_consume(queue='order_service', on_message_callback=process_order_message, auto_ack=True) + +print('User service is waiting for order messages. To exit press CTRL+C') +channel.start_consuming() + + +# CRUD операции для пользователей +# CREATE +@app.route('/users', methods=['POST']) +def create_user(): + data = request.get_json() + user = {'id': len(users) + 1, 'name': data['name']} + users.append(user) + return jsonify(user), 201 + + +# READ +@app.route('/users/', methods=['GET']) +def get_user(user_id): + user = next((user for user in users if user['id'] == user_id), None) + if user: + return jsonify(user) + else: + return jsonify({'error': 'User not found'}), 404 + + +# UPDATE +@app.route('/users/', methods=['PUT']) +def update_user(user_id): + user = next((user for user in users if user['id'] == user_id), None) + if user: + data = request.get_json() + user['name'] = data['name'] + return jsonify(user) + else: + return jsonify({'error': 'User not found'}), 404 + + +# DELETE +@app.route('/users/', methods=['DELETE']) +def delete_user(user_id): + global users + users = [user for user in users if user['id'] != user_id] + return jsonify({'result': True}) + + +if __name__ == '__main__': + app.run(port=5001) -- 2.25.1 From 83528356a1c301a9e951c8175d574794bd161777 Mon Sep 17 00:00:00 2001 From: acidmikk Date: Fri, 24 Nov 2023 07:55:12 +0400 Subject: [PATCH 3/7] worked nginx --- basharin_sevastyan_lab_3/docker-compose.yaml | 32 +++++++--- basharin_sevastyan_lab_3/nginx/nginx.conf | 30 +++++---- .../order_service/Dockerfile | 4 +- .../order_service/order_service.py | 10 +-- .../order_service/requirements.txt | 3 +- .../user_service/Dockerfile | 4 +- .../user_service/requirements.txt | 3 +- .../user_service/user_service.py | 64 +++++++++++-------- 8 files changed, 93 insertions(+), 57 deletions(-) diff --git a/basharin_sevastyan_lab_3/docker-compose.yaml b/basharin_sevastyan_lab_3/docker-compose.yaml index 104c23e..9a3d771 100644 --- a/basharin_sevastyan_lab_3/docker-compose.yaml +++ b/basharin_sevastyan_lab_3/docker-compose.yaml @@ -1,6 +1,15 @@ -version: '3' +version: '3.8' services: + rabbitmq: + image: "rabbitmq:management" + ports: + - "5672:5672" + - "15672:15672" + networks: + - my_network + restart: always + user-service: build: context: ./user_service @@ -8,6 +17,8 @@ services: - "5001:5001" depends_on: - rabbitmq + networks: + - my_network order-service: build: @@ -16,18 +27,21 @@ services: - "5002:5002" depends_on: - rabbitmq - - rabbitmq: - image: "rabbitmq:management" - ports: - - "5672:5672" - - "15672:15672" + networks: + - my_network nginx: - build: - context: ./nginx + image: nginx:latest ports: - "80:80" depends_on: - user-service - order-service + networks: + - my_network + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + +networks: + my_network: + driver: bridge \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/nginx/nginx.conf b/basharin_sevastyan_lab_3/nginx/nginx.conf index 2f4ae77..9bb0979 100644 --- a/basharin_sevastyan_lab_3/nginx/nginx.conf +++ b/basharin_sevastyan_lab_3/nginx/nginx.conf @@ -1,19 +1,27 @@ -worker_processes 1; - events { worker_connections 1024; } http { - include /etc/nginx/mime.types; - default_type application/octet-stream; + server { + listen 80; + listen [::]:80; + server_name localhost; - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 2048; + location /user-service/ { + proxy_pass http://user-service:5001/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } - include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-enabled/*; + location /order-service/ { + proxy_pass http://order-service:5002/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } } \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/order_service/Dockerfile b/basharin_sevastyan_lab_3/order_service/Dockerfile index 46d249e..3e8508e 100644 --- a/basharin_sevastyan_lab_3/order_service/Dockerfile +++ b/basharin_sevastyan_lab_3/order_service/Dockerfile @@ -2,5 +2,5 @@ FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -COPY . . -CMD ["python", "order_service.py"] \ No newline at end of file +COPY . /app +CMD ["gunicorn", "--bind", "0.0.0.0:5002", "order_service:app"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/order_service/order_service.py b/basharin_sevastyan_lab_3/order_service/order_service.py index 376e354..9d7c1c4 100644 --- a/basharin_sevastyan_lab_3/order_service/order_service.py +++ b/basharin_sevastyan_lab_3/order_service/order_service.py @@ -2,17 +2,17 @@ from flask import Flask, request, jsonify import pika import json +import time app = Flask(__name__) # Конфигурация RabbitMQ -connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) +time.sleep(20) +connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq')) channel = connection.channel() -channel.exchange_declare(exchange='microservices', exchange_type='direct') +channel.queue_declare(queue='order_queue', durable=True) -# CRUD операции для заказов в order_service оставим здесь, чтобы он мог отправлять сообщения - # CREATE @app.route('/orders', methods=['POST']) def create_order(): @@ -22,7 +22,7 @@ def create_order(): # Отправка сообщения о создании заказа channel.basic_publish(exchange='microservices', routing_key='order', body=json.dumps(order)) - return jsonify(order), 201 + return order, 201 # READ diff --git a/basharin_sevastyan_lab_3/order_service/requirements.txt b/basharin_sevastyan_lab_3/order_service/requirements.txt index 920c2a7..e949d43 100644 --- a/basharin_sevastyan_lab_3/order_service/requirements.txt +++ b/basharin_sevastyan_lab_3/order_service/requirements.txt @@ -1,2 +1,3 @@ Flask==3.0.0 -pika==1.3.2 \ No newline at end of file +pika==1.3.2 +gunicorn==21.2.0 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/Dockerfile b/basharin_sevastyan_lab_3/user_service/Dockerfile index 467cb44..f868a6a 100644 --- a/basharin_sevastyan_lab_3/user_service/Dockerfile +++ b/basharin_sevastyan_lab_3/user_service/Dockerfile @@ -2,5 +2,5 @@ FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -COPY . . -CMD ["python", "user_service.py"] \ No newline at end of file +COPY . /app +CMD ["gunicorn", "--bind", "0.0.0.0:5001", "user_service:app"] \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/requirements.txt b/basharin_sevastyan_lab_3/user_service/requirements.txt index 920c2a7..e949d43 100644 --- a/basharin_sevastyan_lab_3/user_service/requirements.txt +++ b/basharin_sevastyan_lab_3/user_service/requirements.txt @@ -1,2 +1,3 @@ Flask==3.0.0 -pika==1.3.2 \ No newline at end of file +pika==1.3.2 +gunicorn==21.2.0 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/user_service.py b/basharin_sevastyan_lab_3/user_service/user_service.py index cd6e450..a73ba14 100644 --- a/basharin_sevastyan_lab_3/user_service/user_service.py +++ b/basharin_sevastyan_lab_3/user_service/user_service.py @@ -1,16 +1,30 @@ # user_service.py +import time from flask import Flask, request, jsonify import pika import json +import threading app = Flask(__name__) +users = [] + # Конфигурация RabbitMQ -connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) -channel = connection.channel() -channel.exchange_declare(exchange='microservices', exchange_type='direct') - -users = [] +def connect_to_rabbitmq(): + retries = 5 + while retries > 0: + try: + connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq')) + channel = connection.channel() + channel.queue_declare(queue='order_service', durable=True) + #channel.queue_bind(queue='order_service', routing_key='order') + channel.basic_consume(queue='order_service', on_message_callback=process_order_message, auto_ack=True) + print('Waiting for messages. To exit press CTRL+C') + channel.start_consuming() + except pika.exceptions.AMQPConnectionError: + print("Failed to connect to RabbitMQ. Retrying...") + retries -= 1 + time.sleep(5) # Обработка сообщений о заказах @@ -54,23 +68,19 @@ def process_order_message(ch, method, properties, body): print(f"User not found for order deletion: {user_id}") -# Начало прослушивания сообщений о заказах -channel.queue_declare(queue='order_service', durable=True) -channel.queue_bind(exchange='microservices', queue='order_service', routing_key='order') -channel.basic_consume(queue='order_service', on_message_callback=process_order_message, auto_ack=True) - -print('User service is waiting for order messages. To exit press CTRL+C') -channel.start_consuming() - - # CRUD операции для пользователей # CREATE -@app.route('/users', methods=['POST']) -def create_user(): - data = request.get_json() - user = {'id': len(users) + 1, 'name': data['name']} - users.append(user) - return jsonify(user), 201 +@app.route('/users', methods=['GET']) +def show_users(): + return users + + +@app.route('/add_users/', methods=['POST']) +def create_user(name): + if request.method == 'POST': + user = {'id': len(users) + 1, 'name': name} + users.append(user) + return jsonify(user) # READ @@ -80,19 +90,18 @@ def get_user(user_id): if user: return jsonify(user) else: - return jsonify({'error': 'User not found'}), 404 + return jsonify({'error': 'User not found'}) # UPDATE -@app.route('/users/', methods=['PUT']) -def update_user(user_id): +@app.route('/users/_', methods=['PUT']) +def update_user(user_id, name): user = next((user for user in users if user['id'] == user_id), None) if user: - data = request.get_json() - user['name'] = data['name'] + user['name'] = name return jsonify(user) else: - return jsonify({'error': 'User not found'}), 404 + return jsonify({'error': 'User not found'}) # DELETE @@ -104,4 +113,7 @@ def delete_user(user_id): if __name__ == '__main__': + # Запускаем обработчик RabbitMQ в отдельном потоке + rabbitmq_thread = threading.Thread(target=connect_to_rabbitmq()) + rabbitmq_thread.start() app.run(port=5001) -- 2.25.1 From 06eba2e0843d5b8a20d098cc859a74d9e6615061 Mon Sep 17 00:00:00 2001 From: acidmikk Date: Fri, 24 Nov 2023 22:22:08 +0400 Subject: [PATCH 4/7] all worked api with nginx --- .../order_service/order_service.py | 62 ++++++++++++------- .../user_service/user_service.py | 8 ++- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/basharin_sevastyan_lab_3/order_service/order_service.py b/basharin_sevastyan_lab_3/order_service/order_service.py index 9d7c1c4..f0b06be 100644 --- a/basharin_sevastyan_lab_3/order_service/order_service.py +++ b/basharin_sevastyan_lab_3/order_service/order_service.py @@ -11,47 +11,65 @@ time.sleep(20) connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq')) channel = connection.channel() channel.queue_declare(queue='order_queue', durable=True) +orders = [] + + +# READ ALL +@app.route('/orders', methods=['GET']) +def show_orders(): + return orders # CREATE -@app.route('/orders', methods=['POST']) -def create_order(): - data = request.get_json() - order = {'user_id': data['user_id'], 'product': data['product'], 'action': 'create'} - +@app.route('/add_order/__', methods=['POST']) +def create_order(user_id, product, action): + order = {'id': len(orders) + 1, + 'user_id': user_id, + 'product': product, + 'action': action} + orders.append(order) # Отправка сообщения о создании заказа - channel.basic_publish(exchange='microservices', routing_key='order', body=json.dumps(order)) + channel.basic_publish(exchange='microservices', routing_key='order', body=bytes(json.dumps(order))) - return order, 201 + return jsonify(order) # READ -@app.route('/orders/', methods=['GET']) +@app.route('/order/', methods=['GET']) def get_order(order_id): - # Реализация READ операции по желанию - return jsonify({'error': 'Read operation not implemented in order service'}), 501 + order = next((order for order in orders if order['id'] == order_id), None) + if order: + read_order = {'id': order['id'], + 'user_id': order['user_id'], + 'product': order['product']} + return jsonify(read_order) + else: + return jsonify({'error': 'Order not found'}) # UPDATE -@app.route('/orders/', methods=['PUT']) -def update_order(order_id): - data = request.get_json() - order = {'user_id': data['user_id'], 'product': data['product'], 'order_id': order_id, 'action': 'update'} - - # Отправка сообщения об обновлении заказа - channel.basic_publish(exchange='microservices', routing_key='order', body=json.dumps(order)) - - return jsonify(order) +@app.route('/order//__', methods=['PUT']) +def update_order(order_id, user_id, product, action): + order = next((order for order in orders if order['id'] == order_id), None) + if order: + order['user_id'] = user_id + order['product'] = product + order['action'] = action# Отправка сообщения об обновлении заказа + channel.basic_publish(exchange='microservices', routing_key='order', body=bytes(json.dumps(order))) + return jsonify(order) + else: + return jsonify({'error': 'Order not found'}) # DELETE @app.route('/orders/', methods=['DELETE']) def delete_order(order_id): - user_id = request.args.get('user_id') - order = {'user_id': user_id, 'order_id': order_id, 'action': 'delete'} + global orders + order = next((order for order in orders if order['id'] == order_id), None) + orders = [order for order in orders if order['id'] != order] # Отправка сообщения об удалении заказа - channel.basic_publish(exchange='microservices', routing_key='order', body=json.dumps(order)) + channel.basic_publish(exchange='microservices', routing_key='order', body=bytes(json.dumps(order))) return jsonify({'result': True}) diff --git a/basharin_sevastyan_lab_3/user_service/user_service.py b/basharin_sevastyan_lab_3/user_service/user_service.py index a73ba14..a4b4397 100644 --- a/basharin_sevastyan_lab_3/user_service/user_service.py +++ b/basharin_sevastyan_lab_3/user_service/user_service.py @@ -16,8 +16,9 @@ def connect_to_rabbitmq(): try: connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq')) channel = connection.channel() + channel.exchange_declare(exchange='microservices', exchange_type='direct') channel.queue_declare(queue='order_service', durable=True) - #channel.queue_bind(queue='order_service', routing_key='order') + channel.queue_bind(exchange='microservices', queue='order_service', routing_key='order') channel.basic_consume(queue='order_service', on_message_callback=process_order_message, auto_ack=True) print('Waiting for messages. To exit press CTRL+C') channel.start_consuming() @@ -69,13 +70,14 @@ def process_order_message(ch, method, properties, body): # CRUD операции для пользователей -# CREATE +# READ ALL @app.route('/users', methods=['GET']) def show_users(): return users -@app.route('/add_users/', methods=['POST']) +# CREATE +@app.route('/add_user/', methods=['POST']) def create_user(name): if request.method == 'POST': user = {'id': len(users) + 1, 'name': name} -- 2.25.1 From 22b163ed29c4e78fa2cf5fb7e657b9f8199112c5 Mon Sep 17 00:00:00 2001 From: acidmikk Date: Sat, 25 Nov 2023 03:01:57 +0400 Subject: [PATCH 5/7] rewrite on sync messages --- basharin_sevastyan_lab_3/docker-compose.yaml | 16 +-- .../order_service/order_service.py | 26 +++-- .../order_service/requirements.txt | 3 +- .../user_service/requirements.txt | 3 +- .../user_service/user_service.py | 101 ++++++++++++------ 5 files changed, 91 insertions(+), 58 deletions(-) diff --git a/basharin_sevastyan_lab_3/docker-compose.yaml b/basharin_sevastyan_lab_3/docker-compose.yaml index 9a3d771..b4cc2e5 100644 --- a/basharin_sevastyan_lab_3/docker-compose.yaml +++ b/basharin_sevastyan_lab_3/docker-compose.yaml @@ -1,34 +1,23 @@ version: '3.8' services: - rabbitmq: - image: "rabbitmq:management" - ports: - - "5672:5672" - - "15672:15672" - networks: - - my_network - restart: always - user-service: build: context: ./user_service ports: - "5001:5001" - depends_on: - - rabbitmq networks: - my_network + restart: always order-service: build: context: ./order_service ports: - "5002:5002" - depends_on: - - rabbitmq networks: - my_network + restart: always nginx: image: nginx:latest @@ -41,6 +30,7 @@ services: - my_network volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf + restart: always networks: my_network: diff --git a/basharin_sevastyan_lab_3/order_service/order_service.py b/basharin_sevastyan_lab_3/order_service/order_service.py index f0b06be..05b437c 100644 --- a/basharin_sevastyan_lab_3/order_service/order_service.py +++ b/basharin_sevastyan_lab_3/order_service/order_service.py @@ -1,16 +1,16 @@ # order_service.py from flask import Flask, request, jsonify -import pika -import json -import time +import requests app = Flask(__name__) # Конфигурация RabbitMQ -time.sleep(20) -connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq')) -channel = connection.channel() -channel.queue_declare(queue='order_queue', durable=True) +# time.sleep(20) +# connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq')) +# if connection: +# print(f'Connect to RabbitMQ') +# channel = connection.channel() +# channel.queue_declare(queue='order_service', durable=True) orders = [] @@ -29,7 +29,8 @@ def create_order(user_id, product, action): 'action': action} orders.append(order) # Отправка сообщения о создании заказа - channel.basic_publish(exchange='microservices', routing_key='order', body=bytes(json.dumps(order))) + requests.post("http://localhost/order-service/event", json=order) + #channel.basic_publish(exchange='', routing_key='order_service', body=json.dumps(order).encode('utf-8'),properties=pika.BasicProperties(delivery_mode=2, # make message persistent)) return jsonify(order) @@ -54,8 +55,10 @@ def update_order(order_id, user_id, product, action): if order: order['user_id'] = user_id order['product'] = product - order['action'] = action# Отправка сообщения об обновлении заказа - channel.basic_publish(exchange='microservices', routing_key='order', body=bytes(json.dumps(order))) + order['action'] = action + # Отправка сообщения об обновлении заказа + requests.post("http://localhost/order-service/event", json=order) + #channel.basic_publish(exchange='', routing_key='order_service', body=json.dumps(order).encode('utf-8'), properties=pika.BasicProperties(delivery_mode=2, # make message persistent)) return jsonify(order) else: return jsonify({'error': 'Order not found'}) @@ -69,7 +72,8 @@ def delete_order(order_id): orders = [order for order in orders if order['id'] != order] # Отправка сообщения об удалении заказа - channel.basic_publish(exchange='microservices', routing_key='order', body=bytes(json.dumps(order))) + requests.post("http://localhost/order-service/event", json=order) + #channel.basic_publish(exchange='', routing_key='order_service', body=json.dumps(order).encode('utf-8'), properties=pika.BasicProperties(delivery_mode=2, # make message persistent )) return jsonify({'result': True}) diff --git a/basharin_sevastyan_lab_3/order_service/requirements.txt b/basharin_sevastyan_lab_3/order_service/requirements.txt index e949d43..411f23b 100644 --- a/basharin_sevastyan_lab_3/order_service/requirements.txt +++ b/basharin_sevastyan_lab_3/order_service/requirements.txt @@ -1,3 +1,2 @@ Flask==3.0.0 -pika==1.3.2 -gunicorn==21.2.0 \ No newline at end of file +requests==2.31.0 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/requirements.txt b/basharin_sevastyan_lab_3/user_service/requirements.txt index e949d43..411f23b 100644 --- a/basharin_sevastyan_lab_3/user_service/requirements.txt +++ b/basharin_sevastyan_lab_3/user_service/requirements.txt @@ -1,3 +1,2 @@ Flask==3.0.0 -pika==1.3.2 -gunicorn==21.2.0 \ No newline at end of file +requests==2.31.0 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/user_service.py b/basharin_sevastyan_lab_3/user_service/user_service.py index a4b4397..b9026ba 100644 --- a/basharin_sevastyan_lab_3/user_service/user_service.py +++ b/basharin_sevastyan_lab_3/user_service/user_service.py @@ -1,36 +1,82 @@ # user_service.py +import json import time from flask import Flask, request, jsonify -import pika -import json -import threading app = Flask(__name__) users = [] -# Конфигурация RabbitMQ -def connect_to_rabbitmq(): - retries = 5 - while retries > 0: - try: - connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq')) - channel = connection.channel() - channel.exchange_declare(exchange='microservices', exchange_type='direct') - channel.queue_declare(queue='order_service', durable=True) - channel.queue_bind(exchange='microservices', queue='order_service', routing_key='order') - channel.basic_consume(queue='order_service', on_message_callback=process_order_message, auto_ack=True) - print('Waiting for messages. To exit press CTRL+C') - channel.start_consuming() - except pika.exceptions.AMQPConnectionError: - print("Failed to connect to RabbitMQ. Retrying...") - retries -= 1 - time.sleep(5) - - # Обработка сообщений о заказах -def process_order_message(ch, method, properties, body): - data = json.loads(body) +# def process_order_message(ch, method, properties, body: bytes): +# data = json.loads(body.decode('utf-8')) +# user_id = data.get('user_id') +# +# if data['action'] == 'create': +# # Создание заказа у пользователя +# user = next((user for user in users if user['id'] == user_id), None) +# if user: +# order_id = len(user.get('orders', [])) + 1 +# order = {'id': order_id, 'product': data['product']} +# user.setdefault('orders', []).append(order) +# print(f"Order created for user {user_id}: {order}") +# else: +# print(f"User not found for order creation: {user_id}") +# +# elif data['action'] == 'update': +# # Обновление заказа у пользователя +# user = next((user for user in users if user['id'] == user_id), None) +# if user: +# order_id = data.get('order_id') +# order = next((order for order in user['orders'] if order['id'] == order_id), None) +# if order: +# order['product'] = data['product'] +# print(f"Order updated for user {user_id}: {order}") +# else: +# print(f"Order not found for update: {order_id}") +# else: +# print(f"User not found for order update: {user_id}") +# +# elif data['action'] == 'delete': +# # Удаление заказа у пользователя +# user = next((user for user in users if user['id'] == user_id), None) +# if user: +# order_id = data.get('order_id') +# user['orders'] = [order for order in user.get('orders', []) if order['id'] != order_id] +# print(f"Order deleted for user {user_id}: {order_id}") +# else: +# print(f"User not found for order deletion: {user_id}") +# ch.basic_ack(delivery_tag=method.delivery_tag) + + +# first_con = True +# # Конфигурация RabbitMQ +# def connect_to_rabbitmq(): +# global first_con +# if first_con: +# time.sleep(15) +# first_con = False +# credentials = pika.PlainCredentials(username="guest", password="guest") +# connection = pika.BlockingConnection(pika.ConnectionParameters(host='rabbitmq', credentials=credentials)) +# channel = connection.channel() +# channel.queue_declare(queue='order_service', durable=True) +# channel.basic_qos(prefetch_count=1) +# +# def callback(ch, method, properties, body): +# process_order_message(ch, method, properties, body) +# ch.close() +# +# channel.basic_consume(queue='order_service', on_message_callback=callback, auto_ack=False) +# print('Waiting for messages. To exit press CTRL+C') +# while True: +# connection.process_data_events(time_limit=1) + +# CRUD операции для пользователей +# READ ALL +@app.route('/event') +def event(): + data = request.get_json() + print(data) user_id = data.get('user_id') if data['action'] == 'create': @@ -68,9 +114,6 @@ def process_order_message(ch, method, properties, body): else: print(f"User not found for order deletion: {user_id}") - -# CRUD операции для пользователей -# READ ALL @app.route('/users', methods=['GET']) def show_users(): return users @@ -115,7 +158,5 @@ def delete_user(user_id): if __name__ == '__main__': - # Запускаем обработчик RabbitMQ в отдельном потоке - rabbitmq_thread = threading.Thread(target=connect_to_rabbitmq()) - rabbitmq_thread.start() + #connect_to_rabbitmq() app.run(port=5001) -- 2.25.1 From 5e85f5a31579c1de1e2543b5ba617315bc82fd93 Mon Sep 17 00:00:00 2001 From: acidmikk Date: Sun, 26 Nov 2023 01:14:39 +0400 Subject: [PATCH 6/7] sevastyan_basharin_lab_3 is ready --- .../order_service/order_service.py | 28 +++++++++---------- .../order_service/requirements.txt | 3 +- .../user_service/requirements.txt | 3 +- .../user_service/user_service.py | 20 ++++++++----- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/basharin_sevastyan_lab_3/order_service/order_service.py b/basharin_sevastyan_lab_3/order_service/order_service.py index 05b437c..81d5ac2 100644 --- a/basharin_sevastyan_lab_3/order_service/order_service.py +++ b/basharin_sevastyan_lab_3/order_service/order_service.py @@ -21,22 +21,22 @@ def show_orders(): # CREATE -@app.route('/add_order/__', methods=['POST']) -def create_order(user_id, product, action): +@app.route('/add_order/_', methods=['POST']) +def create_order(user_id, product): order = {'id': len(orders) + 1, 'user_id': user_id, 'product': product, - 'action': action} + 'action': 'create'} orders.append(order) # Отправка сообщения о создании заказа - requests.post("http://localhost/order-service/event", json=order) + requests.post("http://user-service:5001/event", json=order) #channel.basic_publish(exchange='', routing_key='order_service', body=json.dumps(order).encode('utf-8'),properties=pika.BasicProperties(delivery_mode=2, # make message persistent)) return jsonify(order) # READ -@app.route('/order/', methods=['GET']) +@app.route('/order/get_', methods=['GET']) def get_order(order_id): order = next((order for order in orders if order['id'] == order_id), None) if order: @@ -49,15 +49,14 @@ def get_order(order_id): # UPDATE -@app.route('/order//__', methods=['PUT']) -def update_order(order_id, user_id, product, action): +@app.route('/order//', methods=['PUT']) +def update_order(order_id, product): order = next((order for order in orders if order['id'] == order_id), None) if order: - order['user_id'] = user_id order['product'] = product - order['action'] = action + order['action'] = 'update' # Отправка сообщения об обновлении заказа - requests.post("http://localhost/order-service/event", json=order) + requests.post("http://user-service:5001/event", json=order) #channel.basic_publish(exchange='', routing_key='order_service', body=json.dumps(order).encode('utf-8'), properties=pika.BasicProperties(delivery_mode=2, # make message persistent)) return jsonify(order) else: @@ -65,14 +64,15 @@ def update_order(order_id, user_id, product, action): # DELETE -@app.route('/orders/', methods=['DELETE']) +@app.route('/order/del_', methods=['DELETE']) def delete_order(order_id): global orders - order = next((order for order in orders if order['id'] == order_id), None) - orders = [order for order in orders if order['id'] != order] + del_order = next((order for order in orders if order['id'] == order_id), None) + orders = [order for order in orders if order['id'] != order_id] + del_order['action'] = 'delete' # Отправка сообщения об удалении заказа - requests.post("http://localhost/order-service/event", json=order) + requests.post("http://user-service:5001/event", json=del_order) #channel.basic_publish(exchange='', routing_key='order_service', body=json.dumps(order).encode('utf-8'), properties=pika.BasicProperties(delivery_mode=2, # make message persistent )) return jsonify({'result': True}) diff --git a/basharin_sevastyan_lab_3/order_service/requirements.txt b/basharin_sevastyan_lab_3/order_service/requirements.txt index 411f23b..3d70f32 100644 --- a/basharin_sevastyan_lab_3/order_service/requirements.txt +++ b/basharin_sevastyan_lab_3/order_service/requirements.txt @@ -1,2 +1,3 @@ Flask==3.0.0 -requests==2.31.0 \ No newline at end of file +requests==2.31.0 +gunicorn==21.2.0 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/requirements.txt b/basharin_sevastyan_lab_3/user_service/requirements.txt index 411f23b..3d70f32 100644 --- a/basharin_sevastyan_lab_3/user_service/requirements.txt +++ b/basharin_sevastyan_lab_3/user_service/requirements.txt @@ -1,2 +1,3 @@ Flask==3.0.0 -requests==2.31.0 \ No newline at end of file +requests==2.31.0 +gunicorn==21.2.0 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/user_service.py b/basharin_sevastyan_lab_3/user_service/user_service.py index b9026ba..7249978 100644 --- a/basharin_sevastyan_lab_3/user_service/user_service.py +++ b/basharin_sevastyan_lab_3/user_service/user_service.py @@ -73,8 +73,9 @@ users = [] # CRUD операции для пользователей # READ ALL -@app.route('/event') +@app.route('/event', methods=['POST']) def event(): + print('получено сообщение') data = request.get_json() print(data) user_id = data.get('user_id') @@ -94,7 +95,7 @@ def event(): # Обновление заказа у пользователя user = next((user for user in users if user['id'] == user_id), None) if user: - order_id = data.get('order_id') + order_id = data.get('id') order = next((order for order in user['orders'] if order['id'] == order_id), None) if order: order['product'] = data['product'] @@ -108,11 +109,12 @@ def event(): # Удаление заказа у пользователя user = next((user for user in users if user['id'] == user_id), None) if user: - order_id = data.get('order_id') + order_id = user.get('id') user['orders'] = [order for order in user.get('orders', []) if order['id'] != order_id] print(f"Order deleted for user {user_id}: {order_id}") else: print(f"User not found for order deletion: {user_id}") + return jsonify({'result': True}) @app.route('/users', methods=['GET']) def show_users(): @@ -123,13 +125,17 @@ def show_users(): @app.route('/add_user/', methods=['POST']) def create_user(name): if request.method == 'POST': - user = {'id': len(users) + 1, 'name': name} + if len(users) == 0: + id = 1 + else: + id = users[-1]['id'] + 1 + user = {'id': id, 'name': name} users.append(user) return jsonify(user) # READ -@app.route('/users/', methods=['GET']) +@app.route('/users/get_', methods=['GET']) def get_user(user_id): user = next((user for user in users if user['id'] == user_id), None) if user: @@ -139,7 +145,7 @@ def get_user(user_id): # UPDATE -@app.route('/users/_', methods=['PUT']) +@app.route('/users/upd__', methods=['PUT']) def update_user(user_id, name): user = next((user for user in users if user['id'] == user_id), None) if user: @@ -150,7 +156,7 @@ def update_user(user_id, name): # DELETE -@app.route('/users/', methods=['DELETE']) +@app.route('/users/del_', methods=['DELETE']) def delete_user(user_id): global users users = [user for user in users if user['id'] != user_id] -- 2.25.1 From 02a13a395dd0dd59a69d5293ce37089e1af00ab0 Mon Sep 17 00:00:00 2001 From: acidmikk Date: Sun, 26 Nov 2023 01:40:12 +0400 Subject: [PATCH 7/7] sevastyan_basharin_lab_3 is ready (with README) --- basharin_sevastyan_lab_3/README.md | 136 +++++++++++++++--- .../user_service/user_service.py | 6 +- 2 files changed, 120 insertions(+), 22 deletions(-) diff --git a/basharin_sevastyan_lab_3/README.md b/basharin_sevastyan_lab_3/README.md index e4c6c46..f8c71ba 100644 --- a/basharin_sevastyan_lab_3/README.md +++ b/basharin_sevastyan_lab_3/README.md @@ -1,3 +1,13 @@ +# Лабораторная работа 3. Вариант 5. + +### Как запустить +В директории с файлом `docker-compose.yaml` выполнить команду: +``` +docker-compose up -d +``` +Это запустит `docker-compose`, который создаст контейнер и развернет в нем 3 контейнера. + +### Файловая иерархия ``` basharin_sevastyan_lab_3/ |-- user_service/ @@ -14,8 +24,78 @@ basharin_sevastyan_lab_3/ |-- docker-compose.yml ``` +### Описание работы +#### Описание предметной области +Объекты микросервисов буду связаны следующим образом: +``` +user (single) <- order (many) +``` +#### Синхронный обмен сообщениями +`order_service` будет отправлять http-запрос на `user_service` при определенных crud операциях. Например, при создании +экземпляра `order`, будет отправлен запрос на добавление `order` к определенному `user`: +```python +# CREATE +@app.route('/add_order/_', methods=['POST']) +def create_order(user_id, product): + order = {'id': len(orders) + 1, + 'user_id': user_id, + 'product': product, + 'action': 'create'} + orders.append(order) + # Отправка сообщения о создании заказа + requests.post("http://user-service:5001/event", json=order) + + return jsonify(order) +``` +В `user_service` этот запрос обрабатывается следующим образом: +```python +@app.route('/event', methods=['POST']) +def event(): + print('получено сообщение') + data = request.get_json() + print(data) + user_id = data.get('user_id') + + if data['action'] == 'create': + # Создание заказа у пользователя + user = next((user for user in users if user['id'] == user_id), None) + if user: + order_id = len(user.get('orders', [])) + 1 + order = {'id': order_id, 'product': data['product']} + user.setdefault('orders', []).append(order) + print(f"Order created for user {user_id}: {order}") + else: + print(f"User not found for order creation: {user_id}") + + elif data['action'] == 'update': + # Обновление заказа у пользователя + user = next((user for user in users if user['id'] == user_id), None) + if user: + order_id = data.get('id') + order = next((order for order in user['orders'] if order['id'] == order_id), None) + if order: + order['product'] = data['product'] + print(f"Order updated for user {user_id}: {order}") + else: + print(f"Order not found for update: {order_id}") + else: + print(f"User not found for order update: {user_id}") + + elif data['action'] == 'delete': + # Удаление заказа у пользователя + user = next((user for user in users if user['id'] == user_id), None) + if user: + order_id = user.get('id') + user['orders'] = [order for order in user.get('orders', []) if order['id'] != order_id] + print(f"Order deleted for user {user_id}: {order_id}") + else: + print(f"User not found for order deletion: {user_id}") + return jsonify({'result': True}) +``` + +### Описание docker-compose ```yaml -version: '3' +version: '3.8' services: user-service: @@ -23,49 +103,65 @@ services: context: ./user_service ports: - "5001:5001" - depends_on: - - rabbitmq + networks: + - my_network + restart: always order-service: build: context: ./order_service ports: - "5002:5002" - depends_on: - - rabbitmq - - rabbitmq: - image: "rabbitmq:management" - ports: - - "5672:5672" - - "15672:15672" + networks: + - my_network + restart: always nginx: - build: - context: ./nginx + image: nginx:latest ports: - "80:80" depends_on: - user-service - order-service + networks: + - my_network + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + restart: always + +networks: + my_network: + driver: bridge ``` +### Dockerfile микросервисов ```dockerfile # user_service/Dockerfile FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -COPY . . -CMD ["python", "user_service.py"] +COPY . /app +CMD ["gunicorn", "--bind", "0.0.0.0:5001", "user_service:app"] ``` - ```dockerfile -# user_service/Dockerfile +# order_service/Dockerfile FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -COPY . . -CMD ["python", "order_service.py"] -``` \ No newline at end of file +COPY . /app +CMD ["gunicorn", "--bind", "0.0.0.0:5002", "order_service:app"] +``` + +### Dockerfile nginx +```dockerfile +# nginx/Dockerfile +FROM nginx +COPY nginx.conf /etc/nginx/nginx.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] +``` + +### Видео +https://youtu.be/3-iF9xBHvCU \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/user_service.py b/basharin_sevastyan_lab_3/user_service/user_service.py index 7249978..245f2ee 100644 --- a/basharin_sevastyan_lab_3/user_service/user_service.py +++ b/basharin_sevastyan_lab_3/user_service/user_service.py @@ -71,8 +71,7 @@ users = [] # while True: # connection.process_data_events(time_limit=1) -# CRUD операции для пользователей -# READ ALL + @app.route('/event', methods=['POST']) def event(): print('получено сообщение') @@ -116,6 +115,9 @@ def event(): print(f"User not found for order deletion: {user_id}") return jsonify({'result': True}) + +# CRUD операции для пользователей +# READ ALL @app.route('/users', methods=['GET']) def show_users(): return users -- 2.25.1