diff --git a/shadaev_anton_lab_3/README.md b/shadaev_anton_lab_3/README.md
new file mode 100644
index 0000000..43e22e2
--- /dev/null
+++ b/shadaev_anton_lab_3/README.md
@@ -0,0 +1,74 @@
+# Лабораторная работа №3 - REST API, Gateway и синхронный обмен между микросервисами
+Цель:
+
+Изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API.
+
+Задачи:
+
+Создать 2 микросервиса, реализующих CRUD на связанных сущностях. Реализовать механизм синхронного обмена сообщениями между микросервисами. Реализовать шлюз на основе прозрачного прокси-сервера nginx.
+
+## Запуск:
+
+Чтобы запустить контейнеры в docker, необходимо выполнить следующую команду: `docker-compose -f \ docker-compose.yml up -d`, где:
+
+ -f - путь до docker-compose.yml файла
+ -d - фоновый режим запуска
+
+
+## Демонстрация работы программы
+### Сервис Aggregator
+POST-метод для создания вакансии
+
+![1.png](screenshots%2F1.png)
+
+GET-метод для получения вакансии по id
+
+![2.png](screenshots%2F2.png)
+
+GET-метод для получения списка вакансий
+
+![3.png](screenshots%2F3.png)
+
+PUT-метод для обновления вакансии
+
+![4.png](screenshots%2F4.png)
+
+DELETE-метод для удаления вакансии
+
+![5.png](screenshots%2F5.png)
+
+### Метод, связывающий оба микросервиса
+Демонстрация работы:
+
+![img_12.png](screenshots%2Fimg_12.png)
+
+### Сущности
+Page -> Jobs (One-to-Many)
+
+![img.png](screenshots/test/img.png)
+
+![img_1.png](screenshots/test/img_1.png)
+
+### Dockerfile (aggregator-api)
+
+![img_2.png](screenshots/test/img_2.png)
+
+### Dockerfile (parser-api)
+
+![img_3.png](screenshots/test/img_3.png)
+
+### Docker compose
+
+![img_4.png](screenshots/test/img_4.png)
+
+![img_5.png](screenshots/test/img_5.png)
+
+![img_6.png](screenshots/test/img_6.png)
+
+![img_7.png](screenshots/test/img_7.png)
+
+### Nginx
+![img_8.png](screenshots%2Ftest%2Fimg_8.png)
+
+## Ссылка на видео:
+https://youtu.be/oPLQxyRDlXw
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/Dockerfile b/shadaev_anton_lab_3/aggregator-api/Dockerfile
new file mode 100644
index 0000000..3cf37cb
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/Dockerfile
@@ -0,0 +1,9 @@
+FROM openjdk:17-jdk-slim
+
+EXPOSE 8080
+
+WORKDIR /app
+
+COPY aggregator-api-1.0-SNAPSHOT.jar /app
+
+CMD ["java", "-jar", "/app/aggregator-api-1.0-SNAPSHOT.jar"]
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/aggregator-api-1.0-SNAPSHOT.jar b/shadaev_anton_lab_3/aggregator-api/aggregator-api-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..b1633e2
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/aggregator-api-1.0-SNAPSHOT.jar differ
diff --git a/shadaev_anton_lab_3/aggregator-api/pom.xml b/shadaev_anton_lab_3/aggregator-api/pom.xml
new file mode 100644
index 0000000..2dc83fe
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.company
+ shadaev_anton_lab_3
+ 1.0-SNAPSHOT
+
+
+ aggregator-api
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
+
+ org.postgresql
+ postgresql
+ 42.3.1
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/AggregatorApiApplication.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/AggregatorApiApplication.java
new file mode 100644
index 0000000..b4317dd
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/AggregatorApiApplication.java
@@ -0,0 +1,11 @@
+package com.company;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class AggregatorApiApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(AggregatorApiApplication.class, args);
+ }
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/controller/JobController.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/controller/JobController.java
new file mode 100644
index 0000000..f8b9598
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/controller/JobController.java
@@ -0,0 +1,77 @@
+package com.company.controller;
+
+import com.company.dto.JobDto;
+import com.company.exceptions.JobAlreadyExistsException;
+import com.company.exceptions.JobNotFoundException;
+import com.company.model.Job;
+import com.company.service.JobService;
+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;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/jobs")
+public class JobController {
+ private final JobService jobService;
+
+ @Autowired
+ public JobController(JobService jobService) {
+ this.jobService = jobService;
+ }
+
+ @PostMapping
+ public ResponseEntity> save(@RequestBody JobDto jobDto) {
+ Job job;
+ try {
+ if (jobService.findJobByTitle(jobDto.getTitle()).isPresent())
+ throw new JobAlreadyExistsException("Job already exists!");
+ job = jobService.save(jobDto);
+ return ResponseEntity.status(HttpStatus.CREATED).body(job);
+ } catch (JobAlreadyExistsException e) {
+ return ResponseEntity.badRequest().body(e.getMessage());
+ }
+ }
+
+ @GetMapping
+ public List findAll() {
+ return jobService.findAll();
+ }
+
+ @GetMapping("/{uuid}")
+ public ResponseEntity findJobByUUID(@PathVariable UUID uuid) {
+ return jobService.findJobByUUID(uuid)
+ .map(app -> ResponseEntity.ok().body(app))
+ .orElse(ResponseEntity.notFound().build());
+ }
+
+ @PutMapping("/{uuid}")
+ public ResponseEntity> updateJobByUUID(@PathVariable UUID uuid, @RequestBody JobDto jobDto) {
+ Job job;
+ try {
+ if (jobService.findJobByUUID(uuid).isEmpty())
+ throw new JobNotFoundException("Job not found!");
+ job = jobService.updateJobByUUID(uuid, jobDto);
+ return ResponseEntity.ok().body(job);
+ } catch (JobNotFoundException e) {
+ return ResponseEntity.badRequest().body(e.getMessage());
+ }
+ }
+
+ @DeleteMapping("/{uuid}")
+ public ResponseEntity> deleteJobByUUID(@PathVariable UUID uuid) {
+ UUID statusId;
+ try {
+ if (!jobService.findJobByUUID(uuid).isPresent())
+ throw new JobNotFoundException("Job not found!");
+ statusId = jobService.deleteJobByUUID(uuid);
+ return ResponseEntity.ok().body(statusId);
+ } catch (JobNotFoundException e) {
+ return ResponseEntity.badRequest().body(e.getMessage());
+ }
+ }
+
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/dto/JobDto.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/dto/JobDto.java
new file mode 100644
index 0000000..4840aea
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/dto/JobDto.java
@@ -0,0 +1,19 @@
+package com.company.dto;
+
+import com.company.model.Job;
+import lombok.Getter;
+
+public record JobDto(@Getter String title, @Getter String description) {
+
+ public JobDto(String title, String description) {
+ this.title = title;
+ this.description = description;
+ }
+
+ public static Job toJob(JobDto jobDto) {
+ return Job.builder()
+ .title(jobDto.getTitle())
+ .description(jobDto.getDescription())
+ .build();
+ }
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/exceptions/JobAlreadyExistsException.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/exceptions/JobAlreadyExistsException.java
new file mode 100644
index 0000000..6b82337
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/exceptions/JobAlreadyExistsException.java
@@ -0,0 +1,10 @@
+package com.company.exceptions;
+
+public class JobAlreadyExistsException extends Exception {
+ public JobAlreadyExistsException() {
+ }
+
+ public JobAlreadyExistsException(String message) {
+ super(message);
+ }
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/exceptions/JobNotFoundException.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/exceptions/JobNotFoundException.java
new file mode 100644
index 0000000..0bfdf21
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/exceptions/JobNotFoundException.java
@@ -0,0 +1,10 @@
+package com.company.exceptions;
+
+public class JobNotFoundException extends Exception {
+ public JobNotFoundException() {
+ }
+
+ public JobNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/model/Job.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/model/Job.java
new file mode 100644
index 0000000..0032f7c
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/model/Job.java
@@ -0,0 +1,21 @@
+package com.company.model;
+
+import lombok.*;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Entity
+@Table(name = "jobs")
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+@Builder
+public class Job {
+ @Id
+ @GeneratedValue
+ private UUID id;
+ private String title;
+ private String description;
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/repo/JobRepository.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/repo/JobRepository.java
new file mode 100644
index 0000000..4eba8b1
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/repo/JobRepository.java
@@ -0,0 +1,13 @@
+package com.company.repo;
+
+import com.company.model.Job;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+import java.util.UUID;
+
+@Repository
+public interface JobRepository extends JpaRepository {
+ Optional findJobByTitle(String title);
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/service/JobService.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/service/JobService.java
new file mode 100644
index 0000000..cfeffeb
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/service/JobService.java
@@ -0,0 +1,17 @@
+package com.company.service;
+
+import com.company.dto.JobDto;
+import com.company.model.Job;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+public interface JobService {
+ Job save(JobDto job);
+ List findAll();
+ Optional findJobByUUID(UUID uuid);
+ Optional findJobByTitle(String title);
+ Job updateJobByUUID(UUID uuid, JobDto jobDto);
+ UUID deleteJobByUUID(UUID uuid);
+}
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/service/impl/JobService.java b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/service/impl/JobService.java
new file mode 100644
index 0000000..75553a4
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/java/com/company/service/impl/JobService.java
@@ -0,0 +1,62 @@
+package com.company.service.impl;
+
+import com.company.dto.JobDto;
+import com.company.model.Job;
+import com.company.repo.JobRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+@Service
+public class JobService implements com.company.service.JobService {
+ private final JobRepository jobRepository;
+
+ @Autowired
+ public JobService(JobRepository jobRepository) {
+ this.jobRepository = jobRepository;
+ }
+
+ @Override
+ @Transactional
+ public Job save(JobDto jobDto) {
+ return jobRepository.save(JobDto.toJob(jobDto));
+ }
+
+ @Override
+ @Transactional
+ public List findAll(){
+ return jobRepository.findAll();
+ }
+
+ @Override
+ @Transactional
+ public Optional findJobByUUID(UUID uuid) {
+ return Optional.ofNullable(jobRepository.findById(uuid).get());
+ }
+
+ @Override
+ @Transactional
+ public Optional findJobByTitle(String title) {
+ return Optional.ofNullable(jobRepository.findJobByTitle(title)).get();
+ }
+
+ @Override
+ @Transactional
+ public Job updateJobByUUID(UUID uuid, JobDto jobDto) {
+ Job job = jobRepository.findById(uuid).get();
+ job.setTitle(jobDto.getTitle());
+ job.setDescription(jobDto.getDescription());
+ return jobRepository.save(job);
+ }
+
+ @Override
+ @Transactional
+ public UUID deleteJobByUUID(UUID uuid) {
+ jobRepository.deleteById(uuid);
+ return uuid;
+ }
+}
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/resources/application.yaml b/shadaev_anton_lab_3/aggregator-api/src/main/resources/application.yaml
new file mode 100644
index 0000000..1161207
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/resources/application.yaml
@@ -0,0 +1,13 @@
+server:
+ port: 8080
+
+spring:
+ jpa:
+ hibernate:
+ ddl-auto: update
+ show-sql: true
+ datasource:
+ driverClassName: org.postgresql.Driver
+ url: jdbc:postgresql://localhost:5433/aggregator_db
+ username: postgres
+ password: postgres
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/src/main/resources/templates/test.html b/shadaev_anton_lab_3/aggregator-api/src/main/resources/templates/test.html
new file mode 100644
index 0000000..5957de6
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/src/main/resources/templates/test.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ test
+
+
+ test...
+
+
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/target/aggregator-api-1.0-SNAPSHOT.jar b/shadaev_anton_lab_3/aggregator-api/target/aggregator-api-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..b1633e2
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/aggregator-api-1.0-SNAPSHOT.jar differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/aggregator-api-1.0-SNAPSHOT.jar.original b/shadaev_anton_lab_3/aggregator-api/target/aggregator-api-1.0-SNAPSHOT.jar.original
new file mode 100644
index 0000000..0503279
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/aggregator-api-1.0-SNAPSHOT.jar.original differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/application.yaml b/shadaev_anton_lab_3/aggregator-api/target/classes/application.yaml
new file mode 100644
index 0000000..1161207
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/target/classes/application.yaml
@@ -0,0 +1,13 @@
+server:
+ port: 8080
+
+spring:
+ jpa:
+ hibernate:
+ ddl-auto: update
+ show-sql: true
+ datasource:
+ driverClassName: org.postgresql.Driver
+ url: jdbc:postgresql://localhost:5433/aggregator_db
+ username: postgres
+ password: postgres
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/AggregatorApiApplication.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/AggregatorApiApplication.class
new file mode 100644
index 0000000..9855bdd
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/AggregatorApiApplication.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/controller/JobController.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/controller/JobController.class
new file mode 100644
index 0000000..8110034
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/controller/JobController.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/dto/JobDto.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/dto/JobDto.class
new file mode 100644
index 0000000..dd565b8
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/dto/JobDto.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/exceptions/JobAlreadyExistsException.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/exceptions/JobAlreadyExistsException.class
new file mode 100644
index 0000000..ce4aa1b
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/exceptions/JobAlreadyExistsException.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/exceptions/JobNotFoundException.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/exceptions/JobNotFoundException.class
new file mode 100644
index 0000000..cb98d45
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/exceptions/JobNotFoundException.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/model/Job.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/model/Job.class
new file mode 100644
index 0000000..d7ed5b9
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/model/Job.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/repo/JobRepository.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/repo/JobRepository.class
new file mode 100644
index 0000000..9e5847c
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/repo/JobRepository.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/service/JobService.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/service/JobService.class
new file mode 100644
index 0000000..b3289ca
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/service/JobService.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/service/impl/JobService.class b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/service/impl/JobService.class
new file mode 100644
index 0000000..5b3fe0e
Binary files /dev/null and b/shadaev_anton_lab_3/aggregator-api/target/classes/com/company/service/impl/JobService.class differ
diff --git a/shadaev_anton_lab_3/aggregator-api/target/classes/templates/test.html b/shadaev_anton_lab_3/aggregator-api/target/classes/templates/test.html
new file mode 100644
index 0000000..5957de6
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/target/classes/templates/test.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ test
+
+
+ test...
+
+
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/aggregator-api/target/maven-archiver/pom.properties b/shadaev_anton_lab_3/aggregator-api/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..097b875
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/target/maven-archiver/pom.properties
@@ -0,0 +1,3 @@
+artifactId=aggregator-api
+groupId=com.company
+version=1.0-SNAPSHOT
diff --git a/shadaev_anton_lab_3/aggregator-api/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/shadaev_anton_lab_3/aggregator-api/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..f87c14a
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,10 @@
+com/company/controller/JobController.class
+com/company/service/JobService.class
+com/company/model/Job$JobBuilder.class
+com/company/exceptions/JobAlreadyExistsException.class
+com/company/exceptions/JobNotFoundException.class
+com/company/repo/JobRepository.class
+com/company/dto/JobDto.class
+com/company/service/impl/JobService.class
+com/company/model/Job.class
+com/company/AggregatorApiApplication.class
diff --git a/shadaev_anton_lab_3/aggregator-api/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/shadaev_anton_lab_3/aggregator-api/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..26bdb32
--- /dev/null
+++ b/shadaev_anton_lab_3/aggregator-api/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,9 @@
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/dto/JobDto.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/model/Job.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/service/JobService.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/exceptions/JobNotFoundException.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/exceptions/JobAlreadyExistsException.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/repo/JobRepository.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/service/impl/JobService.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/AggregatorApiApplication.java
+/Users/a-shdv/IdeaProjects/aggregator/aggregator-api/src/main/java/com/company/controller/JobController.java
diff --git a/shadaev_anton_lab_3/docker-compose.yaml b/shadaev_anton_lab_3/docker-compose.yaml
new file mode 100644
index 0000000..d82d8ef
--- /dev/null
+++ b/shadaev_anton_lab_3/docker-compose.yaml
@@ -0,0 +1,74 @@
+version: '3.8'
+services:
+ aggregator-api-service:
+# image: kybernetique/aggregator-api:latest
+ build:
+ context: ./aggregator-api
+ dockerfile: Dockerfile
+ ports:
+ - "8081:8080"
+ environment:
+ - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres-service/aggregator_db
+ - SPRING_DATASOURCE_USERNAME=postgres
+ - SPRING_DATASOURCE_PASSWORD=postgres
+ - SPRING_JPA_HIBERNATE_DDL_AUTO=create-drop
+ depends_on:
+ - postgres-service
+ networks:
+ backend:
+ aliases:
+ - "aggregator"
+
+
+ parser-api-service:
+# image: kybernetique/parser-api:latest
+ build:
+ context: ./parser-api
+ dockerfile: Dockerfile
+ ports:
+ - "8082:8081"
+ environment:
+ - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres-service/aggregator_db
+ - SPRING_DATASOURCE_USERNAME=postgres
+ - SPRING_DATASOURCE_PASSWORD=postgres
+ - SPRING_JPA_HIBERNATE_DDL_AUTO=create-drop
+ depends_on:
+ - postgres-service
+ networks:
+ backend:
+ aliases:
+ - "parser"
+
+ postgres-service:
+ image: postgres:14.1
+ container_name: postgres-db
+ restart: always
+ ports:
+ - "5433:5432"
+ environment:
+ POSTGRES_DB: "aggregator_db"
+ POSTGRES_USER: "postgres"
+ POSTGRES_PASSWORD: "postgres"
+ networks:
+ backend:
+ aliases:
+ - "postgres"
+
+ nginx-service:
+ image: nginx:latest
+ ports:
+ - "81:80"
+ networks:
+ backend:
+ aliases:
+ - "nginx"
+ volumes:
+ - ./nginx.conf:/etc/nginx/nginx.conf
+ depends_on:
+ - aggregator-api-service
+ - parser-api-service
+ - postgres-service
+
+networks:
+ backend:
+ driver: bridge
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/nginx.conf b/shadaev_anton_lab_3/nginx.conf
new file mode 100644
index 0000000..3d9dfdb
--- /dev/null
+++ b/shadaev_anton_lab_3/nginx.conf
@@ -0,0 +1,19 @@
+events {
+ worker_connections 1024;
+}
+
+http {
+ server {
+ listen 80;
+ listen [::]:80;
+ server_name localhost;
+
+ location /aggregator-api/ {
+ proxy_pass http://aggregator-api-service:8080/;
+ }
+
+ location /parser-api/ {
+ proxy_pass http://parser-api-service:8081/;
+ }
+ }
+}
diff --git a/shadaev_anton_lab_3/parser-api/Dockerfile b/shadaev_anton_lab_3/parser-api/Dockerfile
new file mode 100644
index 0000000..c58ab26
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/Dockerfile
@@ -0,0 +1,9 @@
+FROM openjdk:17-jdk-slim
+
+EXPOSE 8080
+
+WORKDIR /app
+
+COPY parser-api-1.0-SNAPSHOT.jar /app
+
+CMD ["java", "-jar", "/app/parser-api-1.0-SNAPSHOT.jar"]
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/parser-api/parser-api-1.0-SNAPSHOT.jar b/shadaev_anton_lab_3/parser-api/parser-api-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..483ff13
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/parser-api-1.0-SNAPSHOT.jar differ
diff --git a/shadaev_anton_lab_3/parser-api/pom.xml b/shadaev_anton_lab_3/parser-api/pom.xml
new file mode 100644
index 0000000..2a2905f
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.company
+ shadaev_anton_lab_3
+ 1.0-SNAPSHOT
+
+
+ parser-api
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
+
+ org.postgresql
+ postgresql
+ 42.3.1
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/ParserApiApplication.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/ParserApiApplication.java
new file mode 100644
index 0000000..c23febc
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/ParserApiApplication.java
@@ -0,0 +1,18 @@
+package com.company;
+
+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 ParserApiApplication {
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(ParserApiApplication.class, args);
+ }
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/controller/PageController.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/controller/PageController.java
new file mode 100644
index 0000000..f0a5631
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/controller/PageController.java
@@ -0,0 +1,75 @@
+package com.company.controller;
+
+import com.company.dto.PageDto;
+import com.company.exception.PageNotFoundException;
+import com.company.model.Page;
+import com.company.service.PageService;
+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;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/pages")
+public class PageController {
+ private final PageService pageService;
+
+ @Autowired
+ public PageController(PageService pageService) {
+ this.pageService = pageService;
+ }
+
+ @PostMapping
+ public ResponseEntity> save(@RequestBody PageDto pageDto) {
+ Page page;
+ page = pageService.save(pageDto);
+ return ResponseEntity.status(HttpStatus.CREATED).body(page);
+ }
+
+ @GetMapping
+ public List findAll() {
+ return pageService.findAll();
+ }
+
+ @GetMapping("/{uuid}")
+ public ResponseEntity findPageByUUID(@PathVariable UUID uuid) {
+ return pageService.findPageByUUID(uuid)
+ .map(app -> ResponseEntity.ok().body(app))
+ .orElse(ResponseEntity.notFound().build());
+ }
+
+ @PutMapping("/{uuid}")
+ public ResponseEntity> updatePageByUUID(@PathVariable UUID uuid, @RequestBody PageDto pageDto) {
+ Page page;
+ try {
+ if (pageService.findPageByUUID(uuid).isEmpty())
+ throw new PageNotFoundException("Page not found!");
+ page = pageService.updatePageByUUID(uuid, pageDto);
+ return ResponseEntity.ok().body(page);
+ } catch (PageNotFoundException e) {
+ return ResponseEntity.badRequest().body(e.getMessage());
+ }
+ }
+
+ @DeleteMapping("/{uuid}")
+ public ResponseEntity> deletePageByUUID(@PathVariable UUID uuid) {
+ UUID statusId;
+ try {
+ if (!pageService.findPageByUUID(uuid).isPresent())
+ throw new PageNotFoundException("Page not found!");
+ statusId = pageService.deletePageByUUID(uuid);
+ return ResponseEntity.ok().body(statusId);
+ } catch (PageNotFoundException e) {
+ return ResponseEntity.badRequest().body(e.getMessage());
+ }
+ }
+
+ @GetMapping("/find-job-info/{uuid}")
+ public ResponseEntity> findJobInfo(@PathVariable UUID uuid) {
+ return ResponseEntity.ok().body(pageService.findJobInfo(uuid));
+ }
+
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/dto/JobInfoDto.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/dto/JobInfoDto.java
new file mode 100644
index 0000000..f2e46f8
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/dto/JobInfoDto.java
@@ -0,0 +1,10 @@
+package com.company.dto;
+
+import lombok.Getter;
+
+public record JobInfoDto(@Getter String title, @Getter String description) {
+ public JobInfoDto(String title, String description) {
+ this.title = title;
+ this.description = description;
+ }
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/dto/PageDto.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/dto/PageDto.java
new file mode 100644
index 0000000..e680945
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/dto/PageDto.java
@@ -0,0 +1,16 @@
+package com.company.dto;
+
+import com.company.model.Page;
+import lombok.Getter;
+
+public record PageDto(@Getter String jobUrl) {
+ public PageDto(String jobUrl) {
+ this.jobUrl = jobUrl;
+ }
+
+ public static Page toPage(PageDto pageDto) {
+ return Page.builder()
+ .jobUrl(pageDto.getJobUrl())
+ .build();
+ }
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/exception/PageNotFoundException.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/exception/PageNotFoundException.java
new file mode 100644
index 0000000..c433aae
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/exception/PageNotFoundException.java
@@ -0,0 +1,10 @@
+package com.company.exception;
+
+public class PageNotFoundException extends Exception {
+ public PageNotFoundException() {
+ }
+
+ public PageNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/model/Page.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/model/Page.java
new file mode 100644
index 0000000..df1d19f
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/model/Page.java
@@ -0,0 +1,23 @@
+package com.company.model;
+
+import lombok.*;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.UUID;
+
+@Entity
+@Table(name = "pages")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class Page {
+ @Id
+ @GeneratedValue
+ private UUID id;
+ private String jobUrl;
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/repo/PageRepository.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/repo/PageRepository.java
new file mode 100644
index 0000000..6f1293c
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/repo/PageRepository.java
@@ -0,0 +1,9 @@
+package com.company.repo;
+
+import com.company.model.Page;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.UUID;
+
+public interface PageRepository extends JpaRepository {
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/service/PageService.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/service/PageService.java
new file mode 100644
index 0000000..49db48c
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/service/PageService.java
@@ -0,0 +1,18 @@
+package com.company.service;
+
+import com.company.dto.JobInfoDto;
+import com.company.dto.PageDto;
+import com.company.model.Page;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+public interface PageService {
+ Page save(PageDto pageDto);
+ List findAll();
+ Optional findPageByUUID(UUID uuid);
+ JobInfoDto findJobInfo(UUID jobUUID);
+ Page updatePageByUUID(UUID uuid, PageDto pageDto);
+ UUID deletePageByUUID(UUID uuid);
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/java/com/company/service/impl/PageService.java b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/service/impl/PageService.java
new file mode 100644
index 0000000..7b4ff25
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/java/com/company/service/impl/PageService.java
@@ -0,0 +1,66 @@
+package com.company.service.impl;
+
+import com.company.dto.JobInfoDto;
+import com.company.dto.PageDto;
+import com.company.model.Page;
+import com.company.repo.PageRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import javax.transaction.Transactional;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+@Service
+public class PageService implements com.company.service.PageService {
+ private final PageRepository pageRepository;
+ private final RestTemplate restTemplate;
+
+ @Autowired
+ public PageService(PageRepository pageRepository, RestTemplate restTemplate) {
+ this.pageRepository = pageRepository;
+ this.restTemplate = restTemplate;
+ }
+
+ @Override
+ @Transactional
+ public Page save(PageDto pageDto) {
+ return pageRepository.save(PageDto.toPage(pageDto));
+ }
+
+ @Override
+ @Transactional
+ public List findAll() {
+ return pageRepository.findAll();
+ }
+
+ @Override
+ @Transactional
+ public Optional findPageByUUID(UUID uuid) {
+ return Optional.ofNullable(pageRepository.findById(uuid).get());
+ }
+
+ @Override
+ @Transactional
+ public Page updatePageByUUID(UUID uuid, PageDto pageDto) {
+ Page page = pageRepository.findById(uuid).get();
+ page.setJobUrl(pageDto.getJobUrl());
+ return pageRepository.save(page);
+ }
+
+ @Override
+ @Transactional
+ public UUID deletePageByUUID(UUID uuid) {
+ pageRepository.deleteById(uuid);
+ return uuid;
+ }
+
+ @Override
+ @Transactional
+ public JobInfoDto findJobInfo(UUID jobUUID) {
+ String jobInfoUrl = "http://nginx/aggregator-api/jobs/" + jobUUID;
+ return restTemplate.getForObject(jobInfoUrl, JobInfoDto.class);
+ }
+}
diff --git a/shadaev_anton_lab_3/parser-api/src/main/resources/application.yaml b/shadaev_anton_lab_3/parser-api/src/main/resources/application.yaml
new file mode 100644
index 0000000..de7fe9f
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/src/main/resources/application.yaml
@@ -0,0 +1,13 @@
+server:
+ port: 8081
+
+spring:
+ jpa:
+ hibernate:
+ ddl-auto: update
+ show-sql: true
+ datasource:
+ driverClassName: org.postgresql.Driver
+ url: jdbc:postgresql://localhost:5433/aggregator_db
+ username: postgres
+ password: postgres
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/application.yaml b/shadaev_anton_lab_3/parser-api/target/classes/application.yaml
new file mode 100644
index 0000000..de7fe9f
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/target/classes/application.yaml
@@ -0,0 +1,13 @@
+server:
+ port: 8081
+
+spring:
+ jpa:
+ hibernate:
+ ddl-auto: update
+ show-sql: true
+ datasource:
+ driverClassName: org.postgresql.Driver
+ url: jdbc:postgresql://localhost:5433/aggregator_db
+ username: postgres
+ password: postgres
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/ParserApiApplication.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/ParserApiApplication.class
new file mode 100644
index 0000000..dd56447
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/ParserApiApplication.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/controller/PageController.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/controller/PageController.class
new file mode 100644
index 0000000..a26ed0e
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/controller/PageController.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/dto/JobInfoDto.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/dto/JobInfoDto.class
new file mode 100644
index 0000000..d1a5921
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/dto/JobInfoDto.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/dto/PageDto.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/dto/PageDto.class
new file mode 100644
index 0000000..bfaeb26
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/dto/PageDto.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/exception/PageNotFoundException.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/exception/PageNotFoundException.class
new file mode 100644
index 0000000..5587f87
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/exception/PageNotFoundException.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/model/Page.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/model/Page.class
new file mode 100644
index 0000000..765f591
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/model/Page.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/repo/PageRepository.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/repo/PageRepository.class
new file mode 100644
index 0000000..99179c5
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/repo/PageRepository.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/service/PageService.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/service/PageService.class
new file mode 100644
index 0000000..056dc0e
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/service/PageService.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/classes/com/company/service/impl/PageService.class b/shadaev_anton_lab_3/parser-api/target/classes/com/company/service/impl/PageService.class
new file mode 100644
index 0000000..2c71734
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/classes/com/company/service/impl/PageService.class differ
diff --git a/shadaev_anton_lab_3/parser-api/target/maven-archiver/pom.properties b/shadaev_anton_lab_3/parser-api/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..068d8b5
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/target/maven-archiver/pom.properties
@@ -0,0 +1,3 @@
+artifactId=parser-api
+groupId=com.company
+version=1.0-SNAPSHOT
diff --git a/shadaev_anton_lab_3/parser-api/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/shadaev_anton_lab_3/parser-api/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..d4d1849
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,10 @@
+com/company/service/impl/PageService.class
+com/company/dto/PageDto.class
+com/company/model/Page.class
+com/company/service/PageService.class
+com/company/repo/PageRepository.class
+com/company/model/Page$PageBuilder.class
+com/company/dto/JobInfoDto.class
+com/company/controller/PageController.class
+com/company/ParserApiApplication.class
+com/company/exception/PageNotFoundException.class
diff --git a/shadaev_anton_lab_3/parser-api/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/shadaev_anton_lab_3/parser-api/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..8b3205e
--- /dev/null
+++ b/shadaev_anton_lab_3/parser-api/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,9 @@
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/ParserApiApplication.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/controller/PageController.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/model/Page.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/service/PageService.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/exception/PageNotFoundException.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/service/impl/PageService.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/dto/PageDto.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/dto/JobInfoDto.java
+/Users/a-shdv/IdeaProjects/aggregator/parser-api/src/main/java/com/company/repo/PageRepository.java
diff --git a/shadaev_anton_lab_3/parser-api/target/parser-api-1.0-SNAPSHOT.jar b/shadaev_anton_lab_3/parser-api/target/parser-api-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..483ff13
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/parser-api-1.0-SNAPSHOT.jar differ
diff --git a/shadaev_anton_lab_3/parser-api/target/parser-api-1.0-SNAPSHOT.jar.original b/shadaev_anton_lab_3/parser-api/target/parser-api-1.0-SNAPSHOT.jar.original
new file mode 100644
index 0000000..3091ccb
Binary files /dev/null and b/shadaev_anton_lab_3/parser-api/target/parser-api-1.0-SNAPSHOT.jar.original differ
diff --git a/shadaev_anton_lab_3/pom.xml b/shadaev_anton_lab_3/pom.xml
new file mode 100644
index 0000000..2e01764
--- /dev/null
+++ b/shadaev_anton_lab_3/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.5
+
+
+
+ com.company
+ shadaev_anton_lab_3
+ 1.0-SNAPSHOT
+ pom
+
+ aggregator-api
+ parser-api
+
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/shadaev_anton_lab_3/screenshots/1.png b/shadaev_anton_lab_3/screenshots/1.png
new file mode 100644
index 0000000..c5db99d
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/1.png differ
diff --git a/shadaev_anton_lab_3/screenshots/2.png b/shadaev_anton_lab_3/screenshots/2.png
new file mode 100644
index 0000000..4d0b68c
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/2.png differ
diff --git a/shadaev_anton_lab_3/screenshots/3.png b/shadaev_anton_lab_3/screenshots/3.png
new file mode 100644
index 0000000..b845a81
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/3.png differ
diff --git a/shadaev_anton_lab_3/screenshots/4.png b/shadaev_anton_lab_3/screenshots/4.png
new file mode 100644
index 0000000..aedec70
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/4.png differ
diff --git a/shadaev_anton_lab_3/screenshots/5.png b/shadaev_anton_lab_3/screenshots/5.png
new file mode 100644
index 0000000..ae2fdd2
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/5.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img.png b/shadaev_anton_lab_3/screenshots/img.png
new file mode 100644
index 0000000..3cbbc5c
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_1.png b/shadaev_anton_lab_3/screenshots/img_1.png
new file mode 100644
index 0000000..5a84663
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_1.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_10.png b/shadaev_anton_lab_3/screenshots/img_10.png
new file mode 100644
index 0000000..868a35e
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_10.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_11.png b/shadaev_anton_lab_3/screenshots/img_11.png
new file mode 100644
index 0000000..9f833b3
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_11.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_12.png b/shadaev_anton_lab_3/screenshots/img_12.png
new file mode 100644
index 0000000..d209250
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_12.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_2.png b/shadaev_anton_lab_3/screenshots/img_2.png
new file mode 100644
index 0000000..7426573
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_2.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_3.png b/shadaev_anton_lab_3/screenshots/img_3.png
new file mode 100644
index 0000000..7a697f9
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_3.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_4.png b/shadaev_anton_lab_3/screenshots/img_4.png
new file mode 100644
index 0000000..931d394
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_4.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_5.png b/shadaev_anton_lab_3/screenshots/img_5.png
new file mode 100644
index 0000000..05a8d52
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_5.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_6.png b/shadaev_anton_lab_3/screenshots/img_6.png
new file mode 100644
index 0000000..ebd7e85
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_6.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_7.png b/shadaev_anton_lab_3/screenshots/img_7.png
new file mode 100644
index 0000000..cb94e23
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_7.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_8.png b/shadaev_anton_lab_3/screenshots/img_8.png
new file mode 100644
index 0000000..b3c1cd0
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_8.png differ
diff --git a/shadaev_anton_lab_3/screenshots/img_9.png b/shadaev_anton_lab_3/screenshots/img_9.png
new file mode 100644
index 0000000..868a35e
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/img_9.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img.png b/shadaev_anton_lab_3/screenshots/test/img.png
new file mode 100644
index 0000000..3cbbc5c
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_1.png b/shadaev_anton_lab_3/screenshots/test/img_1.png
new file mode 100644
index 0000000..5a84663
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_1.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_2.png b/shadaev_anton_lab_3/screenshots/test/img_2.png
new file mode 100644
index 0000000..7426573
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_2.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_3.png b/shadaev_anton_lab_3/screenshots/test/img_3.png
new file mode 100644
index 0000000..7a697f9
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_3.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_4.png b/shadaev_anton_lab_3/screenshots/test/img_4.png
new file mode 100644
index 0000000..931d394
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_4.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_5.png b/shadaev_anton_lab_3/screenshots/test/img_5.png
new file mode 100644
index 0000000..05a8d52
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_5.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_6.png b/shadaev_anton_lab_3/screenshots/test/img_6.png
new file mode 100644
index 0000000..ebd7e85
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_6.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_7.png b/shadaev_anton_lab_3/screenshots/test/img_7.png
new file mode 100644
index 0000000..cb94e23
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_7.png differ
diff --git a/shadaev_anton_lab_3/screenshots/test/img_8.png b/shadaev_anton_lab_3/screenshots/test/img_8.png
new file mode 100644
index 0000000..07eea7e
Binary files /dev/null and b/shadaev_anton_lab_3/screenshots/test/img_8.png differ