diff --git a/afanasev_dmitry_lab_2/.gitignore b/afanasev_dmitry_lab_2/.gitignore new file mode 100644 index 0000000..92626de --- /dev/null +++ b/afanasev_dmitry_lab_2/.gitignore @@ -0,0 +1,92 @@ +data/ + +############################## +## Java +############################## +.mtj.tmp/ +*.class +*.jar +*.war +*.ear +*.nar +hs_err_pid* +replay_pid* + +############################## +## Maven +############################## +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +pom.xml.bak +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +############################## +## Gradle +############################## +bin/ +build/ +.gradle +.gradletasknamecache +gradle-app.setting +!gradle-wrapper.jar + +############################## +## IntelliJ +############################## +out/ +.idea/ +.idea_modules/ +*.iml +*.ipr +*.iws + +############################## +## Eclipse +############################## +.settings/ +bin/ +tmp/ +.metadata +.classpath +.project +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath +.factorypath + +############################## +## NetBeans +############################## +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml + +############################## +## Visual Studio Code +############################## +.vscode/ +.code-workspace + +############################## +## OS X +############################## +.DS_Store + +############################## +## Miscellaneous +############################## +*.log \ No newline at end of file diff --git a/afanasev_dmitry_lab_2/README.md b/afanasev_dmitry_lab_2/README.md new file mode 100644 index 0000000..1cea977 --- /dev/null +++ b/afanasev_dmitry_lab_2/README.md @@ -0,0 +1,38 @@ +# Лабораторная работа 2 + +## Описание +Данная лабораторная работа предназначена для настройки 2 сервисов (простейшего распределенного приложения) с использованием Docker Compose. **FirstService** — ищет в каталоге /var/data файл с наибольшим количеством строк и перекладывает его в /var/result/data.txt. **SecondService** — ищет наименьшее число из файла /var/result/data.txt (сгенерирован 1-ым сервисом) и сохраняет его третью степень в /var/result/result.txt. + +## Запуск проекта +1. Убедитесь, что у вас установлены **Docker** и **Docker Compose**. +2. Клонируйте репозиторий с данным проектом. +3. В командной строке перейдите в директорию с файлом `docker-compose.yml`. +4. Запустите команды: + ```bash + docker-compose up -d + ``` + Эта команда запустит контейнеры в фоновом режиме. +5. После запуска: + - Посмотреть логи первого сервиса о том, что файл создался успешно. + - Посмотреть логи второго сервиса о том, что он обработал созданный первым сервисом файл. + +## Конфигурация +В файле `docker-compose.yml` определены следующие сервисы: +- **FirstService**: + - Создает образ из директории `firstService`. + - Использует локальную директорию `/var/data` и общую `/var/result` для хранения данных. +- **SecondService**: + - Создает образ из директории `secondService`. + - Использует общую `/var/result` директорию для хранения данных. + - Запускается после первого сервиса. + +## Остановка проекта +Для остановки контейнеров запустите: +```bash +docker-compose down +``` +Это завершит работу всех контейнеров. + +## Примечания +- При необходимости можно изменить директорию с данными или другие параметры, отредактировав файл `docker-compose.yml`. +- Ссылка на демонстрацию работы программы: https://vk.com/video215756667_456239452?list=ln-rAyQWJj8q7ezqCaZzL \ No newline at end of file diff --git a/afanasev_dmitry_lab_2/docker-compose.yml b/afanasev_dmitry_lab_2/docker-compose.yml new file mode 100644 index 0000000..1eab81c --- /dev/null +++ b/afanasev_dmitry_lab_2/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.9' + +services: + first-service: + build: ./firstService # Путь к докер-файлу 1 приложения + volumes: + - D:/java/DAS_2024_1/afanasev_dmitry_lab_2/data:/var/data # Монтируем директорию с данными + - common-volume:/var/result # Монтируем общую директорию (нужна 2-му сервису для работы) + second-service: + build: ./secondService # Путь к докер-файлу 2 приложения + volumes: + - common-volume:/var/result # Монтируем общую директорию (нужна 2-му сервису для работы) + depends_on: + - first-service # Запуск после первого сервиса + +volumes: # Именованные тома + common-volume: # Общий для 2-ух сервисов \ No newline at end of file diff --git a/afanasev_dmitry_lab_2/firstService/Dockerfile b/afanasev_dmitry_lab_2/firstService/Dockerfile new file mode 100644 index 0000000..600a6aa --- /dev/null +++ b/afanasev_dmitry_lab_2/firstService/Dockerfile @@ -0,0 +1,17 @@ +# Используем образ с Java 17 +FROM bellsoft/liberica-openjdk-alpine:17.0.8 + +# Создаем директорию для исходных файлов +RUN mkdir /var/data + +# Создаем директорию для приложения +WORKDIR /app + +# Копируем файлы приложения в контейнер +COPY src /app/src + +# Компилируем приложение +RUN javac /app/src/FirstService.java + +# Определяем команду для запуска приложения +CMD ["java", "-cp", "/app/src", "FirstService"] diff --git a/afanasev_dmitry_lab_2/firstService/src/FirstService.java b/afanasev_dmitry_lab_2/firstService/src/FirstService.java new file mode 100644 index 0000000..c1db67a --- /dev/null +++ b/afanasev_dmitry_lab_2/firstService/src/FirstService.java @@ -0,0 +1,52 @@ +import java.io.*; +import java.nio.file.*; + +public class FirstService { + // 1. Ищет в каталоге /var/data файл с наибольшим количеством строк и перекладывает его в /var/result/data.txt. + + public static void main(String[] args) { + Path sourceDir = Paths.get("/var/data"); + Path destinationDir = Paths.get("/var/result"); + Path destinationFile = destinationDir.resolve("data.txt"); + Path largestFile = null; + long maxLineCount = 0; + + try { + // существует ли каталог /var/result, если нет, создаем + if (!Files.exists(destinationDir)) { + Files.createDirectories(destinationDir); + } else { + // иначе чистим + try (DirectoryStream stream = Files.newDirectoryStream(destinationDir)) { + for (Path file : stream) { + Files.delete(file); + } + } + } + + // поиск файла с наибольшим количеством строк в каталоге /var/data + try (DirectoryStream stream = Files.newDirectoryStream(sourceDir)) { + for (Path file : stream) { + if (Files.isRegularFile(file)) { + long lineCount = Files.lines(file).count(); + if (lineCount > maxLineCount) { + maxLineCount = lineCount; + largestFile = file; + } + } + } + } + + // копируем файл с наибольшим количеством строк в /var/result/data.txt + if (largestFile != null) { + Files.copy(largestFile, destinationFile, StandardCopyOption.REPLACE_EXISTING); + System.out.println("Файл " + largestFile + " скопирован в " + destinationFile); + } else { + System.out.println("В каталоге " + sourceDir + " нет файлов."); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/afanasev_dmitry_lab_2/secondService/Dockerfile b/afanasev_dmitry_lab_2/secondService/Dockerfile new file mode 100644 index 0000000..2757904 --- /dev/null +++ b/afanasev_dmitry_lab_2/secondService/Dockerfile @@ -0,0 +1,17 @@ +# Используем образ с Java 17 +FROM bellsoft/liberica-openjdk-alpine:17.0.8 + +# Создаем директорию для исходных файлов +RUN mkdir /var/data + +# Создаем директорию для приложения +WORKDIR /app + +# Копируем файлы приложения в контейнер +COPY src /app/src + +# Компилируем приложение +RUN javac /app/src/SecondService.java + +# Определяем команду для запуска приложения +CMD ["java", "-cp", "/app/src", "SecondService"] diff --git a/afanasev_dmitry_lab_2/secondService/src/SecondService.java b/afanasev_dmitry_lab_2/secondService/src/SecondService.java new file mode 100644 index 0000000..9d5cfad --- /dev/null +++ b/afanasev_dmitry_lab_2/secondService/src/SecondService.java @@ -0,0 +1,51 @@ +import java.io.*; +import java.nio.file.*; +import java.util.*; + +public class SecondService { + // 2. Ищет наименьшее число из файла /var/result/data.txt и сохраняет его третью степень в /var/result/result.txt. + + public static void main(String[] args) { + Path sourceFile = Paths.get("/var/result/data.txt"); + Path destinationDir = Paths.get("/var/result"); + Path destinationFile = destinationDir.resolve("result.txt"); + + try { + // создание /var/result, если не существует + if (!Files.exists(destinationDir)) { + Files.createDirectories(destinationDir); + } + + // читаем числа из файла и находим наименьшее + List numbers = new ArrayList<>(); + try (BufferedReader reader = Files.newBufferedReader(sourceFile)) { + String line; + while ((line = reader.readLine()) != null) { + try { + numbers.add(Integer.parseInt(line.trim())); + } catch (NumberFormatException e) { + System.out.println("Некорректная строка: " + line); + } + } + } + + if (!numbers.isEmpty()) { + // находим наименьшее число и его третью степень + int minNumber = Collections.min(numbers); + int minNumberCubed = (int) Math.pow(minNumber, 3); + + // записываем результат в /var/result/result.txt + try (BufferedWriter writer = Files.newBufferedWriter(destinationFile)) { + writer.write(String.valueOf(minNumberCubed)); + System.out.println("Третья степень наименьшего числа - " + minNumber + " (" + minNumberCubed + + ") сохранена в " + destinationFile); + } + } else { + System.out.println("Файл " + sourceFile + " пуст или не содержит чисел."); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } +}