From 063b93d78e63ac6cdedb3c3774b8a49f4f7689d9 Mon Sep 17 00:00:00 2001 From: Yana <––ƒ––iputilin201@gmail.com> Date: Tue, 10 Dec 2024 20:14:57 +0400 Subject: [PATCH] nikolaeva_yana_lab_3 --- nikolaeva_yana_lab_3/README.md | 43 +++++++++++++++++ nikolaeva_yana_lab_3/docker-compose.yml | 22 +++++++++ nikolaeva_yana_lab_3/gateway/Dockerfile | 2 + nikolaeva_yana_lab_3/gateway/nginx.conf | 15 ++++++ nikolaeva_yana_lab_3/service_books/Dockerfile | 6 +++ nikolaeva_yana_lab_3/service_books/app.py | 48 +++++++++++++++++++ .../service_books/requirements.txt | 2 + .../service_subscription/Dockerfile | 6 +++ .../service_subscription/app.py | 43 +++++++++++++++++ .../service_subscription/requirements.txt | 1 + 10 files changed, 188 insertions(+) create mode 100644 nikolaeva_yana_lab_3/README.md create mode 100644 nikolaeva_yana_lab_3/docker-compose.yml create mode 100644 nikolaeva_yana_lab_3/gateway/Dockerfile create mode 100644 nikolaeva_yana_lab_3/gateway/nginx.conf create mode 100644 nikolaeva_yana_lab_3/service_books/Dockerfile create mode 100644 nikolaeva_yana_lab_3/service_books/app.py create mode 100644 nikolaeva_yana_lab_3/service_books/requirements.txt create mode 100644 nikolaeva_yana_lab_3/service_subscription/Dockerfile create mode 100644 nikolaeva_yana_lab_3/service_subscription/app.py create mode 100644 nikolaeva_yana_lab_3/service_subscription/requirements.txt diff --git a/nikolaeva_yana_lab_3/README.md b/nikolaeva_yana_lab_3/README.md new file mode 100644 index 0000000..4a12aea --- /dev/null +++ b/nikolaeva_yana_lab_3/README.md @@ -0,0 +1,43 @@ + +# Лабораторная работа №3 - REST API, шлюз и синхронный обмен данными между микросервисами + +## Задание + +### Цель: +Изучение принципов проектирования с использованием паттерна шлюза, организации синхронной передачи данных между микросервисами и применения архитектурного стиля RESTful API. + +### Задачи: +1. Создание двух микросервисов, которые реализуют операции CRUD для связанных сущностей. +2. Реализация механизма синхронного обмена данными между микросервисами. +3. Настройка шлюза на базе Nginx в качестве прозрачного прокси-сервера. + +### Микросервисы: +1. **service_books** — сервис, который обрабатывает данные о книгах, связанных с абонементами. +2. **service_subscription** — сервис, который управляет информацией об абонементах. + +### Связь между микросервисами: + +Один абонемент может быть связан с несколькими книгами (отношение 1 ко многим). + + +## Как запустить проект: +Для запуска приложения необходимо выполнить команду: + +docker-compose up + +## Описание работы: + +Для разработки микросервисов был выбран язык программирования Python. + +### Синхронный обмен данными +Сервис `service_books` отправляет HTTP-запросы к `service_subscription` при выполнении определенных операций CRUD. Это позволяет получать актуальную информацию о предметах, связанных с конкретными абонентами. + +### Docker Compose +Конфигурационный файл `docker-compose.yml` представляет собой многоконтейнерное приложение, которое включает в себя три сервиса: `service_subscription`, `service_books` и `nginx`. Функция маршрутизации возложена на сервер Nginx, который обрабатывает запросы и перенаправляет их на соответствующие микросервисы. + +### Nginx +Конфигурационный файл Nginx определяет настройки веб-сервера и обратного прокси, который управляет входящими запросами и направляет их на соответствующие сервисы. + +### ВИДЕО + +https://cloud.mail.ru/public/tior/GJxyvy8Rp \ No newline at end of file diff --git a/nikolaeva_yana_lab_3/docker-compose.yml b/nikolaeva_yana_lab_3/docker-compose.yml new file mode 100644 index 0000000..31571b2 --- /dev/null +++ b/nikolaeva_yana_lab_3/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.8' + +services: + gateway: + build: ./gateway + ports: + - "8080:80" + volumes: + - ./gateway/nginx.conf:/etc/nginx/nginx.conf:ro + depends_on: + - subscription + - books + + subscription: + build: ./service_subscription + ports: + - "5001:5000" + + books: + build: ./service_books + ports: + - "5002:5000" diff --git a/nikolaeva_yana_lab_3/gateway/Dockerfile b/nikolaeva_yana_lab_3/gateway/Dockerfile new file mode 100644 index 0000000..754f9f9 --- /dev/null +++ b/nikolaeva_yana_lab_3/gateway/Dockerfile @@ -0,0 +1,2 @@ +FROM nginx:latest +COPY nginx.conf /etc/nginx/nginx.conf diff --git a/nikolaeva_yana_lab_3/gateway/nginx.conf b/nikolaeva_yana_lab_3/gateway/nginx.conf new file mode 100644 index 0000000..d172115 --- /dev/null +++ b/nikolaeva_yana_lab_3/gateway/nginx.conf @@ -0,0 +1,15 @@ +events {} + +http { + server { + listen 80; + + location /subscription/ { + proxy_pass http://subscription:5000/; + } + + location /books/ { + proxy_pass http://books:5000/; + } + } +} diff --git a/nikolaeva_yana_lab_3/service_books/Dockerfile b/nikolaeva_yana_lab_3/service_books/Dockerfile new file mode 100644 index 0000000..78b3a9c --- /dev/null +++ b/nikolaeva_yana_lab_3/service_books/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.9-slim +WORKDIR /app +COPY requirements.txt requirements.txt +RUN pip install -r requirements.txt +COPY . . +CMD ["python", "app.py"] diff --git a/nikolaeva_yana_lab_3/service_books/app.py b/nikolaeva_yana_lab_3/service_books/app.py new file mode 100644 index 0000000..67923b4 --- /dev/null +++ b/nikolaeva_yana_lab_3/service_books/app.py @@ -0,0 +1,48 @@ +from flask import Flask, request, jsonify +import requests +from uuid import uuid4 + +app = Flask(__name__) +books = [] + +@app.route("/", methods=["GET"]) +def list_books(): + return jsonify(books) + +@app.route("/", methods=["GET"]) +def get_book(book_id): + book = next((b for b in books if b["uuid"] == str(book_id)), None) + if book: + subscription_response = requests.get(f"http://subscription:5000/{book['subscriptionUuid']}") + if subscription_response.status_code == 200: + book["subscriptionInfo"] = subscription_response.json() + return jsonify(book) + return jsonify({"error": "Not found"}), 404 + +@app.route("/", methods=["POST"]) +def create_book(): + data = request.json + new_book = { + "uuid": str(uuid4()), + "author": data["author"], + "subject": data["subject"], + "year": data["year"], + "subscriptionUuid": data["subscriptionUuid"], + } + books.append(new_book) + return jsonify(new_book), 201 + +@app.route("/", methods=["PUT"]) +def update_book(book_id): + data = request.json + book = next((b for b in books if b["uuid"] == str(book_id)), None) + if book: + book.update(data) + return jsonify(book) + return jsonify({"error": "Not found"}), 404 + +@app.route("/", methods=["DELETE"]) +def delete_book(book_id): + global books + books = [b for b in books if b["uuid"] != str(book_id)] + return "", 204 diff --git a/nikolaeva_yana_lab_3/service_books/requirements.txt b/nikolaeva_yana_lab_3/service_books/requirements.txt new file mode 100644 index 0000000..30692b7 --- /dev/null +++ b/nikolaeva_yana_lab_3/service_books/requirements.txt @@ -0,0 +1,2 @@ +flask +requests diff --git a/nikolaeva_yana_lab_3/service_subscription/Dockerfile b/nikolaeva_yana_lab_3/service_subscription/Dockerfile new file mode 100644 index 0000000..78b3a9c --- /dev/null +++ b/nikolaeva_yana_lab_3/service_subscription/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.9-slim +WORKDIR /app +COPY requirements.txt requirements.txt +RUN pip install -r requirements.txt +COPY . . +CMD ["python", "app.py"] diff --git a/nikolaeva_yana_lab_3/service_subscription/app.py b/nikolaeva_yana_lab_3/service_subscription/app.py new file mode 100644 index 0000000..78bf379 --- /dev/null +++ b/nikolaeva_yana_lab_3/service_subscription/app.py @@ -0,0 +1,43 @@ +from flask import Flask, request, jsonify +from uuid import uuid4 + +app = Flask(__name__) +subscriptions = [] + +@app.route("/", methods=["GET"]) +def list_subscriptions(): + return jsonify(subscriptions) + +@app.route("/", methods=["GET"]) +def get_subscription(subscription_id): + subscription = next((s for s in subscriptions if s["uuid"] == str(subscription_id)), None) + if subscription: + return jsonify(subscription) + return jsonify({"error": "Not found"}), 404 + +@app.route("/", methods=["POST"]) +def create_subscription(): + data = request.json + new_subscription = { + "uuid": str(uuid4()), + "number": data["number"], + "fullName": data["fullName"], + "issued": data["issued"], + } + subscriptions.append(new_subscription) + return jsonify(new_subscription), 201 + +@app.route("/", methods=["PUT"]) +def update_subscription(subscription_id): + data = request.json + subscription = next((s for s in subscriptions if s["uuid"] == str(subscription_id)), None) + if subscription: + subscription.update(data) + return jsonify(subscription) + return jsonify({"error": "Not found"}), 404 + +@app.route("/", methods=["DELETE"]) +def delete_subscription(subscription_id): + global subscriptions + subscriptions = [s for s in subscriptions if s["uuid"] != str(subscription_id)] + return "", 204 diff --git a/nikolaeva_yana_lab_3/service_subscription/requirements.txt b/nikolaeva_yana_lab_3/service_subscription/requirements.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/nikolaeva_yana_lab_3/service_subscription/requirements.txt @@ -0,0 +1 @@ +flask