diff --git a/bogdanov_dmitry_lab_2/.gitignore b/bogdanov_dmitry_lab_2/.gitignore
new file mode 100644
index 0000000..6f12951
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/.gitignore
@@ -0,0 +1,2 @@
+data/
+result/
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/README.md b/bogdanov_dmitry_lab_2/README.md
new file mode 100644
index 0000000..1834bb3
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/README.md
@@ -0,0 +1,41 @@
+# Лабораторная работа №2
+
+## Богданов Дмитрий ПИбд-42
+
+### Для выполнения была проделана следующая работа:
+Были написаны и развернуты 3 сервиса: генератор файлов, 2 приложения для работы с этими файлами по вариантам 2 и 1 соответственно:
+
+Вариант 2 (для первого приложения):
+
+```Формирует файл /var/result/data.txt из первых строк всех файлов каталога /var/data.```
+
+Вариант 1 (для второго приложения):
+
+```Ищет набольшее число из файла /var/data/data.txt и сохраняет его вторую степень в /var/result/result.txt.```
+
+Приложения работают совместно, используя общий монтированный том для записи и получения информации:
+```
+ volumes:
+ - ./data:/var/data
+```
+```
+ volumes:
+ - ./data:/var/data
+ - ./result:/var/result
+```
+```
+ volumes:
+ - ./result:/var/result
+```
+
+
+### Запуск лабораторной:
+Необходимо перейти в папку с файлом docker-compose.yaml и ввести следующую команду:
+```
+docker compose up --build
+```
+Сервис генератора сгенерирует папки data и result, где будут сгенерированы входные файлы и файл-результат их обработки соответственно.
+
+## Видео с результатом запуска:
+
+Видео-демонстрацию работы можно посмотреть по данной [ссылке](https://drive.google.com/file/d/1CmVZjJuMStqNFFKbsMLjw4ihTiMnR7it/view).
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/app-1/Dockerfile b/bogdanov_dmitry_lab_2/app-1/Dockerfile
new file mode 100644
index 0000000..8e7da3d
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/app-1/Dockerfile
@@ -0,0 +1,7 @@
+FROM python:latest
+
+WORKDIR /app
+
+COPY app.py /app/
+
+CMD ["python", "app.py"]
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/app-1/app.py b/bogdanov_dmitry_lab_2/app-1/app.py
new file mode 100644
index 0000000..198331a
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/app-1/app.py
@@ -0,0 +1,30 @@
+import os
+
+# Вариант 2 - Формирует файл /var/result/data.txt из первых строк всех файлов каталога /var/data.
+def solve(dir_files, dir_result, filename_result):
+ # Получаем список файлов в директории
+ filenames = os.listdir(dir_files)
+ result = ''
+ # Проходим через каждый файл
+ for filename in filenames:
+ filepath = os.path.join(dir_files, filename)
+ file = open(filepath, "r")
+ # Читаем первую строку, добавляем к результату
+ result += f"{file.readline()}"
+ file.close()
+
+ # Если директории для сохранения результата нет - создаём
+ if not os.path.exists(dir_result):
+ os.makedirs(dir_result)
+ # Если директория с результатом не пустая - завершаем работу
+ if os.listdir(dir_result):
+ return
+ # Пишем результат в файл
+ filepath_result = os.path.join(dir_result, filename_result)
+ result_file = open(filepath_result, "w")
+ result_file.write(result)
+ print(f"Результат записан в файл {filepath_result}")
+ result_file.close()
+
+if __name__ == "__main__":
+ solve('/var/data', '/var/result', 'data.txt')
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/app-2/Dockerfile b/bogdanov_dmitry_lab_2/app-2/Dockerfile
new file mode 100644
index 0000000..8e7da3d
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/app-2/Dockerfile
@@ -0,0 +1,7 @@
+FROM python:latest
+
+WORKDIR /app
+
+COPY app.py /app/
+
+CMD ["python", "app.py"]
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/app-2/app.py b/bogdanov_dmitry_lab_2/app-2/app.py
new file mode 100644
index 0000000..d401506
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/app-2/app.py
@@ -0,0 +1,21 @@
+import os
+
+# Вариант 1 - Ищет набольшее число из файла /var/data/data.txt и сохраняет его вторую степень в /var/result/result.txt.
+def solve(dir_input, dir_result, filename_result):
+ file_input = open(os.path.join(dir_input, 'data.txt'))
+ # Считываем все числа из файла
+ inputs = [int(line) for line in file_input.readlines()]
+ if inputs:
+ # Максимальное число
+ max_num = max(inputs)
+ print(f"Наибольшее число: {max_num}")
+ # Возводим во 2 степень
+ result = max(inputs) ** 2
+ file_result = open(os.path.join(dir_result, filename_result), "w")
+ # Пишем результат в файл
+ file_result.write(str(result))
+ print(f"Получен результат {result}")
+ file_result.close()
+
+if __name__ == "__main__":
+ solve("/var/result", '/var/result', 'result.txt')
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/app-generator/Dockerfile b/bogdanov_dmitry_lab_2/app-generator/Dockerfile
new file mode 100644
index 0000000..d58d177
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/app-generator/Dockerfile
@@ -0,0 +1,7 @@
+FROM python:latest
+
+WORKDIR /app
+
+COPY generator.py /app/
+
+CMD ["python", "generate_files.py"]
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/app-generator/generator.py b/bogdanov_dmitry_lab_2/app-generator/generator.py
new file mode 100644
index 0000000..e7d2035
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/app-generator/generator.py
@@ -0,0 +1,30 @@
+import os
+import random as rnd
+import string
+
+# Генератор названий файлов
+def generate_filename(l):
+ return ''.join(rnd.choices(string.ascii_lowercase + string.digits, k=l)) + '.txt'
+
+def generate_files(dir, num_files, num_lines):
+ # Если директории для сохранения файлов нет - создаём
+ if not os.path.exists(dir):
+ os.makedirs(dir)
+
+ # Если директория для сохранения файлов не пустая - завершаем работу
+ if os.listdir(dir):
+ return
+
+ # Создание файлов
+ for i in range(num_files):
+ filename = generate_filename(20)
+ filepath = os.path.join(dir, filename)
+
+ file = open(filepath, "w")
+ # Запись строк в файл
+ for j in range(num_lines):
+ file.write(f"{rnd.randint(-1000, 1000)}\n")
+ file.close()
+
+if __name__ == "__main__":
+ generate_files('/var/data', 50, 50)
\ No newline at end of file
diff --git a/bogdanov_dmitry_lab_2/docker-compose.yaml b/bogdanov_dmitry_lab_2/docker-compose.yaml
new file mode 100644
index 0000000..3542011
--- /dev/null
+++ b/bogdanov_dmitry_lab_2/docker-compose.yaml
@@ -0,0 +1,27 @@
+services:
+ # Генератор файлов
+ generator:
+ build:
+ context: ./app-generator # Путь к контексту (докер файл + скрипт)
+ volumes:
+ - ./data:/var/data # Папка контейнера : папка локальная
+ entrypoint: python generator.py # Точка входа
+
+ # Первое приложение
+ app1:
+ build:
+ context: ./app-1 # Путь к контексту
+ volumes:
+ - ./data:/var/data # Монтирование папок
+ - ./result:/var/result
+ depends_on:
+ - generator # Указываем, что запускается только после успешной работы сервиса generator
+
+ # Второе приложение, настройка аналогична сервисам выше
+ app2:
+ build:
+ context: ./app-2
+ volumes:
+ - ./result:/var/result
+ depends_on:
+ - app1
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/README.md b/borschevskaya_anna_lab_4/README.md
new file mode 100644
index 0000000..ce7c98a
--- /dev/null
+++ b/borschevskaya_anna_lab_4/README.md
@@ -0,0 +1,50 @@
+# Отчет. Лабораторная работа 4
+
+## Описание
+В ходе лабораторной работы были изучены главы туториала о работе с RabbitMQ. Результат выполнения заданий каждой главы
+отражен на скриншотах в папке /images:
+- Tutorial-Task1.png
+![Tutorial-Task1](images/Tutorial-Task1.png)
+- Tutorial-Task2.png
+![Tutorial-Task2](images/Tutorial-Task2.png)
+- Tutorial-Task3.png
+![Tutorial-Task3](images/Tutorial-Task3.png)
+
+Задание из 3-ей главы туториала было расширено условиями, которые были поставлены в задании к данной лабораторной работе.
+Для демонстрации работы сервисов посредством ассинхронного общения через брокер сообщений RabbitMQ была выбрана
+предметная область "Обработка заказов".
+
+Сервис-издатель "Publisher" публикует в очередь сообщений событие поступления заказа с некоторым номером.
+
+Сервисы-подписчики обрабатывают сообщения о заказах, при этом подписчики обрабатывают сообщение по-разному. Один вид
+подписчика обрабатывает с задержкой в несколько секунд, другой - "мгновенно", они получают одни и те жа сообщения,
+но соединены с разными очередями.
+В качестве эксперимента изначально были запущены по одному экземпляру каждого вида.
+На изображении Consumer2.png представлена работа мгновенно обрабатывающего подписчика. Он справляется с нагрузкой,
+так как размер очереди не растет.
+![Consumer 2](images/Consumer2.png)
+На изображении Consumer1.png представлена работа подписчика, обрабатывающего сообщения с задержкой. Как мы видим,
+в очереди накапливаются сообщения в состоянии 'Ready' - эти сообщения готовы для того, чтобы быть доставленными подписчикам.
+Сервис не справляется с нагрузкой, так как отправляются сообщения быстрее, чем обрабатываются.
+![Consumer 1](images/Consumer1.png)
+Для того, чтобы обеспечить равную скорость отправки и обработки, увеличиваем количество экземпляров-подписчиков данного типа до трех.
+На изображении видно, что теперь длина очереди не растет и система справляется с поступающими сообщениями. Также скорость "publish" и
+"consumer ack" стали равны.
+![Consumer 1](images/Consumer1-scaling.png)
+## Как запустить
+Для того, чтобы запустить сервисы, необходимо выполнить следующие действия:
+1. Установить и запустить Docker Engine или Docker Desktop
+2. Через консоль перейти в папку, в которой расположен файл docker-compose.yml
+3. Выполнить команду для запуска брокера сообщений rabbitmq:
+```
+docker compose up rabbit -d
+```
+4. Выполнить команду для запуска остальных контейнеров:
+```
+docker compose up -d
+```
+Такой порядок запуска важен для того, чтобы брокер сообщений успел полностью запуститься
+и произвести действия для того, чтобы быть готовым принимать соединения от сервисов. Потому что указания depends_on не хватает
+для отслеживания завершения всех необходимых подготовительных процессов брокера.
+## Видео-отчет
+Работоспособность лабораторной работы можно оценить в следующем [видео](https://disk.yandex.ru/i/G0vsfp7vwazYHw).
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/consumer-app/Dockerfile b/borschevskaya_anna_lab_4/consumer-app/Dockerfile
new file mode 100644
index 0000000..30fc690
--- /dev/null
+++ b/borschevskaya_anna_lab_4/consumer-app/Dockerfile
@@ -0,0 +1,23 @@
+# Используем образ Maven для сборки
+FROM maven:3.8-eclipse-temurin-21-alpine AS build
+
+# Устанавливаем рабочую директорию
+WORKDIR /app
+
+# Копируем остальные исходные файлы
+COPY pom.xml .
+COPY src src
+
+# Собираем весь проект
+RUN mvn clean package -DskipTests
+RUN mvn dependency:copy-dependencies
+
+# Используем официальный образ JDK для запуска собранного jar-файла
+FROM eclipse-temurin:21-jdk-alpine
+
+# Копируем jar-файл из предыдущего этапа
+COPY --from=build /app/target/*.jar /app.jar
+COPY --from=build /app/target/dependency /
+
+# Указываем команду для запуска приложения
+CMD ["java", "-jar", "app.jar"]
diff --git a/borschevskaya_anna_lab_4/consumer-app/pom.xml b/borschevskaya_anna_lab_4/consumer-app/pom.xml
new file mode 100644
index 0000000..a8ee175
--- /dev/null
+++ b/borschevskaya_anna_lab_4/consumer-app/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ ru.somecompany
+ consumer-app
+ 1.0.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.3
+
+
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.rabbitmq
+ amqp-client
+ 5.22.0
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/Main.java b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/Main.java
new file mode 100644
index 0000000..c541a18
--- /dev/null
+++ b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/Main.java
@@ -0,0 +1,15 @@
+package ru.somecompany;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import ru.somecompany.config.property.RabbitProperties;
+
+@SpringBootApplication
+@ConfigurationPropertiesScan(basePackageClasses = RabbitProperties.class)
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class, args);
+ }
+}
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/config/ConnectionFactoryConfig.java b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/config/ConnectionFactoryConfig.java
new file mode 100644
index 0000000..3dadb49
--- /dev/null
+++ b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/config/ConnectionFactoryConfig.java
@@ -0,0 +1,45 @@
+package ru.somecompany.config;
+
+import com.rabbitmq.client.BuiltinExchangeType;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import ru.somecompany.config.property.RabbitProperties;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+@Configuration
+@RequiredArgsConstructor
+public class ConnectionFactoryConfig {
+
+ private final RabbitProperties rabbitProperties;
+
+ @Bean
+ public ConnectionFactory connectionFactory() {
+ ConnectionFactory factory = new ConnectionFactory();
+ factory.setHost(rabbitProperties.getHost());
+ factory.setPort(rabbitProperties.getPort());
+ return factory;
+ }
+
+ @Bean
+ public Connection connection(ConnectionFactory connectionFactory) throws IOException, TimeoutException {
+ return connectionFactory.newConnection();
+ }
+
+ @Bean
+ public Channel channel(Connection connection) throws IOException {
+ var exchange = rabbitProperties.getExchange();
+ var queue = rabbitProperties.getQueue();
+ var channel = connection.createChannel();
+
+ channel.exchangeDeclare(exchange, BuiltinExchangeType.FANOUT);
+ channel.queueDeclare(queue, true, false, true, null);
+ channel.queueBind(queue, exchange, "");
+ return channel;
+ }
+}
diff --git a/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/config/property/RabbitProperties.java b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/config/property/RabbitProperties.java
new file mode 100644
index 0000000..25f73f7
--- /dev/null
+++ b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/config/property/RabbitProperties.java
@@ -0,0 +1,19 @@
+package ru.somecompany.config.property;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Data
+@ConfigurationProperties(prefix = "app.rabbit-properties")
+public class RabbitProperties {
+
+ private String host;
+
+ private Integer port;
+
+ private Integer delay;
+
+ private String queue;
+
+ private String exchange;
+}
diff --git a/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/consumer/Consumer.java b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/consumer/Consumer.java
new file mode 100644
index 0000000..4f0d5b6
--- /dev/null
+++ b/borschevskaya_anna_lab_4/consumer-app/src/main/java/ru/somecompany/consumer/Consumer.java
@@ -0,0 +1,76 @@
+package ru.somecompany.consumer;
+
+import com.rabbitmq.client.AMQP;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.DefaultConsumer;
+import com.rabbitmq.client.Envelope;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import ru.somecompany.config.property.RabbitProperties;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class Consumer {
+
+ private final RabbitProperties rabbitProperties;
+
+ private final Connection connection;
+ private final Channel channel;
+
+ @PostConstruct
+ public void consume() {
+ try {
+ channel.basicQos(1);
+ channel.basicConsume(rabbitProperties.getQueue(), false, new DefaultConsumer(channel) {
+ @Override
+ public void handleDelivery(String consumerTag,
+ Envelope envelope,
+ AMQP.BasicProperties properties,
+ byte[] body) throws IOException {
+ long deliveryTag = envelope.getDeliveryTag();
+
+ String message = new String(body, StandardCharsets.UTF_8);
+ System.out.println(" [x] Received '" + message + "'");
+
+ var delay = rabbitProperties.getDelay();
+ try {
+ doWork(delay);
+ } finally {
+ System.out.println(" [x] Processed '" + message + "'");
+ channel.basicAck(deliveryTag, false);
+ }
+ }
+ });
+ } catch (Exception exception) {
+ log.error("Error while set up connection with rabbit", exception);
+ }
+ }
+
+ private static void doWork(Integer delay) {
+ if (delay > 0) {
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException _ignored) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ @PreDestroy
+ public void cleanUp() throws Exception {
+ if (channel != null) {
+ channel.close();
+ }
+ if (connection != null) {
+ connection.close();
+ }
+ }
+}
diff --git a/borschevskaya_anna_lab_4/consumer-app/src/main/resources/application.yml b/borschevskaya_anna_lab_4/consumer-app/src/main/resources/application.yml
new file mode 100644
index 0000000..a7cded6
--- /dev/null
+++ b/borschevskaya_anna_lab_4/consumer-app/src/main/resources/application.yml
@@ -0,0 +1,10 @@
+server:
+ port: ${SERVER_PORT:8081}
+
+app:
+ rabbit-properties:
+ host: ${RABBIT_HOST:localhost}
+ port: ${RABBIT_PORT:5672}
+ delay: ${PROCESS_DELAY:0}
+ queue: ${QUEUE_NAME:queue-1}
+ exchange: ${EXCHANGE_NAME:order-events}
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/docker-compose.yml b/borschevskaya_anna_lab_4/docker-compose.yml
new file mode 100644
index 0000000..a59cc51
--- /dev/null
+++ b/borschevskaya_anna_lab_4/docker-compose.yml
@@ -0,0 +1,79 @@
+services:
+ rabbit:
+ container_name: rabbit
+ image: rabbitmq:3-management
+ ports:
+ - "15672:15672"
+ - "5672:5672"
+ - "5671:5671"
+ networks:
+ - local
+ publisher:
+ build: ./publisher-app
+ container_name: publisher
+ depends_on:
+ - rabbit
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_PORT: 5672
+ networks:
+ - local
+ consumer-1:
+ build: ./consumer-app
+ container_name: consumer-1
+ depends_on:
+ - rabbit
+ - publisher
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_PORT: 5672
+ PROCESS_DELAY: 3000
+ QUEUE_NAME: queue1
+ EXCHANGE_NAME: order-events
+ networks:
+ - local
+ consumer-2:
+ build: ./consumer-app
+ container_name: consumer-2
+ depends_on:
+ - rabbit
+ - publisher
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_PORT: 5672
+ PROCESS_DELAY: 0
+ QUEUE_NAME: queue2
+ EXCHANGE_NAME: order-events
+ networks:
+ - local
+ consumer-12:
+ build: ./consumer-app
+ container_name: consumer-12
+ depends_on:
+ - rabbit
+ - publisher
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_PORT: 5672
+ PROCESS_DELAY: 3000
+ QUEUE_NAME: queue1
+ EXCHANGE_NAME: order-events
+ networks:
+ - local
+ consumer-13:
+ build: ./consumer-app
+ container_name: consumer-13
+ depends_on:
+ - rabbit
+ - publisher
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_PORT: 5672
+ PROCESS_DELAY: 3000
+ QUEUE_NAME: queue1
+ EXCHANGE_NAME: order-events
+ networks:
+ - local
+
+networks:
+ local:
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/helloworld-tutorial/pom.xml b/borschevskaya_anna_lab_4/helloworld-tutorial/pom.xml
new file mode 100644
index 0000000..2a85c45
--- /dev/null
+++ b/borschevskaya_anna_lab_4/helloworld-tutorial/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ ru.somecompany
+ helloworld-tutorial
+ 1.0-SNAPSHOT
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ com.rabbitmq
+ amqp-client
+ 5.22.0
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.5
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.7.5
+
+
+
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Main.java b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Main.java
new file mode 100644
index 0000000..13f9f54
--- /dev/null
+++ b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Main.java
@@ -0,0 +1,28 @@
+package ru.somecompany;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import com.rabbitmq.client.DeliverCallback;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeoutException;
+
+public class Main {
+
+ private static final String QUEUE_NAME = "hello-world";
+
+ public static void main(String[] args) {
+ ConnectionFactory factory = new ConnectionFactory();
+ factory.setHost("localhost");
+ try(Connection connection = factory.newConnection();
+ Channel channel = connection.createChannel();) {
+ var sender = new Sender(channel);
+ var receiver = new Receiver(channel);
+
+ } catch (Exception e) {
+ System.out.println(" [*] Error in Hello-World");
+ }
+ }
+}
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Receiver.java b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Receiver.java
new file mode 100644
index 0000000..ce8f740
--- /dev/null
+++ b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Receiver.java
@@ -0,0 +1,20 @@
+package ru.somecompany;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.DeliverCallback;
+
+import java.io.IOException;
+
+public class Receiver {
+
+ private static final String QUEUE_NAME = "hello-world";
+
+ public Receiver(Channel channel) throws IOException {
+ channel.queueDeclare(QUEUE_NAME, false, false, false, null);
+ DeliverCallback deliverCallback = (consumerTag, delivery) -> {
+ String message = new String(delivery.getBody(), "UTF-8");
+ System.out.println(" [x] Received '" + message + "'");
+ };
+ channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
+ }
+}
diff --git a/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Sender.java b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Sender.java
new file mode 100644
index 0000000..05afcfc
--- /dev/null
+++ b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/java/ru/somecompany/Sender.java
@@ -0,0 +1,18 @@
+package ru.somecompany;
+
+import com.rabbitmq.client.Channel;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+public class Sender {
+
+ private static final String QUEUE_NAME = "hello-world";
+
+ public Sender(Channel channel) throws IOException {
+ channel.queueDeclare(QUEUE_NAME, false, false, false, null);
+ String message = "Hello World!";
+ channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
+ System.out.println(" [x] Sent '" + message + "'");
+ }
+}
diff --git a/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/resources/log4j.properties b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/resources/log4j.properties
new file mode 100644
index 0000000..393e087
--- /dev/null
+++ b/borschevskaya_anna_lab_4/helloworld-tutorial/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/images/Consumer1-scaling.PNG b/borschevskaya_anna_lab_4/images/Consumer1-scaling.PNG
new file mode 100644
index 0000000..9a87b2b
Binary files /dev/null and b/borschevskaya_anna_lab_4/images/Consumer1-scaling.PNG differ
diff --git a/borschevskaya_anna_lab_4/images/Consumer1.PNG b/borschevskaya_anna_lab_4/images/Consumer1.PNG
new file mode 100644
index 0000000..7c60be9
Binary files /dev/null and b/borschevskaya_anna_lab_4/images/Consumer1.PNG differ
diff --git a/borschevskaya_anna_lab_4/images/Consumer2.PNG b/borschevskaya_anna_lab_4/images/Consumer2.PNG
new file mode 100644
index 0000000..9592d50
Binary files /dev/null and b/borschevskaya_anna_lab_4/images/Consumer2.PNG differ
diff --git a/borschevskaya_anna_lab_4/images/Tutorial-Task1.PNG b/borschevskaya_anna_lab_4/images/Tutorial-Task1.PNG
new file mode 100644
index 0000000..b2129cd
Binary files /dev/null and b/borschevskaya_anna_lab_4/images/Tutorial-Task1.PNG differ
diff --git a/borschevskaya_anna_lab_4/images/Tutorial-Task2.PNG b/borschevskaya_anna_lab_4/images/Tutorial-Task2.PNG
new file mode 100644
index 0000000..e29defd
Binary files /dev/null and b/borschevskaya_anna_lab_4/images/Tutorial-Task2.PNG differ
diff --git a/borschevskaya_anna_lab_4/images/Tutorial-Task3.PNG b/borschevskaya_anna_lab_4/images/Tutorial-Task3.PNG
new file mode 100644
index 0000000..e77d7af
Binary files /dev/null and b/borschevskaya_anna_lab_4/images/Tutorial-Task3.PNG differ
diff --git a/borschevskaya_anna_lab_4/publisher-app/.gitignore b/borschevskaya_anna_lab_4/publisher-app/.gitignore
new file mode 100644
index 0000000..5ff6309
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/publisher-app/Dockerfile b/borschevskaya_anna_lab_4/publisher-app/Dockerfile
new file mode 100644
index 0000000..cc673eb
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/Dockerfile
@@ -0,0 +1,21 @@
+# Используем образ Maven для сборки
+FROM maven:3.8-eclipse-temurin-21-alpine AS build
+
+# Устанавливаем рабочую директорию
+WORKDIR /app
+
+# Копируем остальные исходные файлы
+COPY pom.xml .
+COPY src src
+
+# Собираем весь проект
+RUN mvn clean package -DskipTests
+
+# Используем официальный образ JDK для запуска собранного jar-файла
+FROM eclipse-temurin:21-jdk-alpine
+
+# Копируем jar-файл из предыдущего этапа
+COPY --from=build /app/target/*.jar /app.jar
+
+# Указываем команду для запуска приложения
+CMD ["java", "-jar", "app.jar"]
diff --git a/borschevskaya_anna_lab_4/publisher-app/pom.xml b/borschevskaya_anna_lab_4/publisher-app/pom.xml
new file mode 100644
index 0000000..4cfb240
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+
+ ru.somecompany
+ publisher-app
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.3
+
+
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
+ com.rabbitmq
+ amqp-client
+ 5.22.0
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/Main.java b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/Main.java
new file mode 100644
index 0000000..1ce208a
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/Main.java
@@ -0,0 +1,17 @@
+package ru.somecompany;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import ru.somecompany.config.property.RabbitProperties;
+
+@EnableScheduling
+@SpringBootApplication
+@ConfigurationPropertiesScan(basePackageClasses = RabbitProperties.class)
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class, args);
+ }
+}
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/config/ConnectionFactoryConfig.java b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/config/ConnectionFactoryConfig.java
new file mode 100644
index 0000000..0cef48f
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/config/ConnectionFactoryConfig.java
@@ -0,0 +1,40 @@
+package ru.somecompany.config;
+
+import com.rabbitmq.client.BuiltinExchangeType;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import ru.somecompany.config.property.RabbitProperties;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+@Configuration
+@RequiredArgsConstructor
+public class ConnectionFactoryConfig {
+
+ private final RabbitProperties rabbitProperties;
+
+ @Bean
+ public ConnectionFactory connectionFactory() {
+ ConnectionFactory factory = new ConnectionFactory();
+ factory.setHost(rabbitProperties.getHost());
+ factory.setPort(rabbitProperties.getPort());
+ return factory;
+ }
+
+ @Bean
+ public Connection connection(ConnectionFactory connectionFactory) throws IOException, TimeoutException {
+ return connectionFactory.newConnection();
+ }
+
+ @Bean
+ public Channel channel(Connection connection) throws IOException {
+ var channel = connection.createChannel();
+ channel.exchangeDeclare(rabbitProperties.getExchange(), BuiltinExchangeType.FANOUT);
+ return channel;
+ }
+}
diff --git a/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/config/property/RabbitProperties.java b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/config/property/RabbitProperties.java
new file mode 100644
index 0000000..29a8bc5
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/config/property/RabbitProperties.java
@@ -0,0 +1,15 @@
+package ru.somecompany.config.property;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Data
+@ConfigurationProperties(prefix = "app.rabbit-properties")
+public class RabbitProperties {
+
+ private String host;
+
+ private Integer port;
+
+ private String exchange;
+}
diff --git a/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/scheduler/SenderScheduler.java b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/scheduler/SenderScheduler.java
new file mode 100644
index 0000000..66fed4c
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/src/main/java/ru/somecompany/scheduler/SenderScheduler.java
@@ -0,0 +1,41 @@
+package ru.somecompany.scheduler;
+
+import com.rabbitmq.client.BuiltinExchangeType;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import lombok.RequiredArgsConstructor;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeoutException;
+
+@Service
+@RequiredArgsConstructor
+public class SenderScheduler {
+
+ private static final String EXCHANGE_NAME = "order-events";
+ private static final String MESSAGE = "Поступил заказ №%d";
+ private Integer index = 0;
+
+ private final ConnectionFactory connectionFactory;
+ private final Connection connection;
+ private final Channel channel;
+
+ @Scheduled(cron = "*/1 * * * * *")
+ public void sendMessage() {
+ try {
+ var message = String.format(MESSAGE, index);
+
+ channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes(StandardCharsets.UTF_8));
+ index++;
+ System.out.println(" [x] Sent '" + message + "'");
+ } catch (IOException e) {
+ System.out.println(" [x] Error while send message");
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/borschevskaya_anna_lab_4/publisher-app/src/main/resources/application.yml b/borschevskaya_anna_lab_4/publisher-app/src/main/resources/application.yml
new file mode 100644
index 0000000..983abc0
--- /dev/null
+++ b/borschevskaya_anna_lab_4/publisher-app/src/main/resources/application.yml
@@ -0,0 +1,8 @@
+server:
+ port: ${SERVER_PORT:8080}
+
+app:
+ rabbit-properties:
+ host: ${RABBIT_HOST:localhost}
+ port: ${RABBIT_PORT:5672}
+ exchange: ${EXCHANGE_NAME:order-events}
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/workqueue-tutorial/pom.xml b/borschevskaya_anna_lab_4/workqueue-tutorial/pom.xml
new file mode 100644
index 0000000..4a67d9f
--- /dev/null
+++ b/borschevskaya_anna_lab_4/workqueue-tutorial/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ ru.somecompany
+ workqueue-tutorial
+ 1.0-SNAPSHOT
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ com.rabbitmq
+ amqp-client
+ 5.22.0
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.7.5
+
+
+
+
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Main.java b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Main.java
new file mode 100644
index 0000000..8e49bb1
--- /dev/null
+++ b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Main.java
@@ -0,0 +1,23 @@
+package ru.somecompany;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+
+public class Main {
+
+ public static final String QUEUE_NAME = "task_queue";
+
+ public static void main(String[] args) {
+ ConnectionFactory factory = new ConnectionFactory();
+ factory.setHost("localhost");
+ try(Connection connection = factory.newConnection();
+ Channel channel = connection.createChannel();) {
+ var sender = new Sender(channel);
+ sender.send("Work Queue message");
+ var receiver = new Receiver(channel);
+ } catch (Exception e) {
+ System.out.println(" [*] Error in Work-Queue: " + e.getMessage());
+ }
+ }
+}
\ No newline at end of file
diff --git a/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Receiver.java b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Receiver.java
new file mode 100644
index 0000000..4569eef
--- /dev/null
+++ b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Receiver.java
@@ -0,0 +1,44 @@
+package ru.somecompany;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.DeliverCallback;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import static ru.somecompany.Main.QUEUE_NAME;
+
+public class Receiver {
+
+ public Receiver(Channel channel) throws IOException {
+ channel.queueDeclare(QUEUE_NAME, true, false, false, null);
+ System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
+
+ channel.basicQos(1);
+
+ DeliverCallback deliverCallback = (consumerTag, delivery) -> {
+ String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
+
+ System.out.println(" [x] Received '" + message + "'");
+ try {
+ doWork(message);
+ } finally {
+ System.out.println(" [x] Done");
+ channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
+ }
+ };
+ channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> { });
+ }
+
+ private static void doWork(String task) {
+ for (char ch : task.toCharArray()) {
+ if (ch == '.') {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException _ignored) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ }
+}
diff --git a/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Sender.java b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Sender.java
new file mode 100644
index 0000000..3b7ea29
--- /dev/null
+++ b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/java/ru/somecompany/Sender.java
@@ -0,0 +1,29 @@
+package ru.somecompany;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.MessageProperties;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+
+import static ru.somecompany.Main.QUEUE_NAME;
+
+public class Sender {
+
+ private Channel channel;
+
+ public Sender(Channel channel) throws IOException {
+ channel.queueDeclare(QUEUE_NAME, true, false, false, null);
+ this.channel = channel;
+ }
+
+ public void send(String msg) throws IOException {
+ String message = String.join(" ", msg);
+
+ channel.basicPublish("", QUEUE_NAME,
+ MessageProperties.PERSISTENT_TEXT_PLAIN,
+ message.getBytes("UTF-8"));
+ System.out.println(" [x] Sent '" + message + "'");
+ }
+}
diff --git a/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/resources/log4j.properties b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/resources/log4j.properties
new file mode 100644
index 0000000..393e087
--- /dev/null
+++ b/borschevskaya_anna_lab_4/workqueue-tutorial/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerDelay/.dockerignore b/dozorova_alena_lab_4/ConsumerDelay/.dockerignore
new file mode 100644
index 0000000..fe1152b
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerDelay/.dockerignore
@@ -0,0 +1,30 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
+!**/.gitignore
+!.git/HEAD
+!.git/config
+!.git/packed-refs
+!.git/refs/heads/**
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.csproj b/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.csproj
new file mode 100644
index 0000000..a04999b
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ Linux
+ .
+
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.csproj.user b/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.csproj.user
new file mode 100644
index 0000000..dd2d54c
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ Container (Dockerfile)
+
+
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.sln b/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.sln
new file mode 100644
index 0000000..f3a6ad6
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerDelay/ConsumerDelay.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35004.147
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumerDelay", "ConsumerDelay.csproj", "{4DD86D5F-D90D-4BBB-AAA4-F16DA855B51E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4DD86D5F-D90D-4BBB-AAA4-F16DA855B51E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4DD86D5F-D90D-4BBB-AAA4-F16DA855B51E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4DD86D5F-D90D-4BBB-AAA4-F16DA855B51E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4DD86D5F-D90D-4BBB-AAA4-F16DA855B51E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {3E7AED20-0868-42FE-9C39-581BC9D2BB22}
+ EndGlobalSection
+EndGlobal
diff --git a/dozorova_alena_lab_4/ConsumerDelay/Dockerfile b/dozorova_alena_lab_4/ConsumerDelay/Dockerfile
new file mode 100644
index 0000000..e47b674
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerDelay/Dockerfile
@@ -0,0 +1,22 @@
+#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
+WORKDIR /app
+
+FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["ConsumerDelay.csproj", "."]
+RUN dotnet restore "./ConsumerDelay.csproj"
+COPY . .
+WORKDIR "/src/."
+RUN dotnet build "./ConsumerDelay.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "./ConsumerDelay.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "ConsumerDelay.dll"]
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerDelay/Program.cs b/dozorova_alena_lab_4/ConsumerDelay/Program.cs
new file mode 100644
index 0000000..8882de6
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerDelay/Program.cs
@@ -0,0 +1,24 @@
+using ConsumerDelay;
+
+var rabbitHost = Environment.GetEnvironmentVariable("RABBIT_HOST") ?? "localhost";
+var rabbitUsername = Environment.GetEnvironmentVariable("RABBIT_USERNAME") ?? "user";
+var rabbitPassword = Environment.GetEnvironmentVariable("RABBIT_PASSWORD") ?? "password";
+var rabbitExchange = Environment.GetEnvironmentVariable("RABBIT_EXCHANGE") ?? "ReportIn";
+var rabbitQueue = Environment.GetEnvironmentVariable("RABBIT_QUEUE") ?? "Second";
+
+Thread.Sleep(2000);
+
+var receiver = new Receiver(rabbitHost, rabbitUsername, rabbitPassword);
+
+receiver.SubscribeTo(rabbitExchange, (message) =>
+{
+ var rnd = new Random();
+
+ Console.WriteLine($"Пришло сообщение: {message}");
+
+ Thread.Sleep(rnd.Next(2000, 3000));
+ Console.WriteLine($"Обработка сообщения завершена");
+},
+rabbitQueue);
+
+while (true) ;
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerDelay/Receiver.cs b/dozorova_alena_lab_4/ConsumerDelay/Receiver.cs
new file mode 100644
index 0000000..f4e488b
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerDelay/Receiver.cs
@@ -0,0 +1,82 @@
+using RabbitMQ.Client;
+using RabbitMQ.Client.Events;
+using System.Text;
+
+namespace ConsumerDelay
+{
+ public class Receiver : IDisposable
+ {
+ private readonly ConnectionFactory _connectionFactory;
+ private readonly IConnection _connection;
+ private readonly IModel _channel;
+
+ public Dictionary> Queues { get; private set; } = new();
+
+ public Receiver(string brockerHost, string brockerUsername, string brockerPassword)
+ {
+ _connectionFactory = new ConnectionFactory() { HostName = brockerHost, UserName = brockerUsername, Password = brockerPassword };
+ _connection = _connectionFactory.CreateConnection();
+ _channel = _connection.CreateModel();
+ }
+
+ public bool SubscribeTo(string exchange, Action handler, string? queueName = null)
+ {
+ try
+ {
+ if (!Queues.ContainsKey(exchange))
+ {
+ _channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
+ Queues.Add(exchange, new HashSet());
+ }
+ if (queueName != null)
+ _channel.QueueDeclare(queue: queueName,
+ durable: true,
+ exclusive: false,
+ autoDelete: false,
+ arguments: null);
+
+ queueName = queueName ?? _channel.QueueDeclare().QueueName;
+
+
+ _channel.QueueBind(queue: queueName,
+ exchange: exchange,
+ routingKey: string.Empty);
+
+ var consumer = new EventingBasicConsumer(_channel);
+ consumer.Received += (model, ea) =>
+ {
+ try
+ {
+ var message = Encoding.UTF8.GetString(ea.Body.ToArray());
+ handler(message);
+ _channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ };
+ _channel.BasicConsume(queue: queueName,
+ autoAck: false,
+ consumer: consumer);
+
+ Queues[exchange].Add(queueName);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ return false;
+ }
+
+ ~Receiver() => Dispose();
+
+ public void Dispose()
+ {
+ _connection.Dispose();
+ _channel.Dispose();
+ }
+ }
+}
diff --git a/dozorova_alena_lab_4/ConsumerSimple/.dockerignore b/dozorova_alena_lab_4/ConsumerSimple/.dockerignore
new file mode 100644
index 0000000..fe1152b
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/.dockerignore
@@ -0,0 +1,30 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
+!**/.gitignore
+!.git/HEAD
+!.git/config
+!.git/packed-refs
+!.git/refs/heads/**
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.csproj b/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.csproj
new file mode 100644
index 0000000..a04999b
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ Linux
+ .
+
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.csproj.user b/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.csproj.user
new file mode 100644
index 0000000..dd2d54c
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ Container (Dockerfile)
+
+
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.sln b/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.sln
new file mode 100644
index 0000000..64dba82
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/ConsumerSimple.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35004.147
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumerSimple", "ConsumerSimple.csproj", "{ACA8DE52-E29E-41BA-B3DA-213AF316685E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {ACA8DE52-E29E-41BA-B3DA-213AF316685E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ACA8DE52-E29E-41BA-B3DA-213AF316685E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ACA8DE52-E29E-41BA-B3DA-213AF316685E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ACA8DE52-E29E-41BA-B3DA-213AF316685E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {73265D6C-436C-470E-AE8A-17047E6C2ECC}
+ EndGlobalSection
+EndGlobal
diff --git a/dozorova_alena_lab_4/ConsumerSimple/Dockerfile b/dozorova_alena_lab_4/ConsumerSimple/Dockerfile
new file mode 100644
index 0000000..92d16b0
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/Dockerfile
@@ -0,0 +1,22 @@
+#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
+WORKDIR /app
+
+FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["ConsumerSimple.csproj", "."]
+RUN dotnet restore "./ConsumerSimple.csproj"
+COPY . .
+WORKDIR "/src/."
+RUN dotnet build "./ConsumerSimple.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "./ConsumerSimple.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "ConsumerSimple.dll"]
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerSimple/Program.cs b/dozorova_alena_lab_4/ConsumerSimple/Program.cs
new file mode 100644
index 0000000..5aab041
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/Program.cs
@@ -0,0 +1,23 @@
+using ConsumerSimple;
+
+var rabbitHost = Environment.GetEnvironmentVariable("RABBIT_HOST") ?? "localhost";
+var rabbitUsername = Environment.GetEnvironmentVariable("RABBIT_USERNAME") ?? "user";
+var rabbitPassword = Environment.GetEnvironmentVariable("RABBIT_PASSWORD") ?? "password";
+var rabbitExchange = Environment.GetEnvironmentVariable("RABBIT_EXCHANGE") ?? "ReportIn";
+var rabbitQueue = Environment.GetEnvironmentVariable("RABBIT_QUEUE") ?? "First";
+
+Thread.Sleep(2000);
+
+var receiver = new Receiver(rabbitHost, rabbitUsername, rabbitPassword);
+
+receiver.SubscribeTo(rabbitExchange, (message) =>
+{
+ var rnd = new Random();
+
+ Console.WriteLine($"Пришло сообщение: {message}");
+
+ Console.WriteLine($"Сообщение обрабатывается мгновенно");
+},
+rabbitQueue);
+
+while (true) ;
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerSimple/Properties/launchSettings.json b/dozorova_alena_lab_4/ConsumerSimple/Properties/launchSettings.json
new file mode 100644
index 0000000..b9fc529
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/Properties/launchSettings.json
@@ -0,0 +1,10 @@
+{
+ "profiles": {
+ "ConsumerSimple": {
+ "commandName": "Project"
+ },
+ "Container (Dockerfile)": {
+ "commandName": "Docker"
+ }
+ }
+}
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ConsumerSimple/Receiver.cs b/dozorova_alena_lab_4/ConsumerSimple/Receiver.cs
new file mode 100644
index 0000000..9efdd27
--- /dev/null
+++ b/dozorova_alena_lab_4/ConsumerSimple/Receiver.cs
@@ -0,0 +1,82 @@
+using RabbitMQ.Client;
+using RabbitMQ.Client.Events;
+using System.Text;
+
+namespace ConsumerSimple
+{
+ public class Receiver : IDisposable
+ {
+ private readonly ConnectionFactory _connectionFactory;
+ private readonly IConnection _connection;
+ private readonly IModel _channel;
+
+ public Dictionary> Queues { get; private set; } = new();
+
+ public Receiver(string brockerHost, string brockerUsername, string brockerPassword)
+ {
+ _connectionFactory = new ConnectionFactory() { HostName = brockerHost, UserName = brockerUsername, Password = brockerPassword };
+ _connection = _connectionFactory.CreateConnection();
+ _channel = _connection.CreateModel();
+ }
+
+ public bool SubscribeTo(string exchange, Action handler, string? queueName = null)
+ {
+ try
+ {
+ if (!Queues.ContainsKey(exchange))
+ {
+ _channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
+ Queues.Add(exchange, new HashSet());
+ }
+ if (queueName != null)
+ _channel.QueueDeclare(queue: queueName,
+ durable: true,
+ exclusive: false,
+ autoDelete: false,
+ arguments: null);
+
+ queueName = queueName ?? _channel.QueueDeclare().QueueName;
+
+
+ _channel.QueueBind(queue: queueName,
+ exchange: exchange,
+ routingKey: string.Empty);
+
+ var consumer = new EventingBasicConsumer(_channel);
+ consumer.Received += (model, ea) =>
+ {
+ try
+ {
+ var message = Encoding.UTF8.GetString(ea.Body.ToArray());
+ handler(message);
+ _channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ };
+ _channel.BasicConsume(queue: queueName,
+ autoAck: false,
+ consumer: consumer);
+
+ Queues[exchange].Add(queueName);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ return false;
+ }
+
+ ~Receiver() => Dispose();
+
+ public void Dispose()
+ {
+ _connection.Dispose();
+ _channel.Dispose();
+ }
+ }
+}
diff --git a/dozorova_alena_lab_4/EmitLog/EmitLog..csproj b/dozorova_alena_lab_4/EmitLog/EmitLog..csproj
new file mode 100644
index 0000000..efea465
--- /dev/null
+++ b/dozorova_alena_lab_4/EmitLog/EmitLog..csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net8.0
+ EmitLog_
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/EmitLog/Program.cs b/dozorova_alena_lab_4/EmitLog/Program.cs
new file mode 100644
index 0000000..73120f4
--- /dev/null
+++ b/dozorova_alena_lab_4/EmitLog/Program.cs
@@ -0,0 +1,24 @@
+using System.Text;
+using RabbitMQ.Client;
+
+var factory = new ConnectionFactory { HostName = "localhost" };
+using var connection = factory.CreateConnection();
+using var channel = connection.CreateModel();
+
+channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
+
+var message = GetMessage(args);
+var body = Encoding.UTF8.GetBytes(message);
+channel.BasicPublish(exchange: "logs",
+ routingKey: string.Empty,
+ basicProperties: null,
+ body: body);
+Console.WriteLine($" [x] Sent {message}");
+
+Console.WriteLine(" Press [enter] to exit.");
+Console.ReadLine();
+
+static string GetMessage(string[] args)
+{
+ return ((args.Length > 0) ? string.Join(" ", args) : "info: Hello World!");
+}
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/NewTask/NewTask.csproj b/dozorova_alena_lab_4/NewTask/NewTask.csproj
new file mode 100644
index 0000000..f72406b
--- /dev/null
+++ b/dozorova_alena_lab_4/NewTask/NewTask.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/NewTask/Program.cs b/dozorova_alena_lab_4/NewTask/Program.cs
new file mode 100644
index 0000000..0928eb7
--- /dev/null
+++ b/dozorova_alena_lab_4/NewTask/Program.cs
@@ -0,0 +1,32 @@
+using System.Text;
+using RabbitMQ.Client;
+
+var factory = new ConnectionFactory { HostName = "localhost" };
+using var connection = factory.CreateConnection();
+using var channel = connection.CreateModel();
+
+channel.QueueDeclare(queue: "task_queue",
+ durable: true,
+ exclusive: false,
+ autoDelete: false,
+ arguments: null);
+
+var message = GetMessage(args);
+var body = Encoding.UTF8.GetBytes(message);
+
+var properties = channel.CreateBasicProperties();
+properties.Persistent = true;
+
+channel.BasicPublish(exchange: string.Empty,
+ routingKey: "task_queue",
+ basicProperties: properties,
+ body: body);
+Console.WriteLine($" [x] Sent {message}");
+
+Console.WriteLine(" Press [enter] to exit.");
+Console.ReadLine();
+
+static string GetMessage(string[] args)
+{
+ return ((args.Length > 0) ? string.Join(" ", args) : "Hello World!");
+}
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Publisher/.dockerignore b/dozorova_alena_lab_4/Publisher/.dockerignore
new file mode 100644
index 0000000..fe1152b
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/.dockerignore
@@ -0,0 +1,30 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
+!**/.gitignore
+!.git/HEAD
+!.git/config
+!.git/packed-refs
+!.git/refs/heads/**
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Publisher/Dockerfile b/dozorova_alena_lab_4/Publisher/Dockerfile
new file mode 100644
index 0000000..80db941
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/Dockerfile
@@ -0,0 +1,20 @@
+FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
+WORKDIR /app
+
+FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["Publisher.csproj", "."]
+RUN dotnet restore "./Publisher.csproj"
+COPY . .
+WORKDIR "/src/."
+RUN dotnet build "./Publisher.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "./Publisher.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "Publisher.dll"]
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Publisher/Program.cs b/dozorova_alena_lab_4/Publisher/Program.cs
new file mode 100644
index 0000000..f45f635
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/Program.cs
@@ -0,0 +1,40 @@
+using Publisher;
+using System.Text;
+
+var rabbitHost = Environment.GetEnvironmentVariable("RABBIT_HOST") ?? "localhost";
+var rabbitUsername = Environment.GetEnvironmentVariable("RABBIT_USERNAME") ?? "user";
+var rabbitPassword = Environment.GetEnvironmentVariable("RABBIT_PASSWORD") ?? "password";
+var rabbitExchange = Environment.GetEnvironmentVariable("RABBIT_EXCHANGE") ?? "ReportIn";
+
+var sender = new Sender(rabbitHost, rabbitUsername, rabbitPassword);
+
+sender.AddExcange(rabbitExchange);
+
+var rnd = new Random();
+
+while (true)
+{
+ StringBuilder sb = new();
+
+ var type = rnd.Next();
+ switch (type%2)
+ {
+ case 0:
+ {
+ sb.Append($"Был запрошен отчет о данных под номером {rnd.Next(1000)}");
+ break;
+ }
+ case 1:
+ {
+ sb.Append($"Был запрошен отчет об ошибках под номером {rnd.Next(1000)}");
+ break;
+ }
+ }
+
+ var text = sb.ToString();
+ Console.WriteLine($"Было опубликовано сообщение: {text}");
+ sender.PublishToExchange(rabbitExchange, text);
+
+ await Task.Delay(1000);
+}
+
diff --git a/dozorova_alena_lab_4/Publisher/Properties/launchSettings.json b/dozorova_alena_lab_4/Publisher/Properties/launchSettings.json
new file mode 100644
index 0000000..c756d2e
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/Properties/launchSettings.json
@@ -0,0 +1,10 @@
+{
+ "profiles": {
+ "Publisher": {
+ "commandName": "Project"
+ },
+ "Container (Dockerfile)": {
+ "commandName": "Docker"
+ }
+ }
+}
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Publisher/Publisher.csproj b/dozorova_alena_lab_4/Publisher/Publisher.csproj
new file mode 100644
index 0000000..a04999b
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/Publisher.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ Linux
+ .
+
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/Publisher/Publisher.csproj.user b/dozorova_alena_lab_4/Publisher/Publisher.csproj.user
new file mode 100644
index 0000000..3139c26
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/Publisher.csproj.user
@@ -0,0 +1,9 @@
+
+
+
+ Container (Dockerfile)
+
+
+ ProjectDebugger
+
+
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Publisher/Publisher.sln b/dozorova_alena_lab_4/Publisher/Publisher.sln
new file mode 100644
index 0000000..3eb68d4
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/Publisher.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35004.147
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Publisher", "Publisher.csproj", "{C23890FA-A4DD-4E5B-897F-37210C2F60CE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C23890FA-A4DD-4E5B-897F-37210C2F60CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C23890FA-A4DD-4E5B-897F-37210C2F60CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C23890FA-A4DD-4E5B-897F-37210C2F60CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C23890FA-A4DD-4E5B-897F-37210C2F60CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {3BB20EB3-DE49-46CE-8C7A-D956E3DE90BC}
+ EndGlobalSection
+EndGlobal
diff --git a/dozorova_alena_lab_4/Publisher/Sender.cs b/dozorova_alena_lab_4/Publisher/Sender.cs
new file mode 100644
index 0000000..c43eb72
--- /dev/null
+++ b/dozorova_alena_lab_4/Publisher/Sender.cs
@@ -0,0 +1,69 @@
+using RabbitMQ.Client;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Publisher
+{
+ public class Sender : IDisposable
+ {
+ private readonly ConnectionFactory _connectionFactory;
+ private readonly IConnection _connection;
+ private readonly IModel _channel;
+
+ public HashSet Exchanges { get; private set; } = new HashSet();
+
+ public Sender(string brockerHost, string brockerUsername, string brockerPassword)
+ {
+ _connectionFactory = new ConnectionFactory() { HostName = brockerHost, UserName = brockerUsername, Password = brockerPassword };
+ _connection = _connectionFactory.CreateConnection();
+ _channel = _connection.CreateModel();
+ }
+
+ public bool AddExcange(string exchange, string exchangeType = ExchangeType.Fanout)
+ {
+ try
+ {
+ _channel.ExchangeDeclare(exchange, exchangeType);
+ Exchanges.Add(exchange);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ return false;
+ }
+
+ public bool PublishToExchange(string exchange, string message)
+ {
+ try
+ {
+ if (!Exchanges.Contains(exchange))
+ return false;
+
+ var messageBody = Encoding.UTF8.GetBytes(message);
+ _channel.BasicPublish(exchange: exchange,
+ routingKey: string.Empty,
+ basicProperties: null,
+ body: messageBody);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ return false;
+ }
+
+ ~Sender() => Dispose();
+
+ public void Dispose()
+ {
+ _connection.Dispose();
+ _channel.Dispose();
+ }
+ }
+}
diff --git a/dozorova_alena_lab_4/README.md b/dozorova_alena_lab_4/README.md
new file mode 100644
index 0000000..ed18814
--- /dev/null
+++ b/dozorova_alena_lab_4/README.md
@@ -0,0 +1,39 @@
+# Лабораторная работа 4
+В рамках данной работы были реализованы несколько проектов, работающих с RabbitMQ.
+## tutorial
+Для каждого урока были созданы консольные проекты
+### "Hello World!"
+![Task 1](image-4.png)
+### Work Queues
+![Task 2](image-5.png)
+### Publish/Subscribe
+![Task 3](image-6.png)
+## Описание
+В качестве предметной области была выбрана система запросов отчета двух видов: отчета и ошибок.
+## Запуск
+Для запуска лабораторной работы необходимо иметь запущенный Docker на устройстве.
+Необходимо перейти в папку, где располагается данный файл. Далее открыть терминал и ввести команду:
+```
+docker compose up -d --build
+```
+Порты для RabbitMQ были 8081 (для UI) и 5672.
+## Анализ
+Первоначальный вариант запуска предполагает, что имеется всего 2 потребителя:
+ 1. Тратит на обработку сообщения 2-3 секунды
+ 2. Тратит на обработку сообщения крайне малое время
+Задержка при обработке понижает пропускную способность обработчика, что вызывает переполнение очереди. Это подтверждается скринами.
+
+![alt text](image.png)
+
+![alt text](image-1.png)
+
+Теперь запустим несколько обычных обработчиков. Очередь не переполнена постоянно, а периодически, соответственно обработчики вполне справляются с потоком сообщений и увеличение их количества позволит в принципе избавиться от переполнения
+
+![alt text](image-2.png)
+
+![alt text](image-3.png)
+
+## Видеодемонстрация
+Демонстрация: (https://drive.google.com/file/d/16gJMGbMKSFZ_I5gCzuDekpAqUrhbpFRA/view?usp=sharing) Стоит обратить внимание на то, что настройки docker compose файла не гарантируют верный порядок подъема контейнеров, из-за чего некоторые контейнеры пришлось перезапустить.
+
+
diff --git a/dozorova_alena_lab_4/Receive/Program.cs b/dozorova_alena_lab_4/Receive/Program.cs
new file mode 100644
index 0000000..ffe992b
--- /dev/null
+++ b/dozorova_alena_lab_4/Receive/Program.cs
@@ -0,0 +1,29 @@
+using System.Text;
+using RabbitMQ.Client;
+using RabbitMQ.Client.Events;
+
+var factory = new ConnectionFactory { HostName = "localhost" };
+using var connection = factory.CreateConnection();
+using var channel = connection.CreateModel();
+
+channel.QueueDeclare(queue: "hello",
+ durable: false,
+ exclusive: false,
+ autoDelete: false,
+ arguments: null);
+
+Console.WriteLine(" [*] Waiting for messages.");
+
+var consumer = new EventingBasicConsumer(channel);
+consumer.Received += (model, ea) =>
+{
+ var body = ea.Body.ToArray();
+ var message = Encoding.UTF8.GetString(body);
+ Console.WriteLine($" [x] Received {message}");
+};
+channel.BasicConsume(queue: "hello",
+ autoAck: true,
+ consumer: consumer);
+
+Console.WriteLine(" Press [enter] to exit.");
+Console.ReadLine();
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Receive/Receive.csproj b/dozorova_alena_lab_4/Receive/Receive.csproj
new file mode 100644
index 0000000..f72406b
--- /dev/null
+++ b/dozorova_alena_lab_4/Receive/Receive.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/ReceiveLogs/Program.cs b/dozorova_alena_lab_4/ReceiveLogs/Program.cs
new file mode 100644
index 0000000..f1a8612
--- /dev/null
+++ b/dozorova_alena_lab_4/ReceiveLogs/Program.cs
@@ -0,0 +1,31 @@
+using System.Text;
+using RabbitMQ.Client;
+using RabbitMQ.Client.Events;
+
+var factory = new ConnectionFactory { HostName = "localhost" };
+using var connection = factory.CreateConnection();
+using var channel = connection.CreateModel();
+
+channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
+
+// declare a server-named queue
+var queueName = channel.QueueDeclare().QueueName;
+channel.QueueBind(queue: queueName,
+ exchange: "logs",
+ routingKey: string.Empty);
+
+Console.WriteLine(" [*] Waiting for logs.");
+
+var consumer = new EventingBasicConsumer(channel);
+consumer.Received += (model, ea) =>
+{
+ byte[] body = ea.Body.ToArray();
+ var message = Encoding.UTF8.GetString(body);
+ Console.WriteLine($" [x] {message}");
+};
+channel.BasicConsume(queue: queueName,
+ autoAck: true,
+ consumer: consumer);
+
+Console.WriteLine(" Press [enter] to exit.");
+Console.ReadLine();
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/ReceiveLogs/ReceiveLogs.csproj b/dozorova_alena_lab_4/ReceiveLogs/ReceiveLogs.csproj
new file mode 100644
index 0000000..f72406b
--- /dev/null
+++ b/dozorova_alena_lab_4/ReceiveLogs/ReceiveLogs.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/Send/Program.cs b/dozorova_alena_lab_4/Send/Program.cs
new file mode 100644
index 0000000..4e0f5c2
--- /dev/null
+++ b/dozorova_alena_lab_4/Send/Program.cs
@@ -0,0 +1,24 @@
+using System.Text;
+using RabbitMQ.Client;
+
+var factory = new ConnectionFactory { HostName = "localhost" };
+using var connection = factory.CreateConnection();
+using var channel = connection.CreateModel();
+
+channel.QueueDeclare(queue: "hello",
+ durable: false,
+ exclusive: false,
+ autoDelete: false,
+ arguments: null);
+
+const string message = "Hello World!";
+var body = Encoding.UTF8.GetBytes(message);
+
+channel.BasicPublish(exchange: string.Empty,
+ routingKey: "hello",
+ basicProperties: null,
+ body: body);
+Console.WriteLine($" [x] Sent {message}");
+
+Console.WriteLine(" Press [enter] to exit.");
+Console.ReadLine();
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Send/Send.csproj b/dozorova_alena_lab_4/Send/Send.csproj
new file mode 100644
index 0000000..f72406b
--- /dev/null
+++ b/dozorova_alena_lab_4/Send/Send.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/Worker/Program.cs b/dozorova_alena_lab_4/Worker/Program.cs
new file mode 100644
index 0000000..d8b86be
--- /dev/null
+++ b/dozorova_alena_lab_4/Worker/Program.cs
@@ -0,0 +1,39 @@
+using System.Text;
+using RabbitMQ.Client;
+using RabbitMQ.Client.Events;
+
+var factory = new ConnectionFactory { HostName = "localhost" };
+using var connection = factory.CreateConnection();
+using var channel = connection.CreateModel();
+
+channel.QueueDeclare(queue: "task_queue",
+ durable: true,
+ exclusive: false,
+ autoDelete: false,
+ arguments: null);
+
+channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
+
+Console.WriteLine(" [*] Waiting for messages.");
+
+var consumer = new EventingBasicConsumer(channel);
+consumer.Received += (model, ea) =>
+{
+ byte[] body = ea.Body.ToArray();
+ var message = Encoding.UTF8.GetString(body);
+ Console.WriteLine($" [x] Received {message}");
+
+ int dots = message.Split('.').Length - 1;
+ Thread.Sleep(dots * 1000);
+
+ Console.WriteLine(" [x] Done");
+
+ // here channel could also be accessed as ((EventingBasicConsumer)sender).Model
+ channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
+};
+channel.BasicConsume(queue: "task_queue",
+ autoAck: false,
+ consumer: consumer);
+
+Console.WriteLine(" Press [enter] to exit.");
+Console.ReadLine();
\ No newline at end of file
diff --git a/dozorova_alena_lab_4/Worker/Worker.csproj b/dozorova_alena_lab_4/Worker/Worker.csproj
new file mode 100644
index 0000000..f72406b
--- /dev/null
+++ b/dozorova_alena_lab_4/Worker/Worker.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dozorova_alena_lab_4/docker-compose.yaml b/dozorova_alena_lab_4/docker-compose.yaml
new file mode 100644
index 0000000..5e13516
--- /dev/null
+++ b/dozorova_alena_lab_4/docker-compose.yaml
@@ -0,0 +1,59 @@
+services:
+ rabbit:
+ image: rabbitmq:3.10.7-management
+ restart: always
+ ports:
+ - 5672:5672
+ - 8081:15672
+ environment:
+ RABBITMQ_DEFAULT_USER: admin
+ RABBITMQ_DEFAULT_PASS: admin
+
+ publisher:
+ build: ./Publisher/
+ restart: always
+ depends_on:
+ - rabbit
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_USERNAME: admin
+ RABBIT_PASSWORD: admin
+ RABBIT_EXCHANGE: 'ReportIn'
+
+ concumer1:
+ build: ./ConsumerSimple/
+ restart: always
+ depends_on:
+ - rabbit
+ - publisher
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_USERNAME: admin
+ RABBIT_PASSWORD: admin
+ RABBIT_EXCHANGE: 'ReportIn'
+ RABBIT_QUEUE: 'First'
+
+ concumer2:
+ build: ./ConsumerSimple/
+ restart: always
+ depends_on:
+ - rabbit
+ - publisher
+ environment:
+ RABBIT_HOST: rabbit
+ RABBIT_USERNAME: admin
+ RABBIT_PASSWORD: admin
+ RABBIT_EXCHANGE: 'ReportIn'
+ RABBIT_QUEUE: 'Second'
+ # concumer2:
+ # build: ./ConsumerDelay/
+ # restart: always
+ # depends_on:
+ # - rabbit
+ # - publisher
+ # environment:
+ # RABBIT_HOST: rabbit
+ # RABBIT_USERNAME: admin
+ # RABBIT_PASSWORD: admin
+ # RABBIT_EXCHANGE: 'ReportIn'
+ # RABBIT_QUEUE: 'Second'
diff --git a/dozorova_alena_lab_4/image-1.png b/dozorova_alena_lab_4/image-1.png
new file mode 100644
index 0000000..ae1379f
Binary files /dev/null and b/dozorova_alena_lab_4/image-1.png differ
diff --git a/dozorova_alena_lab_4/image-2.png b/dozorova_alena_lab_4/image-2.png
new file mode 100644
index 0000000..6b459d5
Binary files /dev/null and b/dozorova_alena_lab_4/image-2.png differ
diff --git a/dozorova_alena_lab_4/image-3.png b/dozorova_alena_lab_4/image-3.png
new file mode 100644
index 0000000..cb4ffc7
Binary files /dev/null and b/dozorova_alena_lab_4/image-3.png differ
diff --git a/dozorova_alena_lab_4/image-4.png b/dozorova_alena_lab_4/image-4.png
new file mode 100644
index 0000000..09c1d5e
Binary files /dev/null and b/dozorova_alena_lab_4/image-4.png differ
diff --git a/dozorova_alena_lab_4/image-5.png b/dozorova_alena_lab_4/image-5.png
new file mode 100644
index 0000000..5a7333d
Binary files /dev/null and b/dozorova_alena_lab_4/image-5.png differ
diff --git a/dozorova_alena_lab_4/image-6.png b/dozorova_alena_lab_4/image-6.png
new file mode 100644
index 0000000..a2f8b70
Binary files /dev/null and b/dozorova_alena_lab_4/image-6.png differ
diff --git a/dozorova_alena_lab_4/image.png b/dozorova_alena_lab_4/image.png
new file mode 100644
index 0000000..afe250e
Binary files /dev/null and b/dozorova_alena_lab_4/image.png differ
diff --git a/dozorova_alena_lab_5/.gitignore b/dozorova_alena_lab_5/.gitignore
index 30c9ddf..0d65e88 100644
--- a/dozorova_alena_lab_5/.gitignore
+++ b/dozorova_alena_lab_5/.gitignore
@@ -10,3 +10,29 @@
/dozorova_alena_lab_5/ConsoleApp1/.vs
/dozorova_alena_lab_5/ConsoleApp1/bin
/dozorova_alena_lab_5/ConsoleApp1/obj
+/dozorova_alena_lab_3/PostService/.vs
+/dozorova_alena_lab_3/WorkerService/.vs
+/dozorova_alena_lab_4/Receive/bin
+/dozorova_alena_lab_4/Receive/obj
+/dozorova_alena_lab_4/Send/bin
+/dozorova_alena_lab_4/Send/obj
+/dozorova_alena_lab_4/EmitLog/.vs
+/dozorova_alena_lab_4/EmitLog/obj
+/dozorova_alena_lab_4/NewTask/.vs
+/dozorova_alena_lab_4/NewTask/bin
+/dozorova_alena_lab_4/NewTask/obj
+/dozorova_alena_lab_4/ReceiveLogs/obj
+/dozorova_alena_lab_4/Worker/.vs
+/dozorova_alena_lab_4/Worker/bin
+/dozorova_alena_lab_4/Worker/obj
+/dozorova_alena_lab_4/EmitLog/bin
+/dozorova_alena_lab_4/ReceiveLogs/.vs
+/dozorova_alena_lab_4/ReceiveLogs/bin
+/dozorova_alena_lab_4/ConsumerDelay/.vs
+/dozorova_alena_lab_4/ConsumerDelay/obj
+/dozorova_alena_lab_4/ConsumerDelay/Properties
+/dozorova_alena_lab_4/ConsumerSimple/.vs
+/dozorova_alena_lab_4/ConsumerSimple/obj
+/dozorova_alena_lab_4/Publisher/.vs
+/dozorova_alena_lab_4/Publisher/bin
+/dozorova_alena_lab_4/Publisher/objs
diff --git a/kalyshev_yan_lab_2/.gitignore b/kalyshev_yan_lab_2/.gitignore
new file mode 100644
index 0000000..e1c443e
--- /dev/null
+++ b/kalyshev_yan_lab_2/.gitignore
@@ -0,0 +1,5 @@
+data/
+result/
+result_first/
+result_second/
+datagen.py
diff --git a/kalyshev_yan_lab_2/FirstProgram/Dockerfile b/kalyshev_yan_lab_2/FirstProgram/Dockerfile
new file mode 100644
index 0000000..79fedcb
--- /dev/null
+++ b/kalyshev_yan_lab_2/FirstProgram/Dockerfile
@@ -0,0 +1,16 @@
+#Берем базовый образ python
+FROM python:3.12
+
+#Устанавливаем рабочую директорию
+WORKDIR /app
+
+#Копирум код в рабочую директорию
+COPY main.py .
+
+#Задаем /var/data как монтируемый
+VOLUME ["/var/data"]
+#Задаем /var/result как монтируемый
+VOLUME ["/var/result"]
+
+#Задаем команду для выполнения программы
+CMD ["python", "main.py"]
diff --git a/kalyshev_yan_lab_2/FirstProgram/main.py b/kalyshev_yan_lab_2/FirstProgram/main.py
new file mode 100644
index 0000000..8f9edf1
--- /dev/null
+++ b/kalyshev_yan_lab_2/FirstProgram/main.py
@@ -0,0 +1,79 @@
+import os
+import random
+
+# Установите полный путь к каталогу, в котором нужно искать самый большой файл.
+CATALOG_PATH = "/var/data"
+
+# Полный путь до файла результата.
+RESULT_FILE = "/var/result/data.txt"
+
+
+def find_largest_file(directory):
+ """Ищет самый большой по объему файл в заданном каталоге и его подкаталогах."""
+
+ largest_file = None
+ max_size = 0
+
+ for root, _, files in os.walk(directory):
+ for file in files:
+ # Полный путь к текущему файлу.
+ filepath = os.path.join(root, file)
+
+ try:
+ file_size = os.stat(filepath).st_size
+
+ if file_size > max_size:
+ max_size = file_size
+ largest_file = (filepath, file_size)
+
+ except OSError as e:
+ print(f"Ошибка при открытии файла '{filepath}': {e}")
+
+ return largest_file
+
+
+def copy_file(src, dst):
+ """Копирует содержимое файла src в файл dst."""
+
+ try:
+ with open(dst, "wb") as f_dst, open(src, "rb") as f_src:
+ while chunk := f_src.read(4096):
+ f_dst.write(chunk)
+
+ print(f"Файл '{src}' успешно скопирован в '{dst}'.")
+
+ except Exception as e:
+ print(f"Ошибка при копировании файла '{src}': {e}")
+
+
+def main():
+ largest_file_path = find_largest_file(CATALOG_PATH)
+
+ if largest_file_path:
+ src_path, _ = largest_file_path
+ dst_path = RESULT_FILE
+
+ copy_file(src_path, dst_path)
+
+ else:
+ print("Нет файлов в каталоге.")
+
+
+def generate_random_numbers(filename, count):
+ """Функция генерирует случайные числа и записывает их в файл."""
+
+ with open(filename, "w") as f:
+ for _ in range(count):
+ num = random.randint(0, 1000)
+ f.write(str(num) + "\n")
+
+ print(f"Случайные числа успешно записаны в '{filename}'.")
+
+
+if __name__ == "__main__":
+ generate_random_numbers("/var/data/data1.txt", 50)
+ generate_random_numbers("/var/data/data2.txt", 75)
+ generate_random_numbers("/var/data/data3.txt", 25)
+ print("Генерация файлов завершена.")
+
+ main()
diff --git a/kalyshev_yan_lab_2/README.md b/kalyshev_yan_lab_2/README.md
new file mode 100644
index 0000000..8114ef3
--- /dev/null
+++ b/kalyshev_yan_lab_2/README.md
@@ -0,0 +1,74 @@
+# Калышев Ян ПИбд-42
+
+## Описание
+
+Этот проект предоставляет 2 контейнера с простыми python-скриптами такими, что результат первого является исходными данными для второго.
+
+## 1. Варианты
+
+Для первой программы был взят вариант:
+**0**. Ищет в каталоге /var/data самый большой по объёму файл и перекладывает его в /var/result/data.txt.
+
+Для второй программы был взят вариант:
+**2**. Ищет наименьшее число из файла /var/data/data.txt и сохраняет его третью степень в /var/result/result.txt.
+
+## 2. Структура Dockerfile
+
+Оба Dockerfile почти одинаковые:
+
+```Dockerfile
+#Берем базовый образ python
+FROM python:3.12
+
+#Устанавливаем рабочую директорию
+WORKDIR /app
+
+#Копирум код в рабочую директорию
+COPY main.py .
+
+#Задаем /var/data как монтируемый
+VOLUME ["/var/data"]
+#Задаем /var/result как монтируемый
+VOLUME ["/var/result"]
+
+#Задаем команду для выполнения программы
+CMD ["python", "main.py"]
+```
+
+## 3. Docker Compose
+
+`docker-compose.yml`:
+
+```yaml
+services:
+ #Первый скрипт
+ first:
+ #Указание директории для сборки первого скрипта
+ build: ./FirstProgram/
+ #Монтирование 2 каталогов из хост системы
+ volumes:
+ - ./data:/var/data
+ - ./result_first:/var/result
+
+ #Второй скрипт
+ second:
+ #Указание директории для сборки второго скрипта
+ build: ./SecondProgram/
+ #Задание очередности запуска с помощью depends_on
+ depends_on:
+ - first
+ #Монтирование 2 каталогов из хост системы
+ volumes:
+ - ./result_first:/var/data
+ - ./result_second:/var/result
+```
+
+## 4. Запуск
+
+Для запуска использовать команду `docker compose up --build`
+Предварительно нужно создать папку `data`, в которой создать файлы, где каждая строка - это число.
+Результат первого скрипта будет в папке `result_first`, результат второго скрипта будет в папке `result_second`.
+
+## 7. Ссылка на видео
+
+[Видео-отчёт Калышев Ян ПИбд-42](https://zyzf.space/s/65HRyTTXAzxpwBF)
diff --git a/kalyshev_yan_lab_2/SecondProgram/Dockerfile b/kalyshev_yan_lab_2/SecondProgram/Dockerfile
new file mode 100644
index 0000000..79fedcb
--- /dev/null
+++ b/kalyshev_yan_lab_2/SecondProgram/Dockerfile
@@ -0,0 +1,16 @@
+#Берем базовый образ python
+FROM python:3.12
+
+#Устанавливаем рабочую директорию
+WORKDIR /app
+
+#Копирум код в рабочую директорию
+COPY main.py .
+
+#Задаем /var/data как монтируемый
+VOLUME ["/var/data"]
+#Задаем /var/result как монтируемый
+VOLUME ["/var/result"]
+
+#Задаем команду для выполнения программы
+CMD ["python", "main.py"]
diff --git a/kalyshev_yan_lab_2/SecondProgram/main.py b/kalyshev_yan_lab_2/SecondProgram/main.py
new file mode 100644
index 0000000..607ae04
--- /dev/null
+++ b/kalyshev_yan_lab_2/SecondProgram/main.py
@@ -0,0 +1,60 @@
+# Установите полный путь к файлу, из которого нужно читать числа.
+DATA_FILE = "/var/data/data.txt"
+
+# Полный путь до файла результата.
+RESULT_FILE = "/var/result/result.txt"
+
+
+def find_smallest_number(data_file):
+ """Ищет наименьшее число в заданном файле."""
+
+ try:
+ with open(data_file, "r") as f:
+ numbers = [int(line.strip()) for line in f.readlines()]
+
+ smallest_num = min(numbers)
+ return smallest_num
+
+ except ValueError as e:
+ print(f"Ошибка при преобразовании строк в числа: {e}")
+
+ except Exception as e:
+ print(f"Ошибка чтения файла '{data_file}': {e}")
+
+ return None
+
+
+def cube_number(num):
+ """Возвращает куб заданного числа."""
+
+ return num**3
+
+
+def write_result(result_file, result):
+ """Записывает результат в файл."""
+
+ try:
+ with open(result_file, "w") as f:
+ f.write(str(result))
+
+ print(f"Результат '{result}' успешно записан в '{result_file}'.")
+
+ except Exception as e:
+ print(f"Ошибка записи результата в файл '{result_file}': {e}")
+
+
+def main():
+ smallest_num = find_smallest_number(DATA_FILE)
+
+ if smallest_num is not None:
+ result = cube_number(smallest_num)
+
+ write_result(RESULT_FILE, result)
+ print(result)
+
+ else:
+ print("Нет чисел в файле.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/kalyshev_yan_lab_2/docker-compose.yml b/kalyshev_yan_lab_2/docker-compose.yml
new file mode 100644
index 0000000..76eb9f7
--- /dev/null
+++ b/kalyshev_yan_lab_2/docker-compose.yml
@@ -0,0 +1,21 @@
+services:
+ #Первый скрипт
+ first:
+ #Указание директории для сборки первого скрипта
+ build: ./FirstProgram/
+ #Монтирование 2 каталогов из хост системы
+ volumes:
+ - ./data:/var/data
+ - ./result_first:/var/result
+
+ #Второй скрипт
+ second:
+ #Указание директории для сборки второго скрипта
+ build: ./SecondProgram/
+ #Задание очередности запуска с помощью depends_on
+ depends_on:
+ - first
+ #Монтирование 2 каталогов из хост системы
+ volumes:
+ - ./result_first:/var/data
+ - ./result_second:/var/result
diff --git a/kuzarin_maxim_lab_5/.gitignore b/kuzarin_maxim_lab_5/.gitignore
new file mode 100644
index 0000000..104b544
--- /dev/null
+++ b/kuzarin_maxim_lab_5/.gitignore
@@ -0,0 +1,484 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from `dotnet new gitignore`
+
+# dotenv files
+.env
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# Tye
+.tye/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+.idea
+
+##
+## Visual studio for Mac
+##
+
+
+# globs
+Makefile.in
+*.userprefs
+*.usertasks
+config.make
+config.status
+aclocal.m4
+install-sh
+autom4te.cache/
+*.tar.gz
+tarballs/
+test-results/
+
+# Mac bundle stuff
+*.dmg
+*.app
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# Vim temporary swap files
+*.swp
diff --git a/kuzarin_maxim_lab_5/Images/Resouts.png b/kuzarin_maxim_lab_5/Images/Resouts.png
new file mode 100644
index 0000000..55ce812
Binary files /dev/null and b/kuzarin_maxim_lab_5/Images/Resouts.png differ
diff --git a/kuzarin_maxim_lab_5/MatrixMultiplication.sln b/kuzarin_maxim_lab_5/MatrixMultiplication.sln
new file mode 100644
index 0000000..7b9b107
--- /dev/null
+++ b/kuzarin_maxim_lab_5/MatrixMultiplication.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.34916.146
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixMultiplication", "MatrixMultiplication\MatrixMultiplication.csproj", "{EF2DB216-9BCD-4FEE-B9C8-4262A5B7CC30}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EF2DB216-9BCD-4FEE-B9C8-4262A5B7CC30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EF2DB216-9BCD-4FEE-B9C8-4262A5B7CC30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EF2DB216-9BCD-4FEE-B9C8-4262A5B7CC30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EF2DB216-9BCD-4FEE-B9C8-4262A5B7CC30}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {619485C2-FE35-496B-9E25-4F5465D0C1A1}
+ EndGlobalSection
+EndGlobal
diff --git a/kuzarin_maxim_lab_5/MatrixMultiplication/MatrixMultiplication.csproj b/kuzarin_maxim_lab_5/MatrixMultiplication/MatrixMultiplication.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/kuzarin_maxim_lab_5/MatrixMultiplication/MatrixMultiplication.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/kuzarin_maxim_lab_5/MatrixMultiplication/Program.cs b/kuzarin_maxim_lab_5/MatrixMultiplication/Program.cs
new file mode 100644
index 0000000..2a5dc76
--- /dev/null
+++ b/kuzarin_maxim_lab_5/MatrixMultiplication/Program.cs
@@ -0,0 +1,117 @@
+
+using System.Diagnostics;
+internal class Program
+{
+ private static string[] _resTableColumnsNames = new string[] { "m*m", "1 t", "2 t", "3 t", "4 t", "5 t", "6 t", "7 t", "8 t" };
+
+ private static void Main(string[] args)
+ {
+ Console.WriteLine(string.Join("\t", _resTableColumnsNames));
+
+ for (int i = 10; i < 10000; i *= 2)
+ {
+ var a = CreateMatrix(i, i);
+ var b = CreateMatrix(i, i);
+
+ List times = new() { i };
+
+ for (int j = 1; j <= 8; j++)
+ {
+ var sw = new Stopwatch();
+ sw.Start();
+
+ MultiplyMatrix(a, b, j);
+
+ sw.Stop();
+ times.Add(sw.ElapsedMilliseconds);
+ }
+ Console.WriteLine(string.Join("\t", times));
+ }
+ }
+
+ ///
+ /// Создаём матрицу случайных элементов
+ ///
+ ///
+ ///
+ ///
+ private static int[,] CreateMatrix(int x, int y)
+ {
+ var rnd = new Random();
+
+ var res = new int[y, x];
+
+ for (int i = 0; i < y; i++)
+ {
+ for (int j = 0; j < x; j++)
+ {
+ res[i, j] = rnd.Next(0, 100);
+ }
+ }
+ return res;
+ }
+
+ ///
+ /// Вывести матрицу. Использовался при отладке
+ ///
+ ///
+ private static void PrintMatrix(int[,] mx)
+ {
+ for (int i = 0; i < mx.GetLength(0); i++)
+ {
+ for (int j = 0; j < mx.GetLength(1); j++)
+ {
+ Console.Write($"{mx[i, j].ToString("000")}\t");
+ }
+ Console.WriteLine();
+ }
+ }
+
+ ///
+ /// Непосредственно умножение матриц
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static int[,] MultiplyMatrix(int[,] a, int[,] b, int maxTask)
+ {
+ int[,] res = new int[a.GetLength(0), b.GetLength(1)];
+
+ var semaphore = new SemaphoreSlim(maxTask, maxTask);
+
+ for (int i = 0; i < a.GetLength(0); i++)
+ {
+ for (int j = 0; j < b.GetLength(1); j++)
+ {
+ semaphore.Wait();
+ int ci = i;
+ int cj = j;
+ _ = Task.Run(() =>
+ {
+ try
+ {
+ res[ci, cj] = CalculateElement(a, b, ci, cj);
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ });
+ }
+ }
+ semaphore.Wait(maxTask);
+ return res;
+ }
+
+ ///
+ /// Вычисление значение одного элемента
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static int CalculateElement(int[,] a, int[,] b, int i, int j)
+ => Enumerable.Range(0, a.GetLength(1)).Sum(k => a[i, k] * b[k, j]);
+}
\ No newline at end of file
diff --git a/kuzarin_maxim_lab_5/README.md b/kuzarin_maxim_lab_5/README.md
new file mode 100644
index 0000000..0fb394a
--- /dev/null
+++ b/kuzarin_maxim_lab_5/README.md
@@ -0,0 +1,20 @@
+# Лабораторная работа 5
+Данная работа посвящена параллельному умножению больших матриц (чтобы это был побыстрее)
+## Описание
+Основной принцип умножения матриц: строки умножаются на столбцы, таким образом получаются элементы. И так как значения в строках/столбцах не меняется по ходу алгоритма, его достаточно легко можно распаралелить.
+
+## Запуск
+Приложение представлет собой консольную программу на C#, которую можно скомпилировать и затем запустит exe файл. В результате в окне консоли появится таблица сравнения времени умножения 2-х квадратных матриц (размер указан в первой колонке) с использованием разного числа потоков(от 1 до 8). Чем больше размер, тем дольше будет идти расчёт.
+## Результаты
+Результаты одного из запусков программы представлены ниже.
+
+![Resout](Images/Resouts.png)
+
+Как можно заметить, на небольших размерах распаралеливание не приносит никакого выигрыша, а иногда даже удлиняет время работы. Это связана с тем, что работы с потоками (запуск, получение результата и т. п.) - требует дополнительного времени, а из-за малого числа операций в целом, получаем не прирост производительности, а её падение.
+Противоположно обстоят дела в случае с большими матрицами. Так как там расчётов значительно больше, распаралеливание начинает значительно ускорять вычисление результата. Причём, часто можно видеть, что, например, увеличения числа потоков с 1 до 2 (в 2 раза) сокращает время в 2 раза. Но чем больше потоков, тем прирост меньше (так как вновь вступают в силу факторы, описанные ранее). И прирост производительности пусть и есть, но он очень небольшой.
+
+## Видеодемонстрация
+Был записан видеоролик, демонстрирующий процесс запуска и работы системы. Он расположен по [адресу](https://drive.google.com/file/d/1dhA3JUAhhpDUh32xVW7jMuW1BKDX02eV/view?usp=sharing)
+
+
+
diff --git a/yakovleva_yulia_lab_3/Administrator/.config/dotnet-tools.json b/yakovleva_yulia_lab_3/Administrator/.config/dotnet-tools.json
new file mode 100644
index 0000000..d7000af
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-ef": {
+ "version": "8.0.8",
+ "commands": [
+ "dotnet-ef"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/yakovleva_yulia_lab_3/Administrator/.dockerignore b/yakovleva_yulia_lab_3/Administrator/.dockerignore
new file mode 100644
index 0000000..4d72b4f
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/.dockerignore
@@ -0,0 +1,30 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
+!**/.gitignore
+!.git/HEAD
+!.git/config
+!.git/packed-refs
+!.git/refs/heads/**
\ No newline at end of file
diff --git a/yakovleva_yulia_lab_3/Administrator/.gitignore b/yakovleva_yulia_lab_3/Administrator/.gitignore
new file mode 100644
index 0000000..5e57f18
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/.gitignore
@@ -0,0 +1,484 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from `dotnet new gitignore`
+
+# dotenv files
+.env
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# Tye
+.tye/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+.idea
+
+##
+## Visual studio for Mac
+##
+
+
+# globs
+Makefile.in
+*.userprefs
+*.usertasks
+config.make
+config.status
+aclocal.m4
+install-sh
+autom4te.cache/
+*.tar.gz
+tarballs/
+test-results/
+
+# Mac bundle stuff
+*.dmg
+*.app
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# Vim temporary swap files
+*.swp
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator.sln b/yakovleva_yulia_lab_3/Administrator/Administrator.sln
new file mode 100644
index 0000000..4bdb397
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34728.123
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Administrator", "Administrator\Administrator.csproj", "{45DF535F-4F9E-4A5C-9D60-4B0709863ED8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {45DF535F-4F9E-4A5C-9D60-4B0709863ED8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45DF535F-4F9E-4A5C-9D60-4B0709863ED8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45DF535F-4F9E-4A5C-9D60-4B0709863ED8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45DF535F-4F9E-4A5C-9D60-4B0709863ED8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {211037E3-7DB9-4964-B9B8-211487849EED}
+ EndGlobalSection
+EndGlobal
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/Administrator.csproj b/yakovleva_yulia_lab_3/Administrator/Administrator/Administrator.csproj
new file mode 100644
index 0000000..3583898
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/Administrator.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net8.0
+ enable
+ enable
+ b3476a56-c45e-4a63-be32-5987c93f46b1
+ Linux
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/Administrator.http b/yakovleva_yulia_lab_3/Administrator/Administrator/Administrator.http
new file mode 100644
index 0000000..6780d1b
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/Administrator.http
@@ -0,0 +1,6 @@
+@Administrator_HostAddress = http://localhost:5015
+
+GET {{Administrator_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/Controllers/AdminController.cs b/yakovleva_yulia_lab_3/Administrator/Administrator/Controllers/AdminController.cs
new file mode 100644
index 0000000..1357898
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/Controllers/AdminController.cs
@@ -0,0 +1,126 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Administrator.DataBase;
+using Administrator.DataBase.DBModels;
+
+namespace Administrator.Controllers
+{
+ [ApiController]
+ [Route("Administrators/")]
+ public class AdminController : ControllerBase
+ {
+ private readonly AdminDataBaseContext _context;
+ private readonly ILogger _logger;
+ private readonly IHttpClientFactory _clientFactory;
+
+ public AdminController(AdminDataBaseContext context, ILogger logger, IHttpClientFactory clientFactory)
+ {
+ _context = context;
+ _logger = logger;
+ _clientFactory = clientFactory;
+ }
+
+ //
+ [HttpPost]
+ public async Task> CreateAdministrator(Admin administrator)
+ {
+ if (!await ClientExists(administrator.ClientId))
+ {
+ return BadRequest(" .");
+ }
+
+ _context.Administrators.Add(administrator);
+ await _context.SaveChangesAsync();
+
+ return CreatedAtAction(nameof(GetAdministratorById), new { id = administrator.Id }, administrator);
+ }
+
+ //
+ [HttpPut("{id}")]
+ public async Task UpdateAdministrator(int id, Admin updatedAdministrator)
+ {
+ if (!await ClientExists(updatedAdministrator.ClientId))
+ {
+ return BadRequest(" .");
+ }
+
+ if (id != updatedAdministrator.Id)
+ {
+ return BadRequest();
+ }
+
+ _context.Entry(updatedAdministrator).State = EntityState.Modified;
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!AdminExists(id))
+ {
+ return NotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return NoContent();
+ }
+
+ //
+ [HttpDelete("{id}")]
+ public async Task DeleteAdministrator(int id)
+ {
+ var administrator = await _context.Administrators.FindAsync(id);
+ if (administrator == null)
+ {
+ return NotFound(" ");
+ }
+
+ _context.Administrators.Remove(administrator);
+ await _context.SaveChangesAsync();
+
+ return NoContent();
+ }
+
+ //
+ [HttpGet]
+ public async Task>> GetAllAdministrators()
+ {
+ return await _context.Administrators.ToListAsync();
+ }
+
+ // ID
+ [HttpGet("{id}")]
+ public async Task> GetAdministratorById(int id)
+ {
+ var administrator = await _context.Administrators.FindAsync(id);
+
+ if (administrator == null)
+ {
+ return NotFound(" ");
+ }
+
+ return administrator;
+ }
+
+ private bool AdminExists(int id)
+ {
+ return _context.Administrators.Any(e => e.Id == id);
+ }
+
+ private async Task ClientExists(int buyerId)
+ {
+ var client = _clientFactory.CreateClient("BuyerService");
+ var response = await client.GetAsync($"Buyers/{buyerId}");
+ return response.IsSuccessStatusCode;
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/DataBase/AdminDataBaseContext.cs b/yakovleva_yulia_lab_3/Administrator/Administrator/DataBase/AdminDataBaseContext.cs
new file mode 100644
index 0000000..b66251b
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/DataBase/AdminDataBaseContext.cs
@@ -0,0 +1,20 @@
+using Administrator.DataBase.DBModels;
+using Microsoft.EntityFrameworkCore;
+
+namespace Administrator.DataBase
+{
+ public class AdminDataBaseContext : DbContext
+ {
+ public AdminDataBaseContext(DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ public DbSet Administrators { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity().ToTable("Administrators");
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/DataBase/DBModels/Admin.cs b/yakovleva_yulia_lab_3/Administrator/Administrator/DataBase/DBModels/Admin.cs
new file mode 100644
index 0000000..4879311
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/DataBase/DBModels/Admin.cs
@@ -0,0 +1,21 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Administrator.DataBase.DBModels
+{
+ public class Admin
+ {
+ [Key]
+ public int Id { get; set; }
+
+ [Required]
+ [StringLength(50)]
+ public string FirstName { get; set; }
+
+
+ [StringLength(50)]
+ public string SecondName { get; set; }
+
+ [Required]
+ public int ClientId { get; set; }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/Dockerfile b/yakovleva_yulia_lab_3/Administrator/Administrator/Dockerfile
new file mode 100644
index 0000000..a9d7d88
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/Dockerfile
@@ -0,0 +1,25 @@
+#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
+USER app
+WORKDIR /app
+EXPOSE 8080
+EXPOSE 8081
+
+FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["Administrator/Administrator.csproj", "Administrator/"]
+RUN dotnet restore "./Administrator/Administrator.csproj"
+COPY . .
+WORKDIR "/src/Administrator"
+RUN dotnet build "./Administrator.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "./Administrator.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "Administrator.dll"]
\ No newline at end of file
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/Program.cs b/yakovleva_yulia_lab_3/Administrator/Administrator/Program.cs
new file mode 100644
index 0000000..56b8d8b
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/Program.cs
@@ -0,0 +1,10 @@
+var host = CreateHostBuilder(args).Build();
+
+host.Run();
+
+static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ });
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/Properties/launchSettings.json b/yakovleva_yulia_lab_3/Administrator/Administrator/Properties/launchSettings.json
new file mode 100644
index 0000000..78fbb4e
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/Properties/launchSettings.json
@@ -0,0 +1,42 @@
+{
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true,
+ "applicationUrl": "http://localhost:5015"
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Container (Dockerfile)": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "ASPNETCORE_URLS": "http://+:80"
+ },
+ "publishAllPorts": true,
+ "useSSL": false
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:60492",
+ "sslPort": 0
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/Startup.cs b/yakovleva_yulia_lab_3/Administrator/Administrator/Startup.cs
new file mode 100644
index 0000000..adec894
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/Startup.cs
@@ -0,0 +1,55 @@
+using Microsoft.EntityFrameworkCore;
+using Administrator.DataBase;
+
+public class Startup
+{
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddControllers();
+
+ services.AddDbContext(options =>
+ options.UseNpgsql(Configuration.GetConnectionString("AdminDatabase")));
+
+ services.AddHttpClient("BuyerService", client =>
+ {
+ client.BaseAddress = new Uri("http://buyer-service:8080/");
+ });
+
+ services.AddSwaggerGen();
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceScopeFactory serviceScopeFactory)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseHttpsRedirection();
+
+ app.UseRouting();
+
+ app.UseAuthorization();
+
+ using (var scope = serviceScopeFactory.CreateScope())
+ {
+ var context = scope.ServiceProvider.GetRequiredService();
+ context.Database.Migrate();
+ }
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/appsettings.Development.json b/yakovleva_yulia_lab_3/Administrator/Administrator/appsettings.Development.json
new file mode 100644
index 0000000..ff66ba6
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Administrator/Administrator/appsettings.json b/yakovleva_yulia_lab_3/Administrator/Administrator/appsettings.json
new file mode 100644
index 0000000..cf4c47d
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Administrator/Administrator/appsettings.json
@@ -0,0 +1,12 @@
+{
+ "ConnectionStrings": {
+ "AdminDatabase": "Host=postgresdb;Database=administrator;Username=postgres;Password=123"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/yakovleva_yulia_lab_3/Buyer/.dockerignore b/yakovleva_yulia_lab_3/Buyer/.dockerignore
new file mode 100644
index 0000000..4d72b4f
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/.dockerignore
@@ -0,0 +1,30 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
+!**/.gitignore
+!.git/HEAD
+!.git/config
+!.git/packed-refs
+!.git/refs/heads/**
\ No newline at end of file
diff --git a/yakovleva_yulia_lab_3/Buyer/.gitignore b/yakovleva_yulia_lab_3/Buyer/.gitignore
new file mode 100644
index 0000000..5e57f18
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/.gitignore
@@ -0,0 +1,484 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from `dotnet new gitignore`
+
+# dotenv files
+.env
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# Tye
+.tye/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+.idea
+
+##
+## Visual studio for Mac
+##
+
+
+# globs
+Makefile.in
+*.userprefs
+*.usertasks
+config.make
+config.status
+aclocal.m4
+install-sh
+autom4te.cache/
+*.tar.gz
+tarballs/
+test-results/
+
+# Mac bundle stuff
+*.dmg
+*.app
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# Vim temporary swap files
+*.swp
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer.sln b/yakovleva_yulia_lab_3/Buyer/Buyer.sln
new file mode 100644
index 0000000..73c139c
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34728.123
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Buyer", "Buyer\Buyer.csproj", "{3845B5A1-0A3C-427B-9659-67590EEDB4B6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3845B5A1-0A3C-427B-9659-67590EEDB4B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3845B5A1-0A3C-427B-9659-67590EEDB4B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3845B5A1-0A3C-427B-9659-67590EEDB4B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3845B5A1-0A3C-427B-9659-67590EEDB4B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {2074E7E7-D084-4F69-AED8-8DD2830D2A68}
+ EndGlobalSection
+EndGlobal
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer - Backup.csproj b/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer - Backup.csproj
new file mode 100644
index 0000000..3583898
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer - Backup.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net8.0
+ enable
+ enable
+ b3476a56-c45e-4a63-be32-5987c93f46b1
+ Linux
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer.csproj b/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer.csproj
new file mode 100644
index 0000000..7eb035b
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net8.0
+ enable
+ enable
+ f9482e07-2725-46f1-9b04-c34d26c4f674
+ Linux
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer.http b/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer.http
new file mode 100644
index 0000000..6780d1b
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Buyer.http
@@ -0,0 +1,6 @@
+@Administrator_HostAddress = http://localhost:5015
+
+GET {{Administrator_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Controllers/BuyerController.cs b/yakovleva_yulia_lab_3/Buyer/Buyer/Controllers/BuyerController.cs
new file mode 100644
index 0000000..9f70376
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Controllers/BuyerController.cs
@@ -0,0 +1,105 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Buyer.DataBase;
+using Buyer.DataBase.DBModels;
+
+namespace Buyer.Controllers
+{
+ [ApiController]
+ [Route("Buyers/")]
+ public class BuyerController : Controller
+ {
+ private readonly BuyerDataBaseContext _dbContext;
+
+ public BuyerController(BuyerDataBaseContext dbContext)
+ {
+ _dbContext = dbContext;
+ }
+
+ //
+ [HttpGet]
+ public async Task>> GetAllBuyers()
+ {
+ return await _dbContext.Buyers.ToListAsync();
+ }
+
+ // ID
+ [HttpGet("{id}")]
+ public async Task> GetBuyer(int id)
+ {
+ var Buyer = await _dbContext.Buyers.FindAsync(id);
+
+ if (Buyer == null)
+ {
+ return NotFound();
+ }
+
+ return Buyer;
+ }
+
+ //
+ [HttpPost]
+ public async Task> CreateBuyer(Buyers Buyer)
+ {
+ _dbContext.Buyers.Add(Buyer);
+ await _dbContext.SaveChangesAsync();
+
+ return CreatedAtAction(nameof(GetBuyer), new { id = Buyer.Id }, Buyer);
+ }
+
+ //
+ [HttpPut("{id}")]
+ public async Task UpdateBuyer(int id, Buyers Buyer)
+ {
+ if (id != Buyer.Id)
+ {
+ return BadRequest();
+ }
+
+ _dbContext.Entry(Buyer).State = EntityState.Modified;
+
+ try
+ {
+ await _dbContext.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!BuyerExists(id))
+ {
+ return NotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return NoContent();
+ }
+
+ //
+ [HttpDelete("{id}")]
+ public async Task DeleteBuyer(int id)
+ {
+ var Buyer = await _dbContext.Buyers.FindAsync(id);
+ if (Buyer == null)
+ {
+ return NotFound();
+ }
+
+ _dbContext.Buyers.Remove(Buyer);
+ await _dbContext.SaveChangesAsync();
+
+ return NoContent();
+ }
+
+ private bool BuyerExists(int id)
+ {
+ return _dbContext.Buyers.Any(e => e.Id == id);
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/DataBase/BuyerDataBaseContext.cs b/yakovleva_yulia_lab_3/Buyer/Buyer/DataBase/BuyerDataBaseContext.cs
new file mode 100644
index 0000000..d645634
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/DataBase/BuyerDataBaseContext.cs
@@ -0,0 +1,20 @@
+using Buyer.DataBase.DBModels;
+using Microsoft.EntityFrameworkCore;
+
+namespace Buyer.DataBase
+{
+ public class BuyerDataBaseContext : DbContext
+ {
+ public BuyerDataBaseContext(DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ public DbSet Buyers { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity().ToTable("Buyers");
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/DataBase/DBModels/Buyers.cs b/yakovleva_yulia_lab_3/Buyer/Buyer/DataBase/DBModels/Buyers.cs
new file mode 100644
index 0000000..b7852c6
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/DataBase/DBModels/Buyers.cs
@@ -0,0 +1,18 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Buyer.DataBase.DBModels
+{
+ public class Buyers
+ {
+ [Key]
+ public int Id { get; set; }
+
+ [Required]
+ [StringLength(50)]
+ public string FirstName { get; set; }
+
+
+ [StringLength(50)]
+ public string SecondName { get; set; }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Dockerfile b/yakovleva_yulia_lab_3/Buyer/Buyer/Dockerfile
new file mode 100644
index 0000000..045b57a
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Dockerfile
@@ -0,0 +1,27 @@
+#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
+USER app
+WORKDIR /app
+EXPOSE 8080
+EXPOSE 8081
+
+FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["Buyer/Buyer.csproj", "Buyer/"]
+RUN dotnet restore "./Buyer/Buyer.csproj"
+COPY . .
+WORKDIR "/src/Buyer"
+RUN dotnet build "./Buyer.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "./Buyer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "Buyer.dll"]
+
+CMD dotnet ef database update --no-build && dotnet BuyerService.dll
\ No newline at end of file
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Program.cs b/yakovleva_yulia_lab_3/Buyer/Buyer/Program.cs
new file mode 100644
index 0000000..56b8d8b
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Program.cs
@@ -0,0 +1,10 @@
+var host = CreateHostBuilder(args).Build();
+
+host.Run();
+
+static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ });
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Properties/launchSettings.json b/yakovleva_yulia_lab_3/Buyer/Buyer/Properties/launchSettings.json
new file mode 100644
index 0000000..78fbb4e
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Properties/launchSettings.json
@@ -0,0 +1,42 @@
+{
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true,
+ "applicationUrl": "http://localhost:5015"
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Container (Dockerfile)": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "ASPNETCORE_URLS": "http://+:80"
+ },
+ "publishAllPorts": true,
+ "useSSL": false
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:60492",
+ "sslPort": 0
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/Startup.cs b/yakovleva_yulia_lab_3/Buyer/Buyer/Startup.cs
new file mode 100644
index 0000000..617d2d2
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/Startup.cs
@@ -0,0 +1,50 @@
+using Microsoft.EntityFrameworkCore;
+using Buyer.DataBase;
+
+public class Startup
+{
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddControllers();
+
+ services.AddDbContext(options =>
+ options.UseNpgsql(Configuration.GetConnectionString("BuyerDatabase")));
+
+ services.AddSwaggerGen();
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceScopeFactory serviceScopeFactory)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseHttpsRedirection();
+
+ app.UseRouting();
+
+ app.UseAuthorization();
+
+ using (var scope = serviceScopeFactory.CreateScope())
+ {
+ var context = scope.ServiceProvider.GetRequiredService();
+ context.Database.Migrate();
+ }
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/appsettings.Development.json b/yakovleva_yulia_lab_3/Buyer/Buyer/appsettings.Development.json
new file mode 100644
index 0000000..ff66ba6
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/yakovleva_yulia_lab_3/Buyer/Buyer/appsettings.json b/yakovleva_yulia_lab_3/Buyer/Buyer/appsettings.json
new file mode 100644
index 0000000..a2752bb
--- /dev/null
+++ b/yakovleva_yulia_lab_3/Buyer/Buyer/appsettings.json
@@ -0,0 +1,12 @@
+{
+ "ConnectionStrings": {
+ "BuyerDatabase": "Host=postgresdb;Database=buyer;Username=postgres;Password=123"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/yakovleva_yulia_lab_3/README.md b/yakovleva_yulia_lab_3/README.md
new file mode 100644
index 0000000..4092d9a
--- /dev/null
+++ b/yakovleva_yulia_lab_3/README.md
@@ -0,0 +1,45 @@
+# Лабораторная работа 3 - REST API, Gateway и синхронный обмен между микросервисами
+
+## Описание
+Были разработаны два микросервиса с простыми CRUD операциями и реализован синхронный обмен сообщениями между ними.
+
+Тема дипломной работы: Разработка системы для автоматизации процессов управления компьютерным клубом на платформе .Net
+
+На основе темы были созданны сущности:
+
+Администратор:
+- Идентификатор
+- Имя
+- Фамилия
+- Идентификатор клиента (связь "один ко многим")
+
+Клиент:
+- Идентификатор
+- Имя
+- Фамилия
+
+Сервис Аминистратора имеет возможность управлять списком Клиентов. При создании Администратора можно указать идентификатор Клиента,
+после чего идет запрос на сервис Клиента с целью узнать существует ли привязываемый Клиент. реализовано с помощью Web-API, интерфейс Swagger,
+база данных PostgreSQL. Каждый сервис использует свою базу данных.
+
+## Запуск
+
+1. Запустить Docker
+2. Открыть консоль, перейти в папку, где хранится docker-compose.yml
+3. Выполнить команду:
+```
+docker compose up --build
+```
+
+## Результат
+Выполняем команду:
+```
+docker compose ps
+```
+Видим, что контейнеры успешно подняты.
+Заходим на http://localhost:32774/swagger/index.html и http://localhost:32773/swagger/index.html - создаем администраторов и клиентов через Swagger.
+Видим, что клиенты успешно созданны.
+Создаем администраторов с ссылкой на клиента.
+
+## Отчет
+Работоспособность: [видео](https://vk.com/video372869030_456239953?list=ln-KBJP1uxkWkQNlqzohl)
\ No newline at end of file
diff --git a/yakovleva_yulia_lab_3/docker-compose.yaml b/yakovleva_yulia_lab_3/docker-compose.yaml
new file mode 100644
index 0000000..70475f6
--- /dev/null
+++ b/yakovleva_yulia_lab_3/docker-compose.yaml
@@ -0,0 +1,50 @@
+services:
+ postgresdb:
+ image: postgres:latest
+ container_name: postgres_container
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: 123
+ POSTGRES_DB: administrator
+ PGDATA: /var/lib/postgresql/data/pgdata
+ ports:
+ - "5430:5432" # Проброс порта для PostgreSQL
+ volumes:
+ - ./database.sql:/docker-entrypoint-initdb.d/database.sql # Инициализация базы данных
+ restart: always
+ networks:
+ - desision-making-system-network
+
+ administrator-service:
+ container_name: administrator-service
+ depends_on:
+ - postgresdb # Заивисмость от запуска Posgresql
+ build:
+ context: ./Administrator
+ dockerfile: ./Administrator/Dockerfile
+ environment:
+ ASPNETCORE_ENVIRONMENT: "Development" # Настраиваем среду разработки
+ ASPNETCORE_URLS: "http://+:8080"
+ ports:
+ - "32773:8080" # Проброс порта 8080
+ networks:
+ - desision-making-system-network
+
+ buyer-service:
+ container_name: buyer-service
+ depends_on:
+ - postgresdb # Заивисмость от запуска Posgresql
+ build:
+ context: ./Buyer
+ dockerfile: ./Buyer/Dockerfile
+ environment:
+ ASPNETCORE_ENVIRONMENT: "Development" # Настраиваем среду разработки
+ ASPNETCORE_URLS: "http://+:8080"
+ ports:
+ - "32774:8080" # Проброс порта
+ networks:
+ - desision-making-system-network
+
+networks:
+ desision-making-system-network:
+ driver: bridge