Skip to content
Open
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
55 changes: 55 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# версия Docker Compose
version: '3.8'

# имена и описания контейнеров, которые должны быть развёрнуты
services:
# описание контейнера gateway
gateway:
build:
context: ./gateway
dockerfile: ./Dockerfile
# имя контейнера
container_name: gateway-container
# проброс портов
ports:
- "8080:8080"
# "зависит от",
depends_on:
- server
# переменные окружения
environment:
- SHAREIT_SERVER_URL=http://server:9090

# описание контейнера server
server:
build:
context: ./server
dockerfile: ./Dockerfile
# имя контейнера
container_name: server-container
# проброс портов
ports:
- "9090:9090"
# "зависит от",
depends_on:
- db
# переменные окружения
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/shareit
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root

# описание контейнера db
db:
# образ, из которого должен быть запущен контейнер
image: postgres:14
# имя контейнера
container_name: db-container
# проброс портов
ports:
- "5432:5432"
# переменные окружения
environment:
- POSTGRES_PASSWORD=root
- POSTGRES_USER=root
- POSTGRES_DB=shareit
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:11-jre-jammy
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar -Dserver.port=8080 /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 http://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.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.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</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,60 @@
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.State;
import ru.practicum.shareit.client.BaseClient;

import java.util.Map;

@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(HttpComponentsClientHttpRequestFactory::new)
.build()
);
}

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

public ResponseEntity<Object> getAllBookingOfUser(State state, Integer userId, Integer from, Integer size) {
Map<String, Object> parameters = Map.of(
"state", state.name(),
"from", from,
"size", size
);
return get("?state={state}&from={from}&size={size}", userId, parameters);
}

public ResponseEntity<Object> getAllBookingOfOwner(State state, Integer userId, Integer from, Integer size) {
Map<String, Object> parameters = Map.of(
"state", state.name(),
"from", from,
"size", size
);
return get("/owner?state={state}&from={from}&size={size}", userId, parameters);
}

public ResponseEntity<Object> getConsentToBooking(Integer bookingId, Integer userId, Boolean approved) {
Map<String, Object> parameters = Map.of("approved", approved);
return patch("/" + bookingId + "?approved={approved}", userId, parameters, null);
}

public ResponseEntity<Object> addBookingRequest(BookItemRequestDto requestDto, Integer userId) {
return post("", userId, requestDto);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package ru.practicum.shareit.booking;

import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
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.State;
import ru.practicum.shareit.valid.Add;

import javax.validation.constraints.Positive;
import javax.validation.constraints.PositiveOrZero;

@RestController
@RequestMapping(path = "/bookings")
@RequiredArgsConstructor
public class BookingController {

private final BookingClient bookingClient;

@GetMapping("/{bookingId}")
public ResponseEntity<Object> getBookingById(@PathVariable Integer bookingId,
@RequestHeader("X-Sharer-User-Id") Integer userId) {
return bookingClient.getBookingById(bookingId, userId);
}

@GetMapping
public ResponseEntity<Object> getAllBookingOfUser(@RequestParam(name = "state", defaultValue = "ALL") String stateParam,
@RequestHeader("X-Sharer-User-Id") Integer userId,
@PositiveOrZero @RequestParam(defaultValue = "0") Integer from,
@Positive @RequestParam(defaultValue = "30") Integer size) {
State state = State.from(stateParam)
.orElseThrow(() -> new IllegalArgumentException("Unknown state: " + stateParam));
return bookingClient.getAllBookingOfUser(state, userId, from, size);
}

@GetMapping("/owner")
public ResponseEntity<Object> getAllBookingOfOwner(@RequestParam(name = "state", defaultValue = "ALL") String stateParam,
@RequestHeader("X-Sharer-User-Id") Integer userId,
@PositiveOrZero @RequestParam(defaultValue = "0") Integer from,
@Positive @RequestParam(defaultValue = "30") Integer size) {
State state = State.from(stateParam)
.orElseThrow(() -> new IllegalArgumentException("Unknown state: " + stateParam));
return bookingClient.getAllBookingOfOwner(state, userId, from, size);
}

@PatchMapping("/{bookingId}")
public ResponseEntity<Object> getConsentToBooking(@PathVariable Integer bookingId,
@RequestHeader("X-Sharer-User-Id") Integer userId,
@RequestParam Boolean approved) {
return bookingClient.getConsentToBooking(bookingId, userId, approved);
}

@PostMapping
public ResponseEntity<Object> addBookingRequest(@Validated(Add.class) @RequestBody BookItemRequestDto requestDto,
@RequestHeader("X-Sharer-User-Id") Integer userId) {
return bookingClient.addBookingRequest(requestDto, userId);
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
package ru.practicum.shareit.booking.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import ru.practicum.shareit.valid.Add;

import javax.validation.constraints.Future;
import javax.validation.constraints.FutureOrPresent;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;

@Data
@Builder
@AllArgsConstructor
@Getter
@NoArgsConstructor
public class BookingDtoAdd {
@AllArgsConstructor
public class BookItemRequestDto {

private Integer id;
@NotNull
private Integer itemId;

@NotNull(groups = {Add.class})
@FutureOrPresent(groups = {Add.class})
@NotNull(groups = {Add.class})
private LocalDateTime start;

@Future(groups = {Add.class})
@NotNull(groups = {Add.class})
@FutureOrPresent(groups = {Add.class})
private LocalDateTime end;

@NotNull
private Integer itemId;
}
27 changes: 27 additions & 0 deletions gateway/src/main/java/ru/practicum/shareit/booking/dto/State.java
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 State {
// Все
ALL,
// Текущие
CURRENT,
// Будущие
FUTURE,
// Завершенные
PAST,
// Отклоненные
REJECTED,
// Ожидающие подтверждения
WAITING;

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