Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
42c8329
реализовать микросервисную архитектуру
yiqes Nov 21, 2024
0f05ed0
исправление checkstyle
yiqes Nov 21, 2024
2c13cf9
исправление surefire
yiqes Nov 21, 2024
236df8c
исправление surefire
yiqes Nov 21, 2024
c01ec64
исправление surefire
yiqes Nov 21, 2024
cf849ce
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
e2548bc
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
43b17fe
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
c692ba9
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
caf6347
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
4904d3a
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
a5bfb6d
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
184bda9
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
c7c12a2
исправление surefire добавление тестов сервисных классов
yiqes Nov 22, 2024
42abedd
fixing
yiqes Nov 22, 2024
270583d
fixes
yiqes Nov 22, 2024
2c28e62
fixes
yiqes Nov 23, 2024
dd4ad4a
Merge remote-tracking branch 'origin/add-item-requests-and-gateway' i…
yiqes Nov 23, 2024
22aec17
fixes
yiqes Nov 23, 2024
c5a21ef
fixes
yiqes Nov 23, 2024
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
15 changes: 15 additions & 0 deletions .run/ShareItGateway.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ShareItGateway" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="ru.practicum.shareit.ShareItGateway" />
<module name="shareit-gateway" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="ru.practicum.shareit.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
15 changes: 15 additions & 0 deletions .run/ShareItServer.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ShareItServer" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="ru.practicum.shareit.ShareItServer" />
<module name="shareit-server" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="ru.practicum.shareit.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
46 changes: 46 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
version: '3.8'

services:
db:
image: postgres:16.1
container_name: postgres
ports:
- "6541:5432"
environment:
- POSTGRES_PASSWORD=shareit
- POSTGRES_USER=shareit
- POSTGRES_DB=shareit
volumes:
- ./server/src/main/resources/schema.sql:/docker-entrypoint-initdb.d/initDB.sql
healthcheck:
test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER
timeout: 5s
interval: 5s
retries: 10

gateway:
build: gateway
image: shareit-gateway
container_name: shareit-gateway
ports:
- "8080:8080"
depends_on:
- server
environment:
- SHAREIT_SERVER_URL=http://server:9090

server:
build: server
image: shareit-server
container_name: shareit-server
ports:
- "9090:9090"
depends_on:
db:
condition: service_healthy
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/shareit
- SPRING_DATASOURCE_USERNAME=shareit
- SPRING_DATASOURCE_PASSWORD=shareit
volumes:
- ./server/src/main/resources/application.properties:/app/application.properties
5 changes: 5 additions & 0 deletions gateway/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM eclipse-temurin:21-jre-jammy
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar"]
70 changes: 70 additions & 0 deletions gateway/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.practicum</groupId>
<artifactId>shareit</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>shareit-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>

<name>ShareIt Gateway</name>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
12 changes: 12 additions & 0 deletions gateway/src/main/java/ru/practicum/shareit/ShareItGateway.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ru.practicum.shareit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ShareItGateway {
public static void main(String[] args) {
SpringApplication.run(ShareItGateway.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ru.practicum.shareit.booking;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.util.DefaultUriBuilderFactory;

import ru.practicum.shareit.booking.dto.BookItemRequestDto;
import ru.practicum.shareit.booking.dto.BookingState;
import ru.practicum.shareit.client.BaseClient;

@Service
public class BookingClient extends BaseClient {
private static final String API_PREFIX = "/bookings";

@Autowired
public BookingClient(@Value("${shareit-server.url}") String serverUrl, RestTemplateBuilder builder) {
super(
builder
.uriTemplateHandler(new DefaultUriBuilderFactory(serverUrl + API_PREFIX))
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory())
.build()
);
}

public ResponseEntity<Object> getBookings(Long userId, BookingState state, Integer from, Integer size) {
String path = "?state=" + state.name() + "&from=" + from;
if (size != null) {
path += "&size=" + size;
}
return get(path, userId, null);
}

public ResponseEntity<Object> getBookingsOwner(Long userId, BookingState state, Integer from, Integer size) {
String path = "/owner?state=" + state.name() + "&from=" + from;
if (size != null) {
path += "&size=" + size;
}
return get(path, userId, null);
}


public ResponseEntity<Object> create(Long userId, BookItemRequestDto requestDto) {
return post("", userId, requestDto);
}

public ResponseEntity<Object> getBooking(Long userId, Long bookingId) {
return get("/" + bookingId, userId);
}

public ResponseEntity<Object> update(Long bookingId, Long userId, Boolean approved) {
String path = "/" + bookingId + "?approved=" + approved;
return patch(path, userId, null, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package ru.practicum.shareit.booking;

import jakarta.validation.Valid;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.practicum.shareit.booking.dto.BookItemRequestDto;
import ru.practicum.shareit.booking.dto.BookingState;

@Controller
@RequestMapping(path = "/bookings")
@RequiredArgsConstructor
@Slf4j
@Validated
public class BookingController {
private static final String USER_ID = "X-Sharer-User-Id";
private final BookingClient bookingClient;
private static final String BOOKING_ID = "{booking-id}";

@GetMapping
public ResponseEntity<Object> getBookings(@RequestHeader(USER_ID) Long userId,
@RequestParam(name = "state", defaultValue = "all") String stateParam,
@PositiveOrZero @RequestParam(name = "from", defaultValue = "0")
Integer from,
@RequestParam(required = false) Integer size) {
BookingState state = BookingState.from(stateParam)
.orElseThrow(() -> new IllegalArgumentException("Unknown state: " + stateParam));
log.info("Get booking with state {}, userId={}, from={}, size={}", stateParam, userId, from, size);
return bookingClient.getBookings(userId, state, from, size);
}

@GetMapping("/owner")
public ResponseEntity<Object> getBookingsOwner(@RequestParam(name = "state", defaultValue = "all")
String stateParam,
@RequestHeader(USER_ID) Long userId,
@PositiveOrZero @RequestParam(defaultValue = "0") Integer from,
@RequestParam(required = false) Integer size) {
BookingState state = BookingState.from(stateParam)
.orElseThrow(() -> new IllegalArgumentException("Unknown state: " + stateParam));
log.info("Получен GET-запрос к эндпоинту: '/bookings/owner' на получение " +
"списка всех бронирований вещей пользователя с ID={} с параметром STATE={}", userId, state);
return bookingClient.getBookingsOwner(userId, state, from, size);
}

@PostMapping
public ResponseEntity<Object> create(@RequestHeader(USER_ID) Long userId,
@RequestBody @Valid BookItemRequestDto requestDto) {
log.info("Creating booking {}, userId={}", requestDto, userId);
return bookingClient.create(userId, requestDto);
}

@GetMapping(BOOKING_ID)
public ResponseEntity<Object> getBooking(@RequestHeader(USER_ID) Long userId,
@PathVariable("booking-id") Long bookingId) {
log.info("Get booking {}, userId={}", bookingId, userId);
return bookingClient.getBooking(userId, bookingId);
}

@ResponseBody
@PatchMapping(BOOKING_ID)
public ResponseEntity<Object> update(@PathVariable("booking-id") Long bookingId,
@RequestHeader(USER_ID) Long userId, @RequestParam Boolean approved) {
log.info("Получен PATCH-запрос к эндпоинту: '/bookings' на обновление статуса бронирования с ID={}",
bookingId);
return bookingClient.update(bookingId, userId, approved);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ru.practicum.shareit.booking.dto;

import java.time.LocalDateTime;

import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.FutureOrPresent;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class BookItemRequestDto {
Long itemId;
@FutureOrPresent
LocalDateTime start;
@Future
LocalDateTime end;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.practicum.shareit.booking.dto;

import java.util.Optional;

public enum BookingState {
// Все
ALL,
// Текущие
CURRENT,
// Будущие
FUTURE,
// Завершенные
PAST,
// Отклоненные
REJECTED,
// Ожидающие подтверждения
WAITING;

public static Optional<BookingState> from(String stringState) {
for (BookingState state : values()) {
if (state.name().equalsIgnoreCase(stringState)) {
return Optional.of(state);
}
}
return Optional.empty();
}
}
Loading