From 722b354fab45279dafde02ece16cd01b93a39ee4 Mon Sep 17 00:00:00 2001
From: Danila Kamyshov
Date: Mon, 25 Dec 2023 21:53:03 +0400
Subject: [PATCH] kamyshov_danila_lab_3 is ready
---
kamyshov_danila_lab_3/README.md | 154 ++++++++++++++++++
.../example/messagingapplication/Dockerfile | 14 ++
.../MessagingApplication.java | 11 ++
.../MessagingApplicationController.java | 56 +++++++
.../dto/MessagingApplicationDTO.java | 14 ++
.../model/MessagingApplication.java | 22 +++
.../MessagingApplicationRepository.java | 12 ++
.../service/MessagingApplicationService.java | 70 ++++++++
.../src/main/resources/application.properties | 8 +
.../MessagingApplicationApplicationTests.java | 13 ++
kamyshov_danila_lab_3/screens/img1.png | Bin 0 -> 70342 bytes
kamyshov_danila_lab_3/screens/img10.png | Bin 0 -> 46970 bytes
kamyshov_danila_lab_3/screens/img11.png | Bin 0 -> 33382 bytes
kamyshov_danila_lab_3/screens/img12.png | Bin 0 -> 39633 bytes
kamyshov_danila_lab_3/screens/img13.png | Bin 0 -> 53494 bytes
kamyshov_danila_lab_3/screens/img14.png | Bin 0 -> 33263 bytes
kamyshov_danila_lab_3/screens/img15.png | Bin 0 -> 58150 bytes
kamyshov_danila_lab_3/screens/img16.png | Bin 0 -> 62440 bytes
kamyshov_danila_lab_3/screens/img17.png | Bin 0 -> 35717 bytes
kamyshov_danila_lab_3/screens/img18.png | Bin 0 -> 52597 bytes
kamyshov_danila_lab_3/screens/img19.png | Bin 0 -> 68431 bytes
kamyshov_danila_lab_3/screens/img2.png | Bin 0 -> 75662 bytes
kamyshov_danila_lab_3/screens/img20.png | Bin 0 -> 33400 bytes
kamyshov_danila_lab_3/screens/img3.png | Bin 0 -> 54671 bytes
kamyshov_danila_lab_3/screens/img4.png | Bin 0 -> 55373 bytes
kamyshov_danila_lab_3/screens/img5.png | Bin 0 -> 78616 bytes
kamyshov_danila_lab_3/screens/img6.png | Bin 0 -> 48665 bytes
kamyshov_danila_lab_3/screens/img7.png | Bin 0 -> 28129 bytes
kamyshov_danila_lab_3/screens/img8.png | Bin 0 -> 63106 bytes
kamyshov_danila_lab_3/screens/img9.png | Bin 0 -> 56532 bytes
.../example/userdeviceapplication/Dockerfile | 14 ++
.../UserDeviceApplication.java | 18 ++
.../controller/UserDeviceController.java | 61 +++++++
.../userdeviceapplication/docker-compose.yml | 31 ++++
.../dto/UserDeviceCreateUpdateDTO.java | 11 ++
.../dto/UserDeviceDTO.java | 12 ++
.../dto/UserDeviceDetailDTO.java | 13 ++
.../dto/UserDeviceDetailInfoDTO.java | 10 ++
.../model/UserDevice.java | 21 +++
.../example/userdeviceapplication/nginx.conf | 19 +++
.../repository/UserDeviceRepository.java | 10 ++
.../service/UserDeviceService.java | 114 +++++++++++++
.../src/main/resources/application.properties | 9 +
.../UserDeviceApplicationTests.java | 13 ++
44 files changed, 730 insertions(+)
create mode 100644 kamyshov_danila_lab_3/README.md
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/Dockerfile
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/MessagingApplication.java
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/controller/MessagingApplicationController.java
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/dto/MessagingApplicationDTO.java
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/model/MessagingApplication.java
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/repository/MessagingApplicationRepository.java
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/java/com/example/messagingapplication/service/MessagingApplicationService.java
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/main/resources/application.properties
create mode 100644 kamyshov_danila_lab_3/messaging-application/src/test/java/com/example/messagingapplication/MessagingApplicationApplicationTests.java
create mode 100644 kamyshov_danila_lab_3/screens/img1.png
create mode 100644 kamyshov_danila_lab_3/screens/img10.png
create mode 100644 kamyshov_danila_lab_3/screens/img11.png
create mode 100644 kamyshov_danila_lab_3/screens/img12.png
create mode 100644 kamyshov_danila_lab_3/screens/img13.png
create mode 100644 kamyshov_danila_lab_3/screens/img14.png
create mode 100644 kamyshov_danila_lab_3/screens/img15.png
create mode 100644 kamyshov_danila_lab_3/screens/img16.png
create mode 100644 kamyshov_danila_lab_3/screens/img17.png
create mode 100644 kamyshov_danila_lab_3/screens/img18.png
create mode 100644 kamyshov_danila_lab_3/screens/img19.png
create mode 100644 kamyshov_danila_lab_3/screens/img2.png
create mode 100644 kamyshov_danila_lab_3/screens/img20.png
create mode 100644 kamyshov_danila_lab_3/screens/img3.png
create mode 100644 kamyshov_danila_lab_3/screens/img4.png
create mode 100644 kamyshov_danila_lab_3/screens/img5.png
create mode 100644 kamyshov_danila_lab_3/screens/img6.png
create mode 100644 kamyshov_danila_lab_3/screens/img7.png
create mode 100644 kamyshov_danila_lab_3/screens/img8.png
create mode 100644 kamyshov_danila_lab_3/screens/img9.png
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/Dockerfile
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/UserDeviceApplication.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/controller/UserDeviceController.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/docker-compose.yml
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceCreateUpdateDTO.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDTO.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailDTO.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/dto/UserDeviceDetailInfoDTO.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/model/UserDevice.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/nginx.conf
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/repository/UserDeviceRepository.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/java/com/example/userdeviceapplication/service/UserDeviceService.java
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/main/resources/application.properties
create mode 100644 kamyshov_danila_lab_3/user-device-application/src/test/java/com/example/userdeviceapplication/UserDeviceApplicationTests.java
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 0000000000000000000000000000000000000000..e5ddede26fe847b00988c60a1213fac62cbcb5fb
GIT binary patch
literal 70342
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