diff --git a/kamyshov_danila_lab_3/README.md b/kamyshov_danila_lab_3/README.md
new file mode 100644
index 0000000..ab22ba9
--- /dev/null
+++ b/kamyshov_danila_lab_3/README.md
@@ -0,0 +1,154 @@
+# Лабораторная работа №3 - REST API, Gateway и синхронный обмен между микросервисами
+
+Цель: изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API.
+
+Задачи:
+
+Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
+Реализовать механизм синхронного обмена сообщениями между микросервисами.
+Реализовать шлюз на основе прозрачного прокси-сервера nginx.
+
+# Создание микросервисов
+Первый микросервис - messaging-application для сущности "Приложение для обмена сообщениями"
+Второй микросервис - user-device-application для сущности "Устройство пользователя"
+
+Сущность: Устройство пользователя (User Device):
+UUID (Уникальный идентификатор): Уникальный номер или код, идентифицирующий конкретное устройство пользователя.
+Модель (Model): Название и модель устройства пользователя.
+Тип интерфейса (Interface Type): Тип интерфейса для подключения к веб-приложению (Web, Mobile, Desktop и т.д.).
+UUID приложения для обмена сообщениями (messagingAppUuid): Уникальный идентификатор приложения для обмена сообщениями, с которым данное устройство пользователя связано. Это поле устанавливает связь "1-ко-многим" между устройством и приложением.
+
+Сущность: Приложение для обмена сообщениями (Messaging Application):
+UUID (Уникальный идентификатор): Уникальный номер или код, идентифицирующий конкретное приложение для обмена сообщениями.
+Название (Name): Название приложения для обмена сообщениями.
+Поддерживаемые платформы (Supported Platforms): Операционные системы и устройства, на которых работает приложение (Web, Mobile, Desktop и др.).
+Максимальное количество участников (Maximum Participants): Максимальное количество пользователей, которое может использовать приложение для обмена сообщениями одновременно.
+
+Связь "1-ко-многим" между этими сущностями реализуется через поле "UUID приложения" в сущности "Устройство пользователя". Каждое устройство пользователя связано с конкретным приложением для обмена сообщениями через UUID этого приложения, что позволяет одному приложению быть связанным с несколькими устройствами.
+
+Вот примеры моделей для запросов:
+Пример модели "Приложение для обмена сообщениями" для списка:
+{
+ "uuid": "8f036445-a5bd-401c-926e-840f9de795cd",
+ "Name": "Messenger",
+ "Supported Platforms": "Web, iOS, Android",
+ "Maximum Participants": 100
+}
+Пример модели "Приложение для обмена сообщениями" для создания или изменения:
+{
+ "uuid": "8f036445-a5bd-401c-926e-840f9de795cd",
+ "Name": "Messenger",
+ "Supported Platforms": "Web, iOS, Android",
+ "Maximum Participants": 100
+}
+Пример модели "Устройство пользователя" для списка:
+{
+ "uuid": "8740d660-b251-4272-8535-be7ec3748d4b",
+ "Model": "iPhone X",
+ "type": "Mobile",
+ "Interface Type": "ios",
+ "messagingAppUuid": "8f036445-a5bd-401c-926e-840f9de795cd"
+}
+
+Пример модели "Устройство пользователя" для создания или изменения:
+{
+ "Model": "iPhone X",
+ "type": "Mobile",
+ "Interface Type": "ios",
+ "messagingAppUuid": "8f036445-a5bd-401c-926e-840f9de795cd"
+}
+Пример модели "Устройство пользователя" для подробностей:
+{
+ "uuid": "8740d660-b251-4272-8535-be7ec3748d4b",
+ "Model": "iPhone X",
+ "type": "Mobile",
+ "Interface Type": "ios",
+ "messagingAppUuid": "8f036445-a5bd-401c-926e-840f9de795cd",
+ "messagingAppInfo": {
+ "Name": "Messenger",
+ "Supported Platforms": "Web, iOS, Android",
+ "Maximum Participants": 100
+ }
+}
+
+
+
Структура 1-го микросервиса
+
+
+
+
Структура 2-го микросервиса
+
+
+- контроллеры для обработка запросов, дтошки для выбора что изображать в сваггере при запросах, модели для сущностей, репозитории для отправки данных, сервисы для бизнес-логики
+
+# Докер файлы, докер компоус, nginx
+
+
+
Докер файл для 1-го микросервиса
+
+
+
+
Докер файл для 2-го микросервиса
+
+
+-Использования базового образа, установка рабочий директории, копирования джар файла, экспорт порта, запуск приложения при запуске контейнера
+
+
Докер компоус
+
+
+-создания общей сети для всех сервисов, запуск образов сервисов, проброска портов, копирования конфигурационного файла nginx и запуск этого сервиса после запуска других сервисов
+
+
nginx
+
+
+установка количества одновремменных подключений, прослушка запросов по 80 порту, серверное имя локалхост, адрес для переадресации запросов по нему, url переадрусации
+
+
Скрин созданых образов
+
+
+
+
Скрин созданых контейнеров
+
+
+
+
Swagger 1-го микросервиса
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Swagger 2-го микросервиса
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Видео
+
+Видео с разбором лабораторной работы - https://drive.google.com/file/d/1hOHcZAP8aECQXtKm1CcHNDtKli1TdJLO/view?usp=sharing
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/Dockerfile b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/Dockerfile
new file mode 100644
index 0000000..1fdbff9
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/Dockerfile
@@ -0,0 +1,14 @@
+# Используем базовый образ с Java и средой выполнения Spring Boot
+FROM openjdk:17-jdk-slim
+
+# Устанавливаем рабочий каталог внутри контейнера
+WORKDIR /app
+
+# Копируем JAR-файл приложения в контейнер (предполагается, что JAR-файл находится в каталоге target/)
+COPY target/messaging-application-0.0.1-SNAPSHOT.jar messaging-application.jar
+
+# Экспонируем порт, на котором будет работать приложение
+EXPOSE 8099
+
+# Запускаем приложение при запуске контейнера
+CMD ["java", "-jar", "messaging-application.jar"]
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/MessagingApplication.java b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/MessagingApplication.java
new file mode 100644
index 0000000..8be583a
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/MessagingApplication.java
@@ -0,0 +1,11 @@
+package com.example.messagingapplication;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MessagingApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(MessagingApplication.class, args);
+ }
+}
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/controller/MessagingApplicationController.java b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/controller/MessagingApplicationController.java
new file mode 100644
index 0000000..22b3dac
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/controller/MessagingApplicationController.java
@@ -0,0 +1,56 @@
+package com.example.messagingapplication.controller;
+
+import com.example.messagingapplication.model.MessagingApplication;
+import com.example.messagingapplication.dto.MessagingApplicationDTO;
+import com.example.messagingapplication.service.MessagingApplicationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/messaging-application")
+public class MessagingApplicationController {
+ private final MessagingApplicationService applicationService;
+
+ @Autowired
+ public MessagingApplicationController(MessagingApplicationService applicationService) {
+ this.applicationService = applicationService;
+ }
+
+ @GetMapping("/")
+ public List getAllApplications() {
+ return applicationService.getAllApplications();
+ }
+
+ @GetMapping("/{uuid}")
+ public ResponseEntity getApplicationByUuid(@PathVariable String uuid) {
+ return applicationService.getApplicationByUuid(uuid)
+ .map(app -> ResponseEntity.ok().body(app))
+ .orElse(ResponseEntity.notFound().build());
+ }
+
+ @PostMapping("/")
+ public ResponseEntity createApplication(@RequestBody MessagingApplicationDTO applicationDTO) {
+ MessagingApplication createdApplication = applicationService.createApplication(applicationDTO);
+ return ResponseEntity.status(HttpStatus.CREATED).body(createdApplication);
+ }
+
+ @PutMapping("/{uuid}")
+ public ResponseEntity updateApplication(@PathVariable String uuid, @RequestBody MessagingApplicationDTO applicationDTO) {
+ MessagingApplication updatedApplication = applicationService.updateApplication(uuid, applicationDTO);
+ if (updatedApplication != null) {
+ return ResponseEntity.ok().body(updatedApplication);
+ } else {
+ return ResponseEntity.notFound().build();
+ }
+ }
+
+ @DeleteMapping("/{uuid}")
+ public ResponseEntity deleteApplication(@PathVariable String uuid) {
+ boolean deleted = applicationService.deleteApplication(uuid);
+ return deleted ? ResponseEntity.noContent().build() : ResponseEntity.notFound().build();
+ }
+}
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/dto/MessagingApplicationDTO.java b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/dto/MessagingApplicationDTO.java
new file mode 100644
index 0000000..0a539e9
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/dto/MessagingApplicationDTO.java
@@ -0,0 +1,14 @@
+package com.example.messagingapplication.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class MessagingApplicationDTO {
+ private String name;
+ private String supportedPlatforms;
+ private int maximumParticipants;
+}
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/model/MessagingApplication.java b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/model/MessagingApplication.java
new file mode 100644
index 0000000..787ca2e
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/model/MessagingApplication.java
@@ -0,0 +1,22 @@
+package com.example.messagingapplication.model;
+
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "messaging_application")
+@Data
+public class MessagingApplication {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ private String uuid;
+ private String name;
+ private String supportedPlatforms;
+ private int maximumParticipants;
+}
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/repository/MessagingApplicationRepository.java b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/repository/MessagingApplicationRepository.java
new file mode 100644
index 0000000..6b769a5
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/repository/MessagingApplicationRepository.java
@@ -0,0 +1,12 @@
+package com.example.messagingapplication.repository;
+
+import com.example.messagingapplication.model.MessagingApplication;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface MessagingApplicationRepository extends JpaRepository {
+ Optional findByUuid(String uuid);
+}
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/service/MessagingApplicationService.java b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/service/MessagingApplicationService.java
new file mode 100644
index 0000000..1f374a8
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/service/MessagingApplicationService.java
@@ -0,0 +1,70 @@
+package com.example.messagingapplication.service;
+
+import com.example.messagingapplication.model.MessagingApplication;
+import com.example.messagingapplication.dto.MessagingApplicationDTO;
+import com.example.messagingapplication.repository.MessagingApplicationRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Random;
+
+@Service
+@RequiredArgsConstructor
+public class MessagingApplicationService {
+ private final MessagingApplicationRepository applicationRepository;
+
+ @Transactional
+ public List getAllApplications() {
+ return applicationRepository.findAll();
+ }
+
+ @Transactional
+ public Optional getApplicationByUuid(String uuid) {
+ return applicationRepository.findByUuid(uuid);
+ }
+
+ @Transactional
+ public MessagingApplication createApplication(MessagingApplicationDTO applicationDTO) {
+ MessagingApplication application = new MessagingApplication();
+ application.setUuid(createUUID());
+ application.setName(applicationDTO.getName());
+ application.setSupportedPlatforms(applicationDTO.getSupportedPlatforms());
+ application.setMaximumParticipants(applicationDTO.getMaximumParticipants());
+ return applicationRepository.save(application);
+ }
+
+ @Transactional
+ public MessagingApplication updateApplication(String uuid, MessagingApplicationDTO applicationDTO) {
+ Optional existingApplication = applicationRepository.findByUuid(uuid);
+ if (existingApplication.isPresent()) {
+ MessagingApplication application = existingApplication.get();
+ application.setName(applicationDTO.getName());
+ application.setSupportedPlatforms(applicationDTO.getSupportedPlatforms());
+ application.setMaximumParticipants(applicationDTO.getMaximumParticipants());
+ return applicationRepository.save(application);
+ }
+ return null;
+ }
+
+ @Transactional
+ public boolean deleteApplication(String uuid) {
+ Optional existingApplication = applicationRepository.findByUuid(uuid);
+ if (existingApplication.isPresent()) {
+ applicationRepository.delete(existingApplication.get());
+ return true;
+ }
+ return false;
+ }
+
+ private String createUUID() {
+ Random random = new Random();
+ long mostSigBits = random.nextLong();
+ long leastSigBits = random.nextLong();
+ return String.format("%08x-%04x-%04x-%04x-%012x",
+ mostSigBits >>> 32, (mostSigBits >>> 16) & 0xFFFF, mostSigBits & 0xFFFF,
+ (leastSigBits >>> 16) & 0xFFFF, leastSigBits & 0xFFFF);
+ }
+}
diff --git a/kamyshov_danila_lab_3/messaging-application/src/main/resources/application.properties b/kamyshov_danila_lab_3/messaging-application/src/main/resources/application.properties
new file mode 100644
index 0000000..e51fdaa
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/main/resources/application.properties
@@ -0,0 +1,8 @@
+spring.datasource.url=jdbc:h2:mem:testdb
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=password
+spring.jpa.hibernate.ddl-auto=update
+spring.h2.console.enabled=true
+
+server.port=8099
diff --git a/kamyshov_danila_lab_3/messaging-application/src/test/java/com/example/messagingapplication/MessagingApplicationApplicationTests.java b/kamyshov_danila_lab_3/messaging-application/src/test/java/com/example/messagingapplication/MessagingApplicationApplicationTests.java
new file mode 100644
index 0000000..a079ec4
--- /dev/null
+++ b/kamyshov_danila_lab_3/messaging-application/src/test/java/com/example/messagingapplication/MessagingApplicationApplicationTests.java
@@ -0,0 +1,13 @@
+package com.example.messagingapplication;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class MessagingApplicationApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/kamyshov_danila_lab_3/screens/img1.png b/kamyshov_danila_lab_3/screens/img1.png
new file mode 100644
index 0000000..e5ddede
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img1.png differ
diff --git a/kamyshov_danila_lab_3/screens/img10.png b/kamyshov_danila_lab_3/screens/img10.png
new file mode 100644
index 0000000..48082b2
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img10.png differ
diff --git a/kamyshov_danila_lab_3/screens/img11.png b/kamyshov_danila_lab_3/screens/img11.png
new file mode 100644
index 0000000..15e83fb
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img11.png differ
diff --git a/kamyshov_danila_lab_3/screens/img12.png b/kamyshov_danila_lab_3/screens/img12.png
new file mode 100644
index 0000000..fcf2fc6
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img12.png differ
diff --git a/kamyshov_danila_lab_3/screens/img13.png b/kamyshov_danila_lab_3/screens/img13.png
new file mode 100644
index 0000000..665da82
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img13.png differ
diff --git a/kamyshov_danila_lab_3/screens/img14.png b/kamyshov_danila_lab_3/screens/img14.png
new file mode 100644
index 0000000..dff11c7
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img14.png differ
diff --git a/kamyshov_danila_lab_3/screens/img15.png b/kamyshov_danila_lab_3/screens/img15.png
new file mode 100644
index 0000000..acd624f
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img15.png differ
diff --git a/kamyshov_danila_lab_3/screens/img16.png b/kamyshov_danila_lab_3/screens/img16.png
new file mode 100644
index 0000000..4f5fe11
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img16.png differ
diff --git a/kamyshov_danila_lab_3/screens/img17.png b/kamyshov_danila_lab_3/screens/img17.png
new file mode 100644
index 0000000..186ace0
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img17.png differ
diff --git a/kamyshov_danila_lab_3/screens/img18.png b/kamyshov_danila_lab_3/screens/img18.png
new file mode 100644
index 0000000..83739db
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img18.png differ
diff --git a/kamyshov_danila_lab_3/screens/img19.png b/kamyshov_danila_lab_3/screens/img19.png
new file mode 100644
index 0000000..6c8270c
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img19.png differ
diff --git a/kamyshov_danila_lab_3/screens/img2.png b/kamyshov_danila_lab_3/screens/img2.png
new file mode 100644
index 0000000..118b972
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img2.png differ
diff --git a/kamyshov_danila_lab_3/screens/img20.png b/kamyshov_danila_lab_3/screens/img20.png
new file mode 100644
index 0000000..69c42bb
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img20.png differ
diff --git a/kamyshov_danila_lab_3/screens/img3.png b/kamyshov_danila_lab_3/screens/img3.png
new file mode 100644
index 0000000..ec10ad3
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img3.png differ
diff --git a/kamyshov_danila_lab_3/screens/img4.png b/kamyshov_danila_lab_3/screens/img4.png
new file mode 100644
index 0000000..c5b52f6
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img4.png differ
diff --git a/kamyshov_danila_lab_3/screens/img5.png b/kamyshov_danila_lab_3/screens/img5.png
new file mode 100644
index 0000000..b8298a3
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img5.png differ
diff --git a/kamyshov_danila_lab_3/screens/img6.png b/kamyshov_danila_lab_3/screens/img6.png
new file mode 100644
index 0000000..ec9bac9
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img6.png differ
diff --git a/kamyshov_danila_lab_3/screens/img7.png b/kamyshov_danila_lab_3/screens/img7.png
new file mode 100644
index 0000000..ab186aa
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img7.png differ
diff --git a/kamyshov_danila_lab_3/screens/img8.png b/kamyshov_danila_lab_3/screens/img8.png
new file mode 100644
index 0000000..6c150f8
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img8.png differ
diff --git a/kamyshov_danila_lab_3/screens/img9.png b/kamyshov_danila_lab_3/screens/img9.png
new file mode 100644
index 0000000..0f2db9a
Binary files /dev/null and b/kamyshov_danila_lab_3/screens/img9.png differ
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/Dockerfile b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/Dockerfile
new file mode 100644
index 0000000..40a2e46
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/Dockerfile
@@ -0,0 +1,14 @@
+# Используем базовый образ с Java и средой выполнения Spring Boot
+FROM openjdk:17-jdk-slim
+
+# Устанавливаем рабочий каталог внутри контейнера
+WORKDIR /app
+
+# Копируем JAR-файл приложения в контейнер (предполагается, что JAR-файл находится в каталоге target/)
+COPY target/user-device-application-0.0.1-SNAPSHOT.jar user-device-application.jar
+
+# Экспонируем порт, на котором будет работать приложение
+EXPOSE 8090
+
+# Запускаем приложение при запуске контейнера
+CMD ["java", "-jar", "user-device-application.jar"]
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/UserDeviceApplication.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/UserDeviceApplication.java
new file mode 100644
index 0000000..42f96b2
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/UserDeviceApplication.java
@@ -0,0 +1,18 @@
+package com.example.userdeviceapplication;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootApplication
+public class UserDeviceApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(UserDeviceApplication.class, args);
+ }
+
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+}
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/controller/UserDeviceController.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/controller/UserDeviceController.java
new file mode 100644
index 0000000..2c131c1
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/controller/UserDeviceController.java
@@ -0,0 +1,61 @@
+package com.example.userdeviceapplication.controller;
+
+import com.example.userdeviceapplication.dto.UserDeviceCreateUpdateDTO;
+import com.example.userdeviceapplication.dto.UserDeviceDTO;
+import com.example.userdeviceapplication.dto.UserDeviceDetailDTO;
+import com.example.userdeviceapplication.service.UserDeviceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/user-device-application")
+public class UserDeviceController {
+ private final UserDeviceService userDeviceService;
+
+ @Autowired
+ public UserDeviceController(UserDeviceService userDeviceService) {
+ this.userDeviceService = userDeviceService;
+ }
+
+ @GetMapping("/")
+ public ResponseEntity> getUserDevices() {
+ List userDevices = userDeviceService.getAllUserDevices();
+ return ResponseEntity.ok(userDevices);
+ }
+
+ @GetMapping("/{uuid}")
+ public ResponseEntity getUserDevice(@PathVariable String uuid) {
+ UserDeviceDetailDTO userDevice = userDeviceService.getUserDeviceByUuid(uuid);
+ if (userDevice != null) {
+ return ResponseEntity.ok(userDevice);
+ }
+ return ResponseEntity.notFound().build();
+ }
+
+ @PostMapping("/")
+ public ResponseEntity createUserDevice(@RequestBody UserDeviceCreateUpdateDTO createDTO) {
+ UserDeviceDetailDTO userDevice = userDeviceService.createUserDevice(createDTO);
+ return ResponseEntity.ok(userDevice);
+ }
+
+ @PutMapping("/{uuid}")
+ public ResponseEntity updateUserDevice(@PathVariable String uuid, @RequestBody UserDeviceCreateUpdateDTO updateDTO) {
+ UserDeviceDetailDTO userDevice = userDeviceService.updateUserDevice(uuid, updateDTO);
+ if (userDevice != null) {
+ return ResponseEntity.ok(userDevice);
+ }
+ return ResponseEntity.notFound().build();
+ }
+
+ @DeleteMapping("/{uuid}")
+ public ResponseEntity deleteUserDevice(@PathVariable String uuid) {
+ boolean deleted = userDeviceService.deleteUserDevice(uuid);
+ if (deleted) {
+ return ResponseEntity.ok().build();
+ }
+ return ResponseEntity.notFound().build();
+ }
+}
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/docker-compose.yml b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/docker-compose.yml
new file mode 100644
index 0000000..4b2ac6e
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/docker-compose.yml
@@ -0,0 +1,31 @@
+version: '3'
+services:
+ messaging-application:
+ image: messagingapplication_microservice_1:1.0
+ ports:
+ - "8099:8099"
+ networks:
+ - network
+
+ user-device-application:
+ image: userdeviceapplication_microservice_2:1.0
+ ports:
+ - "8090:8090"
+ networks:
+ - network
+
+ nginx:
+ image: nginx:latest
+ ports:
+ - "80:80"
+ networks:
+ - network
+ volumes:
+ - ./nginx.conf:/etc/nginx/nginx.conf
+ depends_on:
+ - messaging-application
+ - user-device-application
+
+networks:
+ network:
+ driver: bridge
\ No newline at end of file
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceCreateUpdateDTO.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceCreateUpdateDTO.java
new file mode 100644
index 0000000..d232f28
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceCreateUpdateDTO.java
@@ -0,0 +1,11 @@
+package com.example.userdeviceapplication.dto;
+
+import lombok.Data;
+
+@Data
+public class UserDeviceCreateUpdateDTO {
+ private String model;
+ private String type;
+ private String interfaceType;
+ private String messagingAppUuid;
+}
\ No newline at end of file
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDTO.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDTO.java
new file mode 100644
index 0000000..aeca910
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDTO.java
@@ -0,0 +1,12 @@
+package com.example.userdeviceapplication.dto;
+
+import lombok.Data;
+
+@Data
+public class UserDeviceDTO {
+ private String uuid;
+ private String model;
+ private String type;
+ private String interfaceType;
+ private String messagingAppUuid;
+}
\ No newline at end of file
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailDTO.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailDTO.java
new file mode 100644
index 0000000..d014e77
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailDTO.java
@@ -0,0 +1,13 @@
+package com.example.userdeviceapplication.dto;
+
+import lombok.Data;
+
+@Data
+public class UserDeviceDetailDTO {
+ private String uuid;
+ private String model;
+ private String type;
+ private String interfaceType;
+ private String messagingAppUuid;
+ private UserDeviceDetailInfoDTO messagingAppInfo;
+}
\ No newline at end of file
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailInfoDTO.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailInfoDTO.java
new file mode 100644
index 0000000..030f9bb
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailInfoDTO.java
@@ -0,0 +1,10 @@
+package com.example.userdeviceapplication.dto;
+
+import lombok.Data;
+
+@Data
+public class UserDeviceDetailInfoDTO {
+ private String name;
+ private String supportedPlatforms;
+ private int maximumParticipants;
+}
\ No newline at end of file
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/model/UserDevice.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/model/UserDevice.java
new file mode 100644
index 0000000..3c1b632
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/model/UserDevice.java
@@ -0,0 +1,21 @@
+package com.example.userdeviceapplication.model;
+
+import lombok.Data;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+
+@Entity
+@Data
+public class UserDevice {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ private String uuid;
+ private String model;
+ private String type;
+ private String interfaceType;
+ private String messagingAppUuid;
+}
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/nginx.conf b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/nginx.conf
new file mode 100644
index 0000000..6b04374
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/nginx.conf
@@ -0,0 +1,19 @@
+events {
+ worker_connections 1024;
+}
+
+http {
+ server {
+ listen 80;
+ listen [::]:80;
+ server_name localhost;
+
+ location /messaging-application/ {
+ proxy_pass http://messaging-application:8099;
+ }
+
+ location /user-device-application/ {
+ proxy_pass http://user-device-application:8090;
+ }
+ }
+}
\ No newline at end of file
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/repository/UserDeviceRepository.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/repository/UserDeviceRepository.java
new file mode 100644
index 0000000..6e32c4d
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/repository/UserDeviceRepository.java
@@ -0,0 +1,10 @@
+package com.example.userdeviceapplication.repository;
+
+import com.example.userdeviceapplication.model.UserDevice;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UserDeviceRepository extends JpaRepository {
+ UserDevice findByUuid(String uuid);
+}
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/service/UserDeviceService.java b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/service/UserDeviceService.java
new file mode 100644
index 0000000..c601825
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/service/UserDeviceService.java
@@ -0,0 +1,114 @@
+package com.example.userdeviceapplication.service;
+
+import com.example.userdeviceapplication.dto.UserDeviceCreateUpdateDTO;
+import com.example.userdeviceapplication.dto.UserDeviceDTO;
+import com.example.userdeviceapplication.dto.UserDeviceDetailDTO;
+import com.example.userdeviceapplication.dto.UserDeviceDetailInfoDTO;
+import com.example.userdeviceapplication.model.UserDevice;
+import com.example.userdeviceapplication.repository.UserDeviceRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+@Service
+public class UserDeviceService {
+ private final UserDeviceRepository userDeviceRepository;
+ private final RestTemplate restTemplate;
+
+ @Autowired
+ public UserDeviceService(UserDeviceRepository userDeviceRepository, RestTemplate restTemplate) {
+ this.userDeviceRepository = userDeviceRepository;
+ this.restTemplate = restTemplate;
+ }
+
+ public List getAllUserDevices() {
+ List userDevices = userDeviceRepository.findAll();
+ return userDevices.stream()
+ .map(this::convertToUserDeviceDTO)
+ .collect(Collectors.toList());
+ }
+
+ public UserDeviceDetailDTO getUserDeviceByUuid(String uuid) {
+ UserDevice userDevice = userDeviceRepository.findByUuid(uuid);
+ if (userDevice != null) {
+ return convertToUserDeviceDetailDTO(userDevice);
+ }
+ return null;
+ }
+
+ public UserDeviceDetailDTO createUserDevice(UserDeviceCreateUpdateDTO createDTO) {
+ UserDevice userDevice = new UserDevice();
+ userDevice.setUuid(createUUID());
+ updateUserDeviceFromDTO(userDevice, createDTO);
+ userDevice = userDeviceRepository.save(userDevice);
+ return convertToUserDeviceDetailDTO(userDevice);
+ }
+
+ public UserDeviceDetailDTO updateUserDevice(String uuid, UserDeviceCreateUpdateDTO updateDTO) {
+ UserDevice userDevice = userDeviceRepository.findByUuid(uuid);
+ if (userDevice != null) {
+ updateUserDeviceFromDTO(userDevice, updateDTO);
+ userDevice = userDeviceRepository.save(userDevice);
+ return convertToUserDeviceDetailDTO(userDevice);
+ }
+ return null;
+ }
+
+ public boolean deleteUserDevice(String uuid) {
+ UserDevice userDevice = userDeviceRepository.findByUuid(uuid);
+ if (userDevice != null) {
+ userDeviceRepository.delete(userDevice);
+ return true;
+ }
+ return false;
+ }
+
+ private UserDeviceDTO convertToUserDeviceDTO(UserDevice userDevice) {
+ UserDeviceDTO dto = new UserDeviceDTO();
+ dto.setUuid(userDevice.getUuid());
+ dto.setModel(userDevice.getModel());
+ dto.setType(userDevice.getType());
+ dto.setInterfaceType(userDevice.getInterfaceType());
+ dto.setMessagingAppUuid(userDevice.getMessagingAppUuid());
+ return dto;
+ }
+
+ private UserDeviceDetailDTO convertToUserDeviceDetailDTO(UserDevice userDevice) {
+ UserDeviceDetailDTO detailDTO = new UserDeviceDetailDTO();
+ detailDTO.setUuid(userDevice.getUuid());
+ detailDTO.setModel(userDevice.getModel());
+ detailDTO.setType(userDevice.getType());
+ detailDTO.setInterfaceType(userDevice.getInterfaceType());
+ detailDTO.setMessagingAppUuid(userDevice.getMessagingAppUuid());
+
+ UserDeviceDetailInfoDTO subscriptionInfo = getmessagingAppInfo(userDevice.getMessagingAppUuid());
+ detailDTO.setMessagingAppInfo(subscriptionInfo);
+
+ return detailDTO;
+ }
+
+ private void updateUserDeviceFromDTO(UserDevice userDevice, UserDeviceCreateUpdateDTO dto) {
+ userDevice.setModel(dto.getModel());
+ userDevice.setType(dto.getType());
+ userDevice.setInterfaceType(dto.getInterfaceType());
+ userDevice.setMessagingAppUuid(dto.getMessagingAppUuid());
+ }
+
+ private String createUUID() {
+ Random random = new Random();
+ long mostSigBits = random.nextLong();
+ long leastSigBits = random.nextLong();
+ return String.format("%08x-%04x-%04x-%04x-%012x",
+ mostSigBits >>> 32, (mostSigBits >>> 16) & 0xFFFF, mostSigBits & 0xFFFF,
+ (leastSigBits >>> 16) & 0xFFFF, leastSigBits & 0xFFFF);
+ }
+
+ private UserDeviceDetailInfoDTO getmessagingAppInfo(String messagingAppUuid) {
+ String messagingAppInfoUrl = "http://nginx/messaging-application/" + messagingAppUuid;
+ return restTemplate.getForObject(messagingAppInfoUrl, UserDeviceDetailInfoDTO.class);
+ }
+}
diff --git a/kamyshov_danila_lab_3/user-device-application/src/main/resources/application.properties b/kamyshov_danila_lab_3/user-device-application/src/main/resources/application.properties
new file mode 100644
index 0000000..b00d2a6
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+spring.datasource.url=jdbc:h2:mem:testdb
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=password
+spring.jpa.hibernate.ddl-auto=update
+spring.h2.console.enabled=true
+
+server.port=8090
+
diff --git a/kamyshov_danila_lab_3/user-device-application/src/test/java/com/example/userdeviceapplication/UserDeviceApplicationTests.java b/kamyshov_danila_lab_3/user-device-application/src/test/java/com/example/userdeviceapplication/UserDeviceApplicationTests.java
new file mode 100644
index 0000000..46aa8c9
--- /dev/null
+++ b/kamyshov_danila_lab_3/user-device-application/src/test/java/com/example/userdeviceapplication/UserDeviceApplicationTests.java
@@ -0,0 +1,13 @@
+package com.example.userdeviceapplication;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class UserDeviceApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}