Merge pull request 'lab 2 is ready' (#86) from volkov_rafael_lab_2 into main

Reviewed-on: http://student.git.athene.tech/Alexey/DAS_2023_1/pulls/86
This commit is contained in:
Alexey 2023-12-28 10:39:13 +04:00
commit f03ae3e342
30 changed files with 374 additions and 0 deletions

View File

@ -0,0 +1,84 @@
# Лабораторная работа №2 - Разработка простейшего распределенного приложения
Цель: изучение техники создания простого распределенного приложения.
Задачи:
- Согласно вышему варианту (выбирайте любой) разработать два приложения такие, что результат первого является исходными данными для второго.
- Изучить файлы сборки образов docker и разработать их для созданных приложений.
- Собрать файл docker-compose.yml для запуска приложений. Разобраться с монтированием каталогов из хост-системы.
- Правильно закоммитить результат без лишних файлов.
- Оформить pull request по правилам и отправить его на проверку.
# Описание заданий двух приложений
Вариант первого приложения(worker-1): 1 - Ищет в каталоге /var/data файл с наибольшим количеством строк и перекладывает его в /var/result/data.txt
Вариант второго приложения(worker-2): 0 - сохраняет произведение первого и последнего числа из файла /var/result/data.txt в /var/result/result.txt
<p>
<div>руктура проекта</div>
<img src="screens/img1.png" width="650" title="Cтруктура проекта">
</p>
# Работа программы
- Создано две директории: worker-1 и worker-2 для двух программ.
- Dockerfile для образов обоих программ.
<p>
<div>Worker-1 Dockerfile</div>
<img src="screens/img2.png" width="650" title="Worker-1 Dockerfile">
</p>
<p>
<div>Worker-2 Dockerfile</div>
<img src="screens/img3.png" width="650" title="Worker-2 Dockerfile">
</p>
- Содержимое в файлах в папке data
<p>
<img src="screens/img4.png" width="50" title="1">
</p>
<p>
<img src="screens/img5.png" width="50" title="2">
</p>
<p>
<img src="screens/img6.png" width="50" title="3">
</p>
- Описание docker-compose: запускает контейнеры, реализует build для создания образов на основе dockerfile и у второго контейнера описавыется зависимость depends_on от первого контейнера, чтобы сначала запустился первый контейнер, а за ним запустился второй. Также описываются volumes, для монтирование папок data и result в контейнеры.
<p>
<div>docker-compose</div>
<img src="screens/img7.png" width="650" title="docker-compose">
</p>
<p>
<div>Сборка и запуска контейнеров</div>
<img src="screens/img8.png" width="650" title="Сборка и запуска контейнеров">
</p>
<p>
<div>Docker Desktop контейнеры и образы</div>
<img src="screens/img9.png" width="650" title="Docker Desktop контейнеры и образы">
</p>
<p>
<img src="screens/img10.png" width="650" title="Проверка в Docker Desktop контейнеров и образов">
</p>
<p>
<div>Консоль первого воркера</div>
<img src="screens/img11.png" width="650" title="Консоль первого воркера">
</p>
<p>
<div>Консоль второго воркера</div>
<img src="screens/img12.png" width="650" title="Консоль второго воркера">
</p>
<p>
<div>Результат работы контейнера, папка result два файла data.txt и result.txt</div>
<img src="screens/img13.png" width="150" title="Результат работы контейнера, папка result два файла data.txt и result.txt">
</p>
<p>
<div>Содержимое data.txt</div>
<img src="screens/img14.png" width="50" title="Содержимое data.txt">
</p>
<p>
<div>Содержимое result.txt</div>
<img src="screens/img15.png" width="150" title="Содержимое result.txt">
</p>
# Видео
Видео с разбором лабораторной работы - https://drive.google.com/file/d/1-sLDH9PPFeHlEqzfLtcerbGs8sCALaxe/view?usp=sharing

View File

@ -0,0 +1,3 @@
11 12 13
21 22
31 34

View File

@ -0,0 +1,2 @@
45
23 78

View File

@ -0,0 +1,4 @@
52 345
23 345
23 67
23 20

View File

@ -0,0 +1,17 @@
services:
worker-1:
build:
context: /worker-1
dockerfile: Dockerfile
volumes:
- D:\RVIP\volkov_rafael_lab_2\data:/var/data
- D:\RVIP\volkov_rafael_lab_2\result:/var/result
worker-2:
build:
context: /worker-2
dockerfile: Dockerfile
volumes:
- D:\RVIP\volkov_rafael_lab_2\data:/var/data
- D:\RVIP\volkov_rafael_lab_2\result:/var/result
depends_on:
- worker-1

View File

@ -0,0 +1,4 @@
52 345
23 345
23 67
23 20

View File

@ -0,0 +1 @@
1040

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

29
volkov_rafael_lab_2/worker-1/.gitignore vendored Normal file
View File

@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,18 @@
# Используем образ с Java
FROM openjdk:21
# Создаем директории для данных и результата внутри контейнера
RUN mkdir /var/data
RUN mkdir /var/result
# Создаем директорию приложения внутри контейнера
WORKDIR /app
# Копируем исходные файлы вашего Java-приложения внутрь контейнера
COPY src /app/src
# Компилируем Java-код
RUN javac /app/src/FileCopyMaxLines.java
# Запускаем Java-приложение
CMD ["java", "-cp", "/app/src", "FileCopyMaxLines"]

View File

@ -0,0 +1,58 @@
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class FileCopyMaxLines {
public static void main(String[] args) {
String sourceDir = "/var/data";
String destinationFile = "/var/result/data.txt";
try {
// Создаем файл, если он не существует
File file = new File(destinationFile);
if (!file.exists()) {
if (!file.createNewFile()) {
System.err.println("Ошибка при создании файла.");
return;
}
}
// Читаем содержимое каталога
File[] files = new File(sourceDir).listFiles();
if (files != null) {
int maxLines = 0;
String maxLinesFile = null;
// Ищем файл с наибольшим количеством строк
for (File f : files) {
if (!f.isDirectory()) {
String filePath = f.getAbsolutePath();
int lines = countLines(filePath);
if (lines > maxLines) {
maxLines = lines;
maxLinesFile = filePath;
}
}
}
if (maxLinesFile != null) {
// Копируем содержимое файла с наибольшим количеством строк в целевой файл
Path sourcePath = Paths.get(maxLinesFile);
byte[] data = Files.readAllBytes(sourcePath);
Files.write(Paths.get(destinationFile), data, StandardOpenOption.CREATE);
System.out.printf("Файл %s с наибольшим количеством строк (%d) скопирован в %s\n", maxLinesFile, maxLines, destinationFile);
} else {
System.out.println("Не удалось найти файлы в каталоге /var/data.");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Метод для подсчета количества строк в файле
private static int countLines(String filePath) throws IOException {
byte[] data = Files.readAllBytes(Paths.get(filePath));
return new String(data).split("\r\n|\r|\n").length;
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="SonarLintModuleSettings">
<option name="uniqueId" value="a8341579-2851-407d-ad6a-b2b7f768ee65" />
</component>
</module>

29
volkov_rafael_lab_2/worker-2/.gitignore vendored Normal file
View File

@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,18 @@
# Используем образ с Java
FROM openjdk:21
# Создаем директории для данных и результата внутри контейнера
RUN mkdir /var/data
RUN mkdir /var/result
# Создаем директорию приложения внутри контейнера
WORKDIR /app
# Копируем исходные файлы вашего Java-приложения внутрь контейнера
COPY src /app/src
# Компилируем Java-код
RUN javac /app/src/MultiplyFirstLast.java
# Запускаем Java-приложение
CMD ["java", "-cp", "/app/src", "MultiplyFirstLast"]

View File

@ -0,0 +1,79 @@
import java.io.*;
import java.util.Scanner;
import java.nio.file.Files;
import java.nio.file.Paths;
public class MultiplyFirstLast {
public static void main(String[] args) {
String dataFilePath = "/var/result/data.txt";
String resultFilePath = "/var/result/result.txt";
try {
// Создаем файл, если он не существует
File resultFile = new File(resultFilePath);
if (!resultFile.exists()) {
if (!resultFile.createNewFile()) {
System.err.println("Ошибка при создании файла.");
return;
}
}
// Проверяем существование файла data.txt
File dataFile = new File(dataFilePath);
if (!dataFile.exists()) {
System.err.println("Файл data.txt не существует. Пожалуйста, выполните первую программу перед запуском второй.");
return;
}
// Читаем содержимое файла data.txt
StringBuilder content = new StringBuilder();
try (Scanner scanner = new Scanner(dataFile)) {
while (scanner.hasNextLine()) {
content.append(scanner.nextLine()).append("\n");
}
}
String[] lines = content.toString().split("\\r?\\n");
int first = 0;
int last = 0;
boolean firstFound = false;
boolean numbersFound = false;
for (String line : lines) {
String[] numbers = line.split("\\s+");
if (numbers.length > 0) {
// Преобразуем первое и последнее число в числа с плавающей точкой
if (!firstFound) {
first = Integer.parseInt(numbers[0]);
firstFound = true;
}
last = Integer.parseInt(numbers[numbers.length - 1]);
numbersFound = true;
}
}
if (!numbersFound) {
System.err.printf("Не найдены числа в файле %s%n", dataFilePath);
return;
}
int result = first * last;
String outputContent = String.valueOf(result);
// Записываем результат в файл result.txt
try (FileWriter writer = new FileWriter(resultFilePath)) {
writer.write(outputContent);
}
System.out.printf("Результат (%d) сохранен в файл %s%n", result, resultFilePath);
// Читаем и выводим результат из файла result.txt
String resultContent = new String(Files.readAllBytes(Paths.get(resultFilePath)));
System.out.println("Результат, лежащий в файле result - " + resultContent);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="SonarLintModuleSettings">
<option name="uniqueId" value="ca0d01ae-0c7f-4c2c-b85f-2442b28d754e" />
</component>
</module>