forked from Alexey/DAS_2024_1
Merge pull request 'borschevskaya_anna_lab_2 is ready' (#25) from borschevskaya_anna_lab_2 into main
Reviewed-on: Alexey/DAS_2024_1#25
This commit is contained in:
commit
9456d4fe01
38
borschevskaya_anna_lab_2/.gitignore
vendored
Normal file
38
borschevskaya_anna_lab_2/.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
43
borschevskaya_anna_lab_2/README.md
Normal file
43
borschevskaya_anna_lab_2/README.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Отчет. Лабораторная работа 2
|
||||||
|
|
||||||
|
В рамках лабораторной работы №2 были написаны два сервиса, работающих с текстовыми файлами.
|
||||||
|
Для первого сервиса был выбран вариант задания №5:
|
||||||
|
```
|
||||||
|
Ищет в каталоге /var/data файл с самым коротким названием и перекладывает его в /var/result/data.txt.
|
||||||
|
```
|
||||||
|
А для второго - №2:
|
||||||
|
```
|
||||||
|
Ищет наименьшее число из файла /var/data/data.txt и сохраняет его третью степень в /var/result/result.txt.
|
||||||
|
```
|
||||||
|
## Описание
|
||||||
|
Сначала сервис first перемещает данные из файла с самым коротким названием, находящегося в указанной примонтированной директории, в выходную папку.
|
||||||
|
Доступ к выходной папке имеет второй сервис, который выводит наименьшее число из помещенного первым сервисом файла
|
||||||
|
в третьей степени в выходной файл.
|
||||||
|
Выходной файл расположен в примонтированной директории и доступен на машине, где запускаются сервисы.
|
||||||
|
|
||||||
|
В Dockerfile используется многоэтапная сборка с использованием нескольких базовых образов на каждом этапе.
|
||||||
|
Описание значения каждой строки есть в Dockerfile в сервисе first.
|
||||||
|
|
||||||
|
В файле docker-compose.yml приведено описание новых строк, связанных с подключением примонтированных томов.
|
||||||
|
Стоит отметить, что для "общения" сервисов используется общий том common, который монтируется в контейнер по пути /var/result. Это позволяет сохранять результаты
|
||||||
|
работы первого сервиса для использования вторым сервисом.
|
||||||
|
## Как запустить
|
||||||
|
Для того, чтобы запустить сервисы, необходимо выполнить следующие действия:
|
||||||
|
1. Установить и запустить Docker Engine или Docker Desktop
|
||||||
|
2. Через консоль перейти в папку, в которой расположен файл docker-compose.yml
|
||||||
|
3. Выполнить команду:
|
||||||
|
```
|
||||||
|
docker compose up --build
|
||||||
|
```
|
||||||
|
В случае успешного запуска всех контейнеров в консоли будет выведено следующее сообщение:
|
||||||
|
```
|
||||||
|
✔ Network borschevskaya_anna_lab_2_default Created 0.1s
|
||||||
|
✔ Container borschevskaya_anna_lab_2-first-1 Created 0.1s
|
||||||
|
✔ Container borschevskaya_anna_lab_2-second-1 Created 0.1s
|
||||||
|
Attaching to borschevskaya_anna_lab_2-first-1, borschevskaya_anna_lab_2-second-1
|
||||||
|
```
|
||||||
|
Далее, в консоль каждого сервиса будут выведены сообщения о том, как прошла обработка файлов.
|
||||||
|
В случае отсутствия заданных значений переменных окружения INPUT_PATH и OUTPUT_PATH и
|
||||||
|
в иных исключительных ситуация будет выведена информация об этом.
|
||||||
|
## Видео-отчет
|
||||||
|
Работоспособность лабораторной работы можно оценить в следующем [видео](https://disk.yandex.ru/i/LFxdyRUFQDwXEQ).
|
22
borschevskaya_anna_lab_2/docker-compose.yml
Normal file
22
borschevskaya_anna_lab_2/docker-compose.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
services:
|
||||||
|
first:
|
||||||
|
build: ./first # директория, в которой нужно искать Dockerfile для сборки первого сервиса
|
||||||
|
environment:
|
||||||
|
INPUT_PATH: /var/data/ # директория с входными данными для обработки файлов
|
||||||
|
OUTPUT_PATH: /var/result/ # директория с выходными данными обработки
|
||||||
|
volumes:
|
||||||
|
- ./volumes/input:/var/data # монтируется локальная папка с входными данными в папку внутри контейнера
|
||||||
|
- common:/var/result # монтируется общий для двух сервисов том, в который first сложит результаты обработки по варианту
|
||||||
|
second:
|
||||||
|
build: ./second # директория, в которой нужно искать Dockerfile для сборки второго сервиса
|
||||||
|
depends_on: # сервис second зависит от сервиса first и будет запущен после него
|
||||||
|
- first
|
||||||
|
environment:
|
||||||
|
INPUT_PATH: /var/result/
|
||||||
|
OUTPUT_PATH: /var/data/
|
||||||
|
volumes:
|
||||||
|
- ./volumes/output:/var/data
|
||||||
|
- common:/var/result # монтируется общий для двух сервисов том, из которого second получит результаты обработки first сервиса и выполнит свою логику
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
common:
|
25
borschevskaya_anna_lab_2/first/Dockerfile
Normal file
25
borschevskaya_anna_lab_2/first/Dockerfile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Используем образ Maven для сборки
|
||||||
|
FROM maven:3.8-eclipse-temurin-21-alpine AS build
|
||||||
|
|
||||||
|
# Устанавливаем рабочую директорию
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Копируем только pom.xml и загружаем зависимости
|
||||||
|
# Так зависимости закэшируются в Docker при изменении кода закэшированные слои с зависимостями будут подгружаться быстрее
|
||||||
|
COPY pom.xml .
|
||||||
|
RUN mvn dependency:go-offline
|
||||||
|
|
||||||
|
# Копируем остальные исходные файлы
|
||||||
|
COPY src ./src
|
||||||
|
|
||||||
|
# Собираем весь проект
|
||||||
|
RUN mvn clean package -DskipTests
|
||||||
|
|
||||||
|
# Используем официальный образ JDK для запуска собранного jar-файла
|
||||||
|
FROM eclipse-temurin:21-jdk-alpine
|
||||||
|
|
||||||
|
# Копируем jar-файл из предыдущего этапа
|
||||||
|
COPY --from=build /app/target/*.jar /app.jar
|
||||||
|
|
||||||
|
# Указываем команду для запуска приложения
|
||||||
|
CMD ["java", "-jar", "app.jar"]
|
37
borschevskaya_anna_lab_2/first/pom.xml
Normal file
37
borschevskaya_anna_lab_2/first/pom.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>ru.first</groupId>
|
||||||
|
<artifactId>first</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<!-- Build an executable JAR -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>lib/</classpathPrefix>
|
||||||
|
<mainClass>ru.first.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,50 @@
|
|||||||
|
package ru.first;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static final String INPUT_PATH = System.getenv("INPUT_PATH");
|
||||||
|
public static final String OUTPUT_PATH = System.getenv("OUTPUT_PATH");
|
||||||
|
public static final String RESULT_FILE_NAME = "data.txt";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
if (isNull(INPUT_PATH) || INPUT_PATH.isEmpty() || isNull(OUTPUT_PATH) || OUTPUT_PATH.isEmpty()) {
|
||||||
|
System.out.printf("Отсутствуют переменные окружения INPUT_PATH = '%s' или OUTPUT_PATH = '%s'%n",
|
||||||
|
INPUT_PATH, OUTPUT_PATH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var inputPathDir = Path.of(INPUT_PATH);
|
||||||
|
if (!Files.exists(inputPathDir)) {
|
||||||
|
Files.createDirectory(inputPathDir);
|
||||||
|
}
|
||||||
|
var inputDirectory = new File(INPUT_PATH);
|
||||||
|
var allDirFiles = inputDirectory.listFiles();
|
||||||
|
if (isNull(allDirFiles) || allDirFiles.length == 0) {
|
||||||
|
System.out.println("Директория пуста");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var dirFiles = Arrays.stream(allDirFiles).filter(File::isFile).toList();
|
||||||
|
if (dirFiles.isEmpty()) {
|
||||||
|
System.out.println("В указанной директории нет подходящих для обработки файлов");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shortestName = dirFiles.stream().min(Comparator.comparing(file -> file.getName().length())).get();
|
||||||
|
|
||||||
|
var outputPathDir = Path.of(OUTPUT_PATH);
|
||||||
|
if (!Files.exists(outputPathDir)) {
|
||||||
|
Files.createDirectory(outputPathDir);
|
||||||
|
}
|
||||||
|
var resultFilePath = Path.of(OUTPUT_PATH + File.separator + RESULT_FILE_NAME);
|
||||||
|
Files.move(Path.of(INPUT_PATH + File.separator + shortestName.getName()), resultFilePath, REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
}
|
16
borschevskaya_anna_lab_2/second/Dockerfile
Normal file
16
borschevskaya_anna_lab_2/second/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
FROM maven:3.8-eclipse-temurin-21-alpine AS build
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY pom.xml .
|
||||||
|
RUN mvn dependency:go-offline
|
||||||
|
|
||||||
|
COPY src ./src
|
||||||
|
|
||||||
|
RUN mvn clean package -DskipTests
|
||||||
|
|
||||||
|
FROM eclipse-temurin:21-jdk-alpine
|
||||||
|
|
||||||
|
COPY --from=build /app/target/*.jar /app.jar
|
||||||
|
|
||||||
|
CMD ["java", "-jar", "app.jar"]
|
36
borschevskaya_anna_lab_2/second/pom.xml
Normal file
36
borschevskaya_anna_lab_2/second/pom.xml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>ru.second</groupId>
|
||||||
|
<artifactId>second</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>lib/</classpathPrefix>
|
||||||
|
<mainClass>ru.second.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,51 @@
|
|||||||
|
package ru.second;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static final String INPUT_PATH = System.getenv("INPUT_PATH");
|
||||||
|
public static final String INPUT_FILE_NAME = "data.txt";
|
||||||
|
|
||||||
|
public static final String OUTPUT_PATH = System.getenv("OUTPUT_PATH");
|
||||||
|
public static final String RESULT_FILE_NAME = "result.txt";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
if (isNull(INPUT_PATH) || INPUT_PATH.isEmpty() || isNull(OUTPUT_PATH) || OUTPUT_PATH.isEmpty()) {
|
||||||
|
System.out.printf("Отсутствуют переменные окружения INPUT_PATH = '%s' или OUTPUT_PATH = '%s'%n",
|
||||||
|
INPUT_PATH, OUTPUT_PATH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var inputFile = new File(INPUT_PATH + File.separator + INPUT_FILE_NAME);
|
||||||
|
if (!inputFile.exists()) {
|
||||||
|
System.out.println("Входной файл не существует");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (var stream = Files.lines(inputFile.toPath());
|
||||||
|
var writer = new FileWriter(OUTPUT_PATH + File.separator + RESULT_FILE_NAME);
|
||||||
|
) {
|
||||||
|
var min = stream.map(Main::parseInt).reduce(Integer::min);
|
||||||
|
if (min.isEmpty()) {
|
||||||
|
System.out.println("Не найдено минимальное значение среди строк файла");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var minValue = Math.pow(min.get(), 3);
|
||||||
|
System.out.printf("Get min value = '%d'%n", min.get());
|
||||||
|
writer.append(Double.toString(minValue));
|
||||||
|
System.out.printf("To file %s was written value %f%n", RESULT_FILE_NAME, minValue);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.out.println(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Integer parseInt(String line) {
|
||||||
|
line = line.replace("\\n", "");
|
||||||
|
return Integer.parseInt(line);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user