Skip to content
Merged
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
76 changes: 76 additions & 0 deletions gateway/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?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>

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

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

</project>
11 changes: 11 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,11 @@
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,56 @@
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.core.ParameterizedTypeReference;
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.*;
import ru.practicum.shareit.client.BaseClient;

import java.util.List;
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(() -> new HttpComponentsClientHttpRequestFactory())
.build()
);
}

public ResponseEntity<BookingDtoResponse> createBooking(Long userId, BookingDtoRequest bookingDtoRequest) {
return post("", userId, bookingDtoRequest, BookingDtoResponse.class);
}

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

public ResponseEntity<List<BookingDtoResponse>> getBookingByBooker(Long userId, BookingState state) {
ParameterizedTypeReference<List<BookingDtoResponse>> typeRef =
new ParameterizedTypeReference<List<BookingDtoResponse>>() {};
return get("?state={state}", userId, Map.of("state", state.name()), typeRef);
}

public ResponseEntity<List<BookingDtoResponse>> getBookingByOwner(Long userId, BookingState state) {
ParameterizedTypeReference<List<BookingDtoResponse>> typeRef =
new ParameterizedTypeReference<List<BookingDtoResponse>>() {};
return get("/owner?state={state}", userId, Map.of("state", state.name()), typeRef);
}

public ResponseEntity<BookingDtoResponse> approveBooking(Long userId, Long bookingId, Boolean isApproved) {
return patch("/" + bookingId + "?approved={approved}", userId,
Map.of("approved", isApproved), "", BookingDtoResponse.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package ru.practicum.shareit.booking;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.practicum.shareit.booking.dto.*;

import java.util.List;

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

private final BookingClient bookingClient;

@PostMapping
public ResponseEntity<BookingDtoResponse> create(@RequestHeader("X-Sharer-User-Id") @Positive Long userId,
@RequestBody @Valid BookingDtoRequest bookingDtoRequest) {
log.info("POST / bookings");
return bookingClient.createBooking(userId, bookingDtoRequest);
}

@PatchMapping("/{bookingId}")
public ResponseEntity<BookingDtoResponse> approve(@RequestHeader("X-Sharer-User-Id") @Positive Long userId,
@PathVariable @Positive Long bookingId,
@RequestParam(name = "approved") Boolean isApproved) {
log.info("PATCH / bookings / {}", bookingId);
return bookingClient.approveBooking(userId, bookingId, isApproved);
}

@GetMapping("/{bookingId}")
public ResponseEntity<BookingDtoResponse> getById(@RequestHeader("X-Sharer-User-Id") @Positive Long userId,
@PathVariable @Positive Long bookingId) {
log.info("GET booking {}, userId = {}", bookingId, userId);
return bookingClient.getBooking(userId, bookingId);
}

@GetMapping("/owner")
public ResponseEntity<List<BookingDtoResponse>> getByOwnerId(
@RequestHeader("X-Sharer-User-Id") @Positive Long ownerId,
@RequestParam(name = "state", defaultValue = "ALL") BookingState bookingState) {
log.info("GET / ByOwner / {}", ownerId);
return bookingClient.getBookingByOwner(ownerId, bookingState);
}

@GetMapping
public ResponseEntity<List<BookingDtoResponse>> getByBookerId(
@RequestHeader("X-Sharer-User-Id") @Positive Long bookerId,
@RequestParam(name = "state", defaultValue = "ALL") BookingState bookingState) {
log.info("GET / ByBooker / {}", bookerId);
return bookingClient.getBookingByBooker(bookerId, bookingState);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ru.practicum.shareit.booking.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.*;
import lombok.*;

import java.time.Instant;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
public class BookingDtoRequest {

@NotNull
@Positive
private Long itemId;

@NotNull
@FutureOrPresent
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", shape = JsonFormat.Shape.STRING, timezone = "UTC")
private Instant start;

@NotNull
@Future
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", shape = JsonFormat.Shape.STRING, timezone = "UTC")
private Instant end;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ru.practicum.shareit.booking.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import ru.practicum.shareit.item.dto.ItemDtoResponse;
import ru.practicum.shareit.user.dto.UserDtoResponse;

import java.time.LocalDateTime;

@Getter
@Setter
@Builder(toBuilder = true)
public class BookingDtoResponse {
private Long id;

private LocalDateTime start;

private LocalDateTime end;

private ItemDtoResponse item;

private UserDtoResponse booker;

private String status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ru.practicum.shareit.booking.dto;

import java.util.Optional;

public enum BookingState {
ALL, CURRENT, PAST, FUTURE, WAITING, REJECTED;

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