Skip to content
Open

Add #190

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 12 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,22 @@
# Тестовое задание для Java стажеров
Должен быть установлен maven apache.

Привет!
Открываем "Изменение системных переменных среды" на компьютере, внизу нажимаем "Переменные среды", дважды кликаем на Path сверху
и вписываем новый путь к папке bin в папке apache maven, а также новый путь к нашему jdk в папке Java/

Мы ищем стажера, который в перспективе станет Junior Java-разработчиком в нашей команде.
Чтобы понять, что мы подходим друг другу, предлагаем вам написать простое web-приложение. Такое задание поможет нам понять, что вы:
Запускаем среду разработки IntelliJ IDEA, нажимаем на вкладку File сверху->New->Project from version control->Git.

* можете понимать поставленную задачу;
* умеете находить необходимую техническую информацию для реализации решения;
* просто умеете кодить.
Далее нужно скопировать данную строчку https://github.com/walder86/Storage.git и вставить в поле URL, нажать test и, при успешном выполнении, нажать clone.

На задание у вас уйдет ориентировочно один-два вечера. Главное условие — решение должно быть написано с использованием платформы JVM. Библиотеки и фреймворки можно выбирать на свой вкус.
Перезагружаем копьютер (чтобы установился maven apache).

## Что нужно сделать
Далее снова заходим в IntelliJ IDEA и заходим в терминал в среде и вбиваем в терминал команду: mvn install.

Реализовать приложение для автоматизации учёта носков на складе магазина. Кладовщик должен иметь возможность:
После установки раскрываем справа вкладку Maven Projects, разворачиваем папку Lifecycle и жмём 2 раза на install.

* учесть приход и отпуск носков;
* узнать общее количество носков определенного цвета и состава в данный момент времени.
Если такой вкладки нет, то нажимаем ПКМ на файл pom.xml и выбираем add as maven project и ждём конца сборки.

Внешний интерфейс приложения представлен в виде HTTP API (REST, если хочется).
Должен быть запущен Docker, вбиваем в терминал/командную строку команды: docker run -d -p 3310:3306 vldmrvasiliev/socksbd

## Список URL HTTP-методов
Должен появистся и запуститься контейнер с БД, нужно подождать пока он полностью запустится (ждём надписи ready for connections).

### POST /api/socks/income

Регистрирует приход носков на склад.

Параметры запроса передаются в теле запроса в виде JSON-объекта со следующими атрибутами:

* color — цвет носков, строка (например, black, red, yellow);
* cottonPart — процентное содержание хлопка в составе носков, целое число от 0 до 100 (например, 30, 18, 42);
* quantity — количество пар носков, целое число больше 0.

Результаты:

* HTTP 200 — удалось добавить приход;
* HTTP 400 — параметры запроса отсутствуют или имеют некорректный формат;
* HTTP 500 — произошла ошибка, не зависящая от вызывающей стороны (например, база данных недоступна).

### POST /api/socks/outcome

Регистрирует отпуск носков со склада. Здесь параметры и результаты аналогичные, но общее количество носков указанного цвета и состава не увеличивается, а уменьшается.

### GET /api/socks

Возвращает общее количество носков на складе, соответствующих переданным в параметрах критериям запроса.

Параметры запроса передаются в URL:

* color — цвет носков, строка;
* operation — оператор сравнения значения количества хлопка в составе носков, одно значение из: moreThan, lessThan, equal;
* cottonPart — значение процента хлопка в составе носков из сравнения.

Результаты:

* HTTP 200 — запрос выполнен, результат в теле ответа в виде строкового представления целого числа;
* HTTP 400 — параметры запроса отсутствуют или имеют некорректный формат;
* HTTP 500 — произошла ошибка, не зависящая от вызывающей стороны (например, база данных недоступна).

Примеры запросов:

* /api/socks?color=red&operation=moreThan&cottonPart=90 — должен вернуть общее количество красных носков с долей хлопка более 90%;
* /api/socks?color=black&operation=lessThan?cottonPart=10 — должен вернуть общее количество черных носков с долей хлопка менее 10%.

Для хранения данных системы можно использовать любую реляционную базу данных. Схему БД желательно хранить в репозитории в любом удобном виде.

## Как это сделать

Мы ждем, что решение будет:

* написано на языке Java;
* standalone - состоять из одного выполняемого компонента верхнего уровня;
* headless - без UI;
* оформлено как форк к репозитарию и создан пул реквест.

Будет плюсом, если:

* приложение будет основано на Spring(Boot) Framework;
* для версионирования схемы базы данных будет использоваться Liquibase или Flyway;
* база данных будет подниматься рядом с приложением в докер-контейнере;
* приложение будет развернуто на любом облачном сервисе, например Heroku, и его API будет доступно для вызова.
Можно запускать проект и делать запросы, для этого можно использовать Postman
101 changes: 101 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?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.vasiliev.socks</groupId>
<artifactId>socks</artifactId>
<version>1.0-SNAPSHOT</version>

<name>socks Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.20.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.5.10</version>
</dependency>
</dependencies>

<build>
<finalName>socks</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
29 changes: 29 additions & 0 deletions src/main/java/ru/vasiliev/socks/Error/Exceptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ru.vasiliev.socks.Error;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class Exceptions extends RuntimeException {

@ExceptionHandler(SocksError.class)
protected ResponseEntity<SomeExceptions> value(){
return new ResponseEntity<>(new SomeExceptions("Error in the entered parameters", "Invalid value entered"),
HttpStatus.INTERNAL_SERVER_ERROR);

}


@Data
@AllArgsConstructor
private static class SomeExceptions{
private String Error;
private String message;
}

}
4 changes: 4 additions & 0 deletions src/main/java/ru/vasiliev/socks/Error/SocksError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ru.vasiliev.socks.Error;

public class SocksError extends RuntimeException {
}
47 changes: 47 additions & 0 deletions src/main/java/ru/vasiliev/socks/controller/SocksController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package ru.vasiliev.socks.controller;


import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import ru.vasiliev.socks.repository.Socks;
import ru.vasiliev.socks.services.SocksServices;

import javax.validation.Valid;

import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

@Slf4j
@RequiredArgsConstructor
@RestController
public class SocksController {

private final SocksServices socksServices;

@GetMapping(value = "/socks", produces = APPLICATION_JSON_VALUE)
public List<Socks> getSocks(@RequestParam("color") String color,
@RequestParam("cottonPath") Integer cottonPath,
@RequestParam("operation") String operation){
log.info("Get socks");
return socksServices.getSocks(color,cottonPath,operation);
}

@PostMapping(value = "/socks/income", produces = APPLICATION_JSON_VALUE)
public Socks income(@Valid @RequestBody Socks socks){
log.info("Income socks");
return socksServices.income(socks);
}



@PostMapping(value = "/socks/outcome", produces = APPLICATION_JSON_VALUE)
public void outcome(@Valid @RequestBody Socks socks) {
log.info("Outcome socks");
socksServices.outcome(socks);
}



}
38 changes: 38 additions & 0 deletions src/main/java/ru/vasiliev/socks/repository/Socks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ru.vasiliev.socks.repository;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Type;
import org.hibernate.validator.constraints.Range;

import javax.persistence.*;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(schema = "socks", name = "socks")
public class Socks {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;

@NotNull
private String color;

@Range(max = 100)
private Integer cottonPath;

@Min(value = 0)
private Integer quantity;
}
11 changes: 11 additions & 0 deletions src/main/java/ru/vasiliev/socks/repository/SocksRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ru.vasiliev.socks.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface SocksRepository extends CrudRepository<Socks,Integer> {
List<Socks> findAll();
}
Loading