Skip to content

Commit 8420e1d

Browse files
authored
Merge pull request #3 from walder86/add-item-requests-and-gateway
add-item-requests-and-gateway. Добавить запросы на вещи. Выделить валидацию в отдельный сервис. Написать тесты.
2 parents dc386cf + dcbf235 commit 8420e1d

File tree

92 files changed

+6365
-151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+6365
-151
lines changed

docker-compose.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
services:
2+
gateway:
3+
build: gateway
4+
image: shareit-gateway
5+
container_name: shareit-gateway
6+
ports:
7+
- "8080:8080"
8+
depends_on:
9+
- server
10+
environment:
11+
- SHAREIT_SERVER_URL=http://server:9090
12+
13+
server:
14+
build: server
15+
image: shareit-server
16+
container_name: shareit-server
17+
ports:
18+
- "9090:9090"
19+
depends_on:
20+
- db
21+
environment:
22+
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/shareit
23+
- SPRING_DATASOURCE_USERNAME=shareit
24+
- SPRING_DATASOURCE_PASSWORD=shareit
25+
26+
db:
27+
image: postgres:16.1
28+
container_name: postgres
29+
ports:
30+
- "6541:5432"
31+
environment:
32+
- POSTGRES_PASSWORD=shareit
33+
- POSTGRES_USER=shareit
34+
- POSTGRES_DB=shareit
35+
healthcheck:
36+
test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER
37+
timeout: 5s
38+
interval: 5s
39+
retries: 10

gateway/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FROM eclipse-temurin:21-jre-jammy
2+
VOLUME /tmp
3+
ARG JAR_FILE=target/*.jar
4+
COPY ${JAR_FILE} app.jar
5+
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar"]

gateway/pom.xml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>ru.practicum</groupId>
7+
<artifactId>shareit</artifactId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>shareit-gateway</artifactId>
12+
<version>0.0.1-SNAPSHOT</version>
13+
14+
<name>ShareIt Gateway</name>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>org.springframework.boot</groupId>
19+
<artifactId>spring-boot-starter-web</artifactId>
20+
</dependency>
21+
22+
<dependency>
23+
<groupId>org.springframework.boot</groupId>
24+
<artifactId>spring-boot-starter-validation</artifactId>
25+
</dependency>
26+
27+
<dependency>
28+
<groupId>org.springframework.boot</groupId>
29+
<artifactId>spring-boot-starter-actuator</artifactId>
30+
</dependency>
31+
32+
<dependency>
33+
<groupId>org.hibernate.validator</groupId>
34+
<artifactId>hibernate-validator</artifactId>
35+
</dependency>
36+
37+
<dependency>
38+
<groupId>org.apache.httpcomponents.client5</groupId>
39+
<artifactId>httpclient5</artifactId>
40+
</dependency>
41+
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-configuration-processor</artifactId>
45+
<optional>true</optional>
46+
</dependency>
47+
48+
<dependency>
49+
<groupId>org.projectlombok</groupId>
50+
<artifactId>lombok</artifactId>
51+
<optional>true</optional>
52+
</dependency>
53+
54+
<dependency>
55+
<groupId>org.springframework.boot</groupId>
56+
<artifactId>spring-boot-starter-test</artifactId>
57+
<scope>test</scope>
58+
</dependency>
59+
</dependencies>
60+
61+
<build>
62+
<plugins>
63+
<plugin>
64+
<groupId>org.springframework.boot</groupId>
65+
<artifactId>spring-boot-maven-plugin</artifactId>
66+
</plugin>
67+
</plugins>
68+
</build>
69+
70+
</project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package ru.practicum.shareit;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class ShareItGateway {
8+
public static void main(String[] args) {
9+
SpringApplication.run(ShareItGateway.class, args);
10+
}
11+
12+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package ru.practicum.shareit.booking;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.beans.factory.annotation.Value;
5+
import org.springframework.boot.web.client.RestTemplateBuilder;
6+
import org.springframework.http.ResponseEntity;
7+
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
8+
import org.springframework.stereotype.Service;
9+
import org.springframework.web.util.DefaultUriBuilderFactory;
10+
import ru.practicum.shareit.booking.dto.BookingDtoRequest;
11+
import ru.practicum.shareit.booking.dto.BookingState;
12+
import ru.practicum.shareit.client.BaseClient;
13+
import ru.practicum.shareit.exception.StateException;
14+
import ru.practicum.shareit.exception.ValidationException;
15+
16+
import java.time.LocalDateTime;
17+
import java.util.Map;
18+
19+
@Service
20+
public class BookingClient extends BaseClient {
21+
private static final String API_PREFIX = "/bookings";
22+
23+
@Autowired
24+
public BookingClient(@Value("${shareit-server.url}") String url, RestTemplateBuilder builder) {
25+
super(
26+
builder
27+
.uriTemplateHandler(new DefaultUriBuilderFactory(url + API_PREFIX))
28+
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory())
29+
.build()
30+
);
31+
}
32+
33+
public ResponseEntity<Object> createBooking(Long bookerId, BookingDtoRequest bookingDto) {
34+
checkDates(bookingDto.getStart(), bookingDto.getEnd());
35+
return post("", bookerId, bookingDto);
36+
}
37+
38+
public ResponseEntity<Object> approveBooking(Long ownerId, String approved, Long bookingId) {
39+
Map<String, Object> parameters = Map.of(
40+
"approved", approved
41+
);
42+
return patch("/" + bookingId + "?approved={approved}", ownerId, parameters, null);
43+
}
44+
45+
public ResponseEntity<Object> getBookingById(Long bookingId, Long userId) {
46+
return get("/" + bookingId, userId);
47+
}
48+
49+
public ResponseEntity<Object> getBookingByUser(Long userId, String state) {
50+
validateState(state);
51+
Map<String, Object> parameters = Map.of(
52+
"state", state
53+
);
54+
return get("?state={state}", userId, parameters);
55+
}
56+
57+
public ResponseEntity<Object> getBookingByItemsUser(Long userId, String state) {
58+
validateState(state);
59+
Map<String, Object> parameters = Map.of(
60+
"state", state
61+
);
62+
return get("/owner?state={state}", userId, parameters);
63+
}
64+
65+
private void validateState(String state) {
66+
if (BookingState.from(state).isEmpty()) {
67+
throw new StateException("Неизвестное состояние: " + state);
68+
}
69+
}
70+
71+
private void checkDates(LocalDateTime start, LocalDateTime end) {
72+
if (start.isEqual(end)) {
73+
throw new ValidationException("Дата начала и дата окончания бронирования не могут быть равны");
74+
}
75+
if (start.isAfter(end)) {
76+
throw new ValidationException("Дата начала бронирования не может быть позже даты окончания бронирования");
77+
}
78+
}
79+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package ru.practicum.shareit.booking;
2+
3+
import jakarta.validation.Valid;
4+
import lombok.RequiredArgsConstructor;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.http.ResponseEntity;
7+
import org.springframework.validation.annotation.Validated;
8+
import org.springframework.web.bind.annotation.*;
9+
import ru.practicum.shareit.booking.dto.BookingDtoRequest;
10+
11+
@RestController
12+
@RequestMapping("/bookings")
13+
@Validated
14+
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
15+
public class BookingController {
16+
17+
private final BookingClient bookingClient;
18+
19+
@PostMapping
20+
public ResponseEntity<Object> createBooking(@RequestHeader("X-Sharer-User-Id") Long bookerId,
21+
@Valid @RequestBody BookingDtoRequest bookingDto) {
22+
return bookingClient.createBooking(bookerId, bookingDto);
23+
}
24+
25+
@PatchMapping("{bookingId}")
26+
public ResponseEntity<Object> approveBooking(@RequestHeader("X-Sharer-User-Id") Long ownerId,
27+
@RequestParam String approved,
28+
@PathVariable Long bookingId) {
29+
return bookingClient.approveBooking(ownerId, approved, bookingId);
30+
}
31+
32+
@GetMapping("{bookingId}")
33+
public ResponseEntity<Object> getBookingById(
34+
@PathVariable Long bookingId,
35+
@RequestHeader("X-Sharer-User-Id") Long userId) {
36+
return bookingClient.getBookingById(bookingId, userId);
37+
}
38+
39+
@GetMapping
40+
public ResponseEntity<Object> getBookingByUser(
41+
@RequestHeader("X-Sharer-User-Id") Long userId,
42+
@RequestParam(defaultValue = "ALL") String state) {
43+
return bookingClient.getBookingByUser(userId, state);
44+
}
45+
46+
@GetMapping("owner")
47+
public ResponseEntity<Object> getBookingByItemsUser(
48+
@RequestHeader("X-Sharer-User-Id") Long userId,
49+
@RequestParam(defaultValue = "ALL") String state) {
50+
return bookingClient.getBookingByItemsUser(userId, state);
51+
}
52+
}

src/main/java/ru/practicum/shareit/booking/dto/BookingDtoRequest.java renamed to gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingDtoRequest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import jakarta.validation.constraints.NotNull;
66
import lombok.AllArgsConstructor;
77
import lombok.Data;
8-
import ru.practicum.shareit.booking.enumerated.Status;
98

109
import java.time.LocalDateTime;
1110

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package ru.practicum.shareit.booking.dto;
2+
3+
import java.util.Optional;
4+
5+
public enum BookingState {
6+
// Все
7+
ALL,
8+
// Текущие
9+
CURRENT,
10+
// Будущие
11+
FUTURE,
12+
// Завершенные
13+
PAST,
14+
// Отклоненные
15+
REJECTED,
16+
// Ожидающие подтверждения
17+
WAITING;
18+
19+
public static Optional<BookingState> from(String stringState) {
20+
for (BookingState state : values()) {
21+
if (state.name().equalsIgnoreCase(stringState)) {
22+
return Optional.of(state);
23+
}
24+
}
25+
return Optional.empty();
26+
}
27+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package ru.practicum.shareit.booking.dto;
2+
3+
public enum Status {
4+
WAITING, APPROVED, REJECTED, CANCELED
5+
}

0 commit comments

Comments
 (0)