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
90 changes: 90 additions & 0 deletions compose.test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
services:
db:
image: postgres:16.1
container_name: postgres
ports:
- "5445:5432"
volumes:
- ./volumes/shareit:/var/lib/postgresql/data/
environment:
- SPRING_PROFILES_ACTIVE=dev
- POSTGRES_DB=shareit
- POSTGRES_USER=dbuser
- POSTGRES_PASSWORD=12345
healthcheck:
test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER
timeout: 5s
interval: 5s
retries: 10

db-init:
image: postgres:16.1
container_name: db-init-test
depends_on:
db:
condition: service_healthy
entrypoint:
- bash
- -c
- |
set -e
psql postgresql://dbuser:12345@db:5432/shareit -v ON_ERROR_STOP=1 <<-EOSQL
drop table IF EXISTS users CASCADE;
drop table IF EXISTS items CASCADE;
drop table IF EXISTS bookings CASCADE;
drop table IF EXISTS requests CASCADE;
drop table IF EXISTS comments CASCADE;

create TABLE IF NOT EXISTS users (
id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name VARCHAR(255) NOT NULL,
email VARCHAR(512) NOT NULL,
CONSTRAINT pk_user PRIMARY KEY (id),
CONSTRAINT UQ_USER_EMAIL UNIQUE (email)
);

create TABLE IF NOT EXISTS requests (
id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
description VARCHAR(2000),
requestor_id BIGINT NOT NULL,
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
CONSTRAINT pk_request PRIMARY KEY (id),
CONSTRAINT fk_request_requestor FOREIGN KEY (requestor_id) REFERENCES users(id)
);

create TABLE IF NOT EXISTS items (
id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name VARCHAR(255) NOT NULL,
description VARCHAR(2000),
available BOOLEAN DEFAULT TRUE,
owner_id BIGINT NOT NULL,
item_request_id BIGINT,
CONSTRAINT pk_item PRIMARY KEY (id),
CONSTRAINT fk_item_owner FOREIGN KEY (owner_id) REFERENCES users(id),
CONSTRAINT fk_item_item_request FOREIGN KEY (item_request_id) REFERENCES requests(id)
);

create TABLE IF NOT EXISTS bookings (
id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
start_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,
end_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,
item_id BIGINT NOT NULL,
booker_id BIGINT NOT NULL,
status VARCHAR(50),
CONSTRAINT pk_booking PRIMARY KEY (id),
CONSTRAINT fk_booking_item FOREIGN KEY (item_id) REFERENCES items(id),
CONSTRAINT fk_booking_booker FOREIGN KEY (booker_id) REFERENCES users(id)
);

create TABLE IF NOT EXISTS comments (
id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
text VARCHAR(2000),
item_id BIGINT NOT NULL,
author_id BIGINT NOT NULL,
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
CONSTRAINT pk_comment PRIMARY KEY (id),
CONSTRAINT fk_comment_item FOREIGN KEY (item_id) REFERENCES items(id),
CONSTRAINT fk_comment_author FOREIGN KEY (author_id) REFERENCES users(id)
);
EOSQL

17 changes: 0 additions & 17 deletions compose.yaml

This file was deleted.

40 changes: 40 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
services:
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
environment:
- SPRING_PROFILES_ACTIVE=dev
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/shareit
- SPRING_DATASOURCE_USERNAME=dbuser
- SPRING_DATASOURCE_PASSWORD=12345

db:
image: postgres:16.1
container_name: postgres
ports:
- "6541:5432"
environment:
- POSTGRES_PASSWORD=12345
- POSTGRES_USER=dbuser
- POSTGRES_DB=shareit
healthcheck:
test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER
timeout: 5s
interval: 5s
retries: 10
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,55 @@
package ru.practicum.shareit.booking.client;

import java.util.Map;

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.BookingRequestDto;
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> createBooking(long userId, BookingRequestDto bookingRequestDto) {
return post("", userId, bookingRequestDto);
}

public ResponseEntity<Object> updateBooking(Long userId, Long bookingId, Boolean approved) {
Map<String, Object> parameters = Map.of("approved", approved);

return patch("/" + bookingId + "?approved={approved}", userId, parameters, null);
}

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

public ResponseEntity<Object> findUserBookings(Long userId, String state) {
Map<String, Object> parameters = Map.of("state", state);

return get("?state={state}", userId, parameters);
}

public ResponseEntity<Object> findOwnerReservedItems(Long userId, String state) {
Map<String, Object> parameters = Map.of("state", state);

return get("/owner?state={state}", userId, parameters);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package ru.practicum.shareit.booking.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ru.practicum.shareit.booking.client.BookingClient;
import ru.practicum.shareit.booking.dto.BookingRequestDto;


@Controller
@RequestMapping(path = "/bookings")
@RequiredArgsConstructor
@Slf4j
@Validated
public class BookingController {
private final BookingClient bookingClient;

@PostMapping
public ResponseEntity<Object> createBooking(@RequestHeader("X-Sharer-User-Id") long userId,
@RequestBody @Valid BookingRequestDto bookingRequestDto) {
log.info("Создание бронирования {}, userId={}", bookingRequestDto, userId);
return bookingClient.createBooking(userId, bookingRequestDto);
}

@PatchMapping("/{bookingId}")
public ResponseEntity<Object> updateBooking(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable("bookingId") Long bookingId, @RequestParam(name = "approved") Boolean approved) {
log.info("Идентификатор бронирования {} по идентификатору пользователя {}", bookingId, userId);
return bookingClient.updateBooking(userId, bookingId, approved);
}

@GetMapping("/{bookingId}")
public ResponseEntity<Object> findBookingById(@RequestHeader("X-Sharer-User-Id") long userId,
@PathVariable Long bookingId) {
log.info("Забронировать {}, userId={}", bookingId, userId);
return bookingClient.findBookingById(userId, bookingId);
}

@GetMapping
public ResponseEntity<Object> findUserBookings(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam(name = "state", defaultValue = "ALL") String state) {
log.info("Получить бронирования {}.", state);
return bookingClient.findUserBookings(userId, state);
}

@GetMapping("/owner")
public ResponseEntity<Object> findOwnerReservedItems(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam(name = "state", defaultValue = "ALL") String state) {
log.info("Получить зарезервированные товары владельца{}.", state);
return bookingClient.findOwnerReservedItems(userId, state);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ru.practicum.shareit.booking.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -15,9 +14,7 @@
@Setter
public class BookingResponseDto {
private Long id;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime start;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime end;
private ItemDto item;
private UserDto booker;
Expand Down
Loading