diff --git a/antonov_dmitry_lab_3/README.md b/antonov_dmitry_lab_3/README.md index 7c6afb0..8abd8a3 100644 --- a/antonov_dmitry_lab_3/README.md +++ b/antonov_dmitry_lab_3/README.md @@ -1,67 +1,54 @@ -# Лабораторная работа №3 - Знакомство с docker и docker-compose +# Лабораторная работа №3 - REST API, Gateway и синхронный обмен между микросервисами -Разверните 3 сервиса на выбор в контейнерах docker с помощью docker-compose. -Требования и docker-compose: +Изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API. -Несколько контейнеров. -Хотя бы один volume. -Хотя бы один порт, проброшенный на хост. -При этом разворачивание системы должно пройти до конца. Например, должен быть создан -администратор и система должна корректно функционировать. Это необходимо будет предоставить -в отчёте, поэтому не забывайте делать скриншоты. +Создать два микросервиса. -# Выбранные сервисы +Каждый сервис реализует CRUD-операции: список записей, подробности конкретной записи, создание, удаление и изменение записи. +В качестве хранилища данных может выступать оперативная память приложения или база данных. +Сущности необходимо подобрать по следующим критериям: -* mediawiki - движок вики -* drupal - популярная система управления контентом -* wordpress - популярная система управления контентом. +Они должны быть связаны с предполагаемой темой диплома. +Они должны быть связаны как "1-ко-многим". + +# Задачи + +* Создать 2 микросервиса, реализующих CRUD на связанных сущностях. +* Реализовать механизм синхронного обмена сообщениями между микросервисами. +* Реализовать шлюз на основе прозрачного прокси-сервера nginx. # Запуск Командой в консоли проекта "docker-compose up -d" # Описание работы: -Развернули три сервиса плюс базу данных к ним. -Подробное описание для docker-compose дано в комментариях. +Развернули два приложения -1. mediawiki: -- доступ на http://localhost:8080/ +1. Сервис с врачами: +- доступ на http://localhost:5000/ -2. drupal: -- доступ на http://localhost:8081/ +2. Сервис с пациентами: +- доступ на http://localhost:5001/ -3. wordpress: -- доступ на http://localhost:8082/ +Сервисы связываются друг с другом через ссылку и библиотеку requests

Старт сервисов
- +

-

Сервисы
- +
Сервис врачей
+

-

Images
- +
Сервис пациентов
+

-

Volumes
- -

-

-

Сервис 1
- -

-

-

Сервис 2
- -

-

-

Сервис 3
- +
Связь сервисов через библиотеку requests
+

# Ссылка на видео -https://disk.yandex.ru/i/nG5KrHy_DsQxuw +https://disk.yandex.ru/i/3o4aLuqp1EpbJg diff --git a/antonov_dmitry_lab_3/docker-compose.yml b/antonov_dmitry_lab_3/docker-compose.yml index 0b0fe2e..3b331e8 100644 --- a/antonov_dmitry_lab_3/docker-compose.yml +++ b/antonov_dmitry_lab_3/docker-compose.yml @@ -14,9 +14,9 @@ services: nginx: image: nginx ports: - - "8085:8085" + - "80:80" volumes: - - ./nginx.conf:/etc/nginx/conf.d/nginx.conf + - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf depends_on: - service_a - service_b \ No newline at end of file diff --git a/antonov_dmitry_lab_3/nginx.conf b/antonov_dmitry_lab_3/nginx.conf deleted file mode 100644 index c07aa54..0000000 --- a/antonov_dmitry_lab_3/nginx.conf +++ /dev/null @@ -1,13 +0,0 @@ -server { - listen 8085; - listen [::]:8085; - server_name localhost; - - location /service_a/ { - proxy_pass http://127.0.0.1:5000; - } - - location /service_b/ { - proxy_pass http://127.0.0.1:5001; - } -} \ No newline at end of file diff --git a/antonov_dmitry_lab_3/nginx/nginx.conf b/antonov_dmitry_lab_3/nginx/nginx.conf new file mode 100644 index 0000000..23b3fa1 --- /dev/null +++ b/antonov_dmitry_lab_3/nginx/nginx.conf @@ -0,0 +1,17 @@ +server { + listen 80; + + location /app1/ { + proxy_pass http://localhost:5000/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /app2/ { + proxy_pass http://localhost: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; + } +} diff --git a/antonov_dmitry_lab_3/screens/img1.png b/antonov_dmitry_lab_3/screens/img1.png new file mode 100644 index 0000000..5e59a8d Binary files /dev/null and b/antonov_dmitry_lab_3/screens/img1.png differ diff --git a/antonov_dmitry_lab_3/screens/img2.png b/antonov_dmitry_lab_3/screens/img2.png new file mode 100644 index 0000000..7aaa510 Binary files /dev/null and b/antonov_dmitry_lab_3/screens/img2.png differ diff --git a/antonov_dmitry_lab_3/screens/img3.png b/antonov_dmitry_lab_3/screens/img3.png new file mode 100644 index 0000000..4ec5c62 Binary files /dev/null and b/antonov_dmitry_lab_3/screens/img3.png differ diff --git a/antonov_dmitry_lab_3/screens/img4.png b/antonov_dmitry_lab_3/screens/img4.png new file mode 100644 index 0000000..0a1e85d Binary files /dev/null and b/antonov_dmitry_lab_3/screens/img4.png differ diff --git a/antonov_dmitry_lab_3/service_a/app.py b/antonov_dmitry_lab_3/service_a/app.py index 4836e89..ab01af6 100644 --- a/antonov_dmitry_lab_3/service_a/app.py +++ b/antonov_dmitry_lab_3/service_a/app.py @@ -1,42 +1,98 @@ from flask import Flask, jsonify, request +import requests app = Flask(__name__) -# "customers" -customers_data = [] +# набор данных докторов с их пациентами +doctors_data = [ + { + 'id': 1, + 'name': 'Doctor A', + 'email': 'doctor.a@example.com', + 'patients': [ + {'id': 1, 'name': 'Patient A1', 'email': 'patient.a1@example.com'}, + {'id': 2, 'name': 'Patient A2', 'email': 'patient.a2@example.com'}, + ], + }, + { + 'id': 2, + 'name': 'Doctor B', + 'email': 'doctor.b@example.com', + 'patients': [ + {'id': 3, 'name': 'Patient B1', 'email': 'patient.b1@example.com'}, + {'id': 4, 'name': 'Patient B2', 'email': 'patient.b2@example.com'}, + ], + }, + { + 'id': 3, + 'name': 'Doctor C', + 'email': 'doctor.c@example.com', + 'patients': [ + {'id': 5, 'name': 'Patient C1', 'email': 'patient.c1@example.com'}, + ], + }, +] +# URL для сервиса пациентов +patients_service_url = "http://localhost/app2/patients" -@app.route('/service_a/', methods=['GET']) +@app.route('/', methods=['GET']) def get_index(): - return "Hello from service_a" + return "это первый сервис" -@app.route('/service_a/customers', methods=['GET']) -def get_customers(): - return jsonify(customers_data) +@app.route('/doctors', methods=['GET']) +def get_doctors(): + return jsonify(doctors_data) -@app.route('/service_a/customers', methods=['POST']) -def create_customer(): - new_customer = request.json - customers_data.append(new_customer) - return jsonify(new_customer), 201 +@app.route('/doctors', methods=['POST']) +def create_doctor(): + new_doctor = request.json + # уникальный id для нового доктора + new_doctor['id'] = len(doctors_data) + 1 + new_doctor['patients'] = [] + doctors_data.append(new_doctor) + return jsonify(new_doctor), 201 -@app.route('/service_a/customers/', methods=['PUT']) -def update_customer(id): - for customer in customers_data: - if customer['id'] == id: - customer.update(request.json) - return jsonify(customer), 200 - return jsonify({'error': 'Customer not found'}), 404 +@app.route('/doctors/', methods=['PUT']) +def update_doctor(id): + for doctor in doctors_data: + if doctor['id'] == id: + doctor.update(request.json) + return jsonify(doctor), 200 + return jsonify({'error': 'Доктор не найден'}), 404 -@app.route('/service_a/customers/', methods=['DELETE']) -def delete_customer(id): - global customers_data - customers_data = [customer for customer in customers_data if customer['id'] != id] - return jsonify({'message': 'Customer deleted'}), 200 +@app.route('/doctors/', methods=['DELETE']) +def delete_doctor(id): + global doctors_data + doctors_data = [doctor for doctor in doctors_data if doctor['id'] != id] + return jsonify({'message': 'Доктор удален'}), 200 + + +@app.route('/doctors//patients', methods=['GET']) +def get_doctor_patients(id): + for doctor in doctors_data: + if doctor['id'] == id: + return jsonify(doctor['patients']) + return jsonify({'error': 'Доктор не найден'}), 404 + + +@app.route('/doctors//patients', methods=['POST']) +def create_doctor_patient(id): + for doctor in doctors_data: + if doctor['id'] == id: + new_patient = request.json + # назначить уникальный id новому пациенту + new_patient['id'] = len(doctor['patients']) + 1 + doctor['patients'].append(new_patient) + + requests.post(patients_service_url, json=new_patient) + + return jsonify(new_patient), 201 + return jsonify({'error': 'Доктор не найден'}), 404 if __name__ == '__main__': diff --git a/antonov_dmitry_lab_3/service_b/app.py b/antonov_dmitry_lab_3/service_b/app.py index cb9766d..8f306f9 100644 --- a/antonov_dmitry_lab_3/service_b/app.py +++ b/antonov_dmitry_lab_3/service_b/app.py @@ -1,42 +1,69 @@ from flask import Flask, jsonify, request +import requests app = Flask(__name__) -# "clients" -clients_data = [] +# набор данных пациентов и их врачей +patients_data = [ + {'id': 1, 'name': 'Patient A', 'email': 'patient.a@example.com', 'doctor_id': 1}, + {'id': 2, 'name': 'Patient B', 'email': 'patient.b@example.com', 'doctor_id': 2}, + {'id': 3, 'name': 'Patient C', 'email': 'patient.c@example.com', 'doctor_id': 1}, +] + +# URL сервиса докторов +doctor_service_url = "http://localhost:5000" @app.route('/', methods=['GET']) def get_index(): - return "Hello from service_b" + return "это второй сервис" -@app.route('/clients', methods=['GET']) -def get_clients(): - return jsonify(clients_data) +@app.route('/patients', methods=['GET']) +def get_patients(): + return jsonify(patients_data) -@app.route('/clients', methods=['POST']) -def create_client(): - new_client = request.json - clients_data.append(new_client) - return jsonify(new_client), 201 +@app.route('/patients/', methods=['GET']) +def get_patient(id): + for patient in patients_data: + if patient['id'] == id: + return jsonify(patient) + return jsonify({'error': 'Пациент не найден'}), 404 -@app.route('/clients/', methods=['PUT']) -def update_client(id): - for client in clients_data: - if client['id'] == id: - client.update(request.json) - return jsonify(client), 200 - return jsonify({'error': 'Client not found'}), 404 +@app.route('/patients', methods=['POST']) +def create_patient(): + new_patient = request.json + # назначить уникальный id новому пациенту + new_patient['id'] = len(patients_data) + 1 + patients_data.append(new_patient) + + # отправляем запрос другому сервису + requests.post(f"{doctor_service_url}/doctors/1/patients", json=new_patient) + + return jsonify(new_patient), 201 -@app.route('/clients/', methods=['DELETE']) -def delete_client(id): - global clients_data - clients_data = [client for client in clients_data if client['id'] != id] - return jsonify({'message': 'Client deleted'}), 200 +@app.route('/patients/', methods=['PUT']) +def update_patient(id): + for patient in patients_data: + if patient['id'] == id: + patient.update(request.json) + # отправляем запрос другому сервису + response = requests.put(f"{doctor_service_url}/doctors/1/patients/{id}", json=request.json) + return jsonify(patient), 200 + return jsonify({'error': 'Пациент не найден'}), 404 + + +@app.route('/patients/', methods=['DELETE']) +def delete_patient(id): + # отправляем запрос другому сервису + response = requests.delete(f"{doctor_service_url}/doctors/1/patients/{id}") + + global patients_data + patients_data = [patient for patient in patients_data if patient['id'] != id] + return jsonify({'message': 'Пациент удален'}), 200 if __name__ == '__main__':