├── explore-with-me-stats
├── stats-client
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ └── application.properties
│ │ │ └── java
│ │ │ └── ru
│ │ │ └── practicum
│ │ │ └── explorewithme
│ │ │ ├── BaseClient.java
│ │ │ └── StatsClient.java
│ └── pom.xml
├── stats-service
│ ├── Dockerfile-stats
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ ├── schema.sql
│ │ │ └── application.properties
│ │ │ └── java
│ │ │ └── ru
│ │ │ └── practicum
│ │ │ └── explorewithme
│ │ │ ├── controller
│ │ │ ├── exception
│ │ │ │ ├── LocalDateTimeException.java
│ │ │ │ ├── ErrorResponse.java
│ │ │ │ └── ErrorHandler.java
│ │ │ └── StatsController.java
│ │ │ ├── ExploreWithMeStats.java
│ │ │ ├── service
│ │ │ ├── StatsService.java
│ │ │ └── StatsServiceImpl.java
│ │ │ ├── model
│ │ │ ├── Stat.java
│ │ │ └── StatMapper.java
│ │ │ └── repository
│ │ │ └── StatsRepository.java
│ └── pom.xml
├── stats-dto
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── ru
│ │ │ └── practicum
│ │ │ └── explorewithme
│ │ │ └── dto
│ │ │ ├── StatDtoWithHitsProjection.java
│ │ │ ├── StatDtoWithHits.java
│ │ │ └── StatDto.java
│ ├── .gitignore
│ └── pom.xml
└── pom.xml
├── Dockerfile-postgres-main
├── Dockerfile-postgres-stats
├── explore-wth-me-main
├── Dockerfile-main
├── src
│ └── main
│ │ ├── java
│ │ └── ru
│ │ │ └── practicum
│ │ │ └── explorewithme
│ │ │ ├── model
│ │ │ ├── enums
│ │ │ │ ├── EventState.java
│ │ │ │ ├── RequestStatus.java
│ │ │ │ └── LocationStatus.java
│ │ │ ├── Category.java
│ │ │ ├── User.java
│ │ │ ├── Compilation.java
│ │ │ ├── Location.java
│ │ │ ├── ParticipationRequest.java
│ │ │ └── Event.java
│ │ │ ├── dto
│ │ │ ├── user
│ │ │ │ ├── UserShortDto.java
│ │ │ │ ├── UserDto.java
│ │ │ │ ├── NewUserRequest.java
│ │ │ │ └── mapper
│ │ │ │ │ └── UserMapper.java
│ │ │ ├── location
│ │ │ │ ├── CoordinatesResponseDto.java
│ │ │ │ ├── LocationDtoWithEvents.java
│ │ │ │ ├── LocationDto.java
│ │ │ │ ├── LocationUpdateRequest.java
│ │ │ │ ├── NewCoordinatesDto.java
│ │ │ │ ├── NewLocationDtoAdmin.java
│ │ │ │ └── mapper
│ │ │ │ │ └── LocationMapper.java
│ │ │ ├── category
│ │ │ │ ├── NewCategoryDto.java
│ │ │ │ ├── CategoryDto.java
│ │ │ │ └── mapper
│ │ │ │ │ └── CategoryMapper.java
│ │ │ ├── request
│ │ │ │ ├── EventRequestStatusUpdateRequest.java
│ │ │ │ ├── EventRequestStatusUpdateResult.java
│ │ │ │ ├── ParticipationRequestDto.java
│ │ │ │ └── mapper
│ │ │ │ │ └── RequestMapper.java
│ │ │ ├── compilation
│ │ │ │ ├── UpdateCompilationRequest.java
│ │ │ │ ├── NewCompilationDto.java
│ │ │ │ ├── CompilationDto.java
│ │ │ │ └── mapper
│ │ │ │ │ └── CompilationMapper.java
│ │ │ └── event
│ │ │ │ ├── annotations
│ │ │ │ ├── AfterNowValidator.java
│ │ │ │ ├── AfterNow.java
│ │ │ │ ├── DateTime.java
│ │ │ │ └── DateTimeValidator.java
│ │ │ │ ├── EventShortDto.java
│ │ │ │ ├── UpdateEventUserRequest.java
│ │ │ │ ├── NewEventDto.java
│ │ │ │ ├── EventFullDto.java
│ │ │ │ └── mapper
│ │ │ │ └── EventMapper.java
│ │ │ ├── util
│ │ │ └── exception
│ │ │ │ ├── ClientErrorException.java
│ │ │ │ ├── EntityNotFoundException.java
│ │ │ │ └── handler
│ │ │ │ ├── ErrorResponse.java
│ │ │ │ └── ErrorHandler.java
│ │ │ ├── repository
│ │ │ ├── CategoryRepository.java
│ │ │ ├── UserRepository.java
│ │ │ ├── CompilationRepository.java
│ │ │ ├── ParticipationRequestRepository.java
│ │ │ ├── LocationRepository.java
│ │ │ └── EventRepository.java
│ │ │ ├── ExploreWithMeMain.java
│ │ │ ├── service
│ │ │ ├── user
│ │ │ │ ├── UserService.java
│ │ │ │ └── UserServiceImpl.java
│ │ │ ├── request
│ │ │ │ ├── ParticipationRequestService.java
│ │ │ │ └── ParticipationRequestServiceImpl.java
│ │ │ ├── category
│ │ │ │ ├── CategoryService.java
│ │ │ │ └── CategoryServiceImpl.java
│ │ │ ├── location
│ │ │ │ ├── LocationService.java
│ │ │ │ └── LocationServiceImpl.java
│ │ │ ├── compilation
│ │ │ │ ├── CompilationService.java
│ │ │ │ └── CompilationServiceImpl.java
│ │ │ └── event
│ │ │ │ ├── StatsServiceClient.java
│ │ │ │ ├── EventService.java
│ │ │ │ ├── UpdateEventOperations.java
│ │ │ │ └── EventServiceImpl.java
│ │ │ └── controller
│ │ │ ├── CategoriesController.java
│ │ │ ├── LocationsController.java
│ │ │ ├── CompilationsController.java
│ │ │ ├── admin
│ │ │ ├── AdminLocationsController.java
│ │ │ ├── AdminUsersController.java
│ │ │ ├── AdminCategoriesController.java
│ │ │ ├── AdminCompilationsController.java
│ │ │ └── AdminEventsController.java
│ │ │ ├── users
│ │ │ ├── UsersRequestsController.java
│ │ │ └── UsersEventsController.java
│ │ │ └── EventsController.java
│ │ └── resources
│ │ ├── application.properties
│ │ └── schema.sql
└── pom.xml
├── lombok.config
├── .github
└── workflows
│ ├── api-tests.yml
│ └── wait-for-it.sh
├── suppressions.xml
├── .gitignore
├── docker-compose.yml
├── README.md
├── ewm-stats-service-spec.json
├── pom.xml
└── checkstyle.xml
/explore-with-me-stats/stats-client/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | explore-with-me-stats-service.url=http://localhost:9090
--------------------------------------------------------------------------------
/Dockerfile-postgres-main:
--------------------------------------------------------------------------------
1 | FROM postgres:14-alpine
2 | COPY explore-wth-me-main/src/main/resources/schema.sql /docker-entrypoint-initdb.d/schema.sql
--------------------------------------------------------------------------------
/Dockerfile-postgres-stats:
--------------------------------------------------------------------------------
1 | FROM postgres:14-alpine
2 | COPY explore-with-me-stats/stats-service/src/main/resources/schema.sql /docker-entrypoint-initdb.d/
--------------------------------------------------------------------------------
/explore-wth-me-main/Dockerfile-main:
--------------------------------------------------------------------------------
1 | FROM amazoncorretto:11
2 | COPY target/*.jar main-service.jar
3 | ENTRYPOINT ["java", "-jar", "/main-service.jar"]
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/Dockerfile-stats:
--------------------------------------------------------------------------------
1 | FROM amazoncorretto:11
2 | COPY target/*.jar stats-service.jar
3 | ENTRYPOINT ["java", "-jar", "/stats-service.jar"]
--------------------------------------------------------------------------------
/lombok.config:
--------------------------------------------------------------------------------
1 | config.stopBubbling = true
2 | lombok.anyconstructor.addconstructorproperties = false
3 | lombok.addLombokGeneratedAnnotation = true
4 | lombok.addSuppressWarnings = false
--------------------------------------------------------------------------------
/.github/workflows/api-tests.yml:
--------------------------------------------------------------------------------
1 | name: Explore With Me API Tests
2 |
3 | on:
4 | pull_request:
5 |
6 | jobs:
7 | build:
8 | uses: yandex-praktikum/java-explore-with-me/.github/workflows/api-tests.yml@ci
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/enums/EventState.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model.enums;
2 |
3 | public enum EventState {
4 | PENDING, PUBLISHED, CANCELED
5 | }
6 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/enums/RequestStatus.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model.enums;
2 |
3 | public enum RequestStatus {
4 | PENDING, CONFIRMED, REJECTED, CANCELED
5 | }
6 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/enums/LocationStatus.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model.enums;
2 |
3 | public enum LocationStatus {
4 | SUGGESTED_BY_USER,
5 | APPROVED_BY_ADMIN,
6 | CANCELED_BY_ADMIN
7 | }
8 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-dto/src/main/java/ru/practicum/explorewithme/dto/StatDtoWithHitsProjection.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto;
2 |
3 | public interface StatDtoWithHitsProjection {
4 | String getApp();
5 |
6 | String getUri();
7 |
8 | Long getHits();
9 | }
10 |
--------------------------------------------------------------------------------
/suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/user/UserShortDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.user;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | @Data
7 | @Builder
8 | public class UserShortDto {
9 | private Long id;
10 | private String name;
11 | }
12 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/util/exception/ClientErrorException.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.util.exception;
2 |
3 | public class ClientErrorException extends RuntimeException {
4 | public ClientErrorException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/util/exception/EntityNotFoundException.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.util.exception;
2 |
3 | public class EntityNotFoundException extends RuntimeException {
4 | public EntityNotFoundException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS stats CASCADE;
2 |
3 | CREATE TABLE stats (
4 | id BIGSERIAL PRIMARY KEY,
5 | app VARCHAR(100) NOT NULL,
6 | uri VARCHAR(100) NOT NULL,
7 | ip VARCHAR(100) NOT NULL,
8 | timestamp TIMESTAMP WITH TIME ZONE NOT NULL
9 | );
10 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/controller/exception/LocalDateTimeException.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.controller.exception;
2 |
3 | public class LocalDateTimeException extends RuntimeException {
4 | public LocalDateTimeException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/location/CoordinatesResponseDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.location;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | @Data
7 | @Builder
8 | public class CoordinatesResponseDto {
9 | private long id;
10 | private double lat;
11 | private double lon;
12 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/location/LocationDtoWithEvents.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.location;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | @AllArgsConstructor
8 | public class LocationDtoWithEvents {
9 | private String name;
10 | private Long events;
11 | }
12 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/controller/exception/ErrorResponse.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.controller.exception;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | class ErrorResponse {
7 | private final String message;
8 |
9 | public ErrorResponse(String message) {
10 | this.message = message;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/util/exception/handler/ErrorResponse.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.util.exception.handler;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public class ErrorResponse {
7 |
8 | private final String error;
9 |
10 | public ErrorResponse(String error) {
11 | this.error = error;
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/category/NewCategoryDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.category;
2 |
3 | import lombok.Data;
4 |
5 | import javax.validation.constraints.NotBlank;
6 | import javax.validation.constraints.Size;
7 |
8 | @Data
9 | public class NewCategoryDto {
10 | @NotBlank
11 | @Size(max = 50)
12 | private String name;
13 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/repository/CategoryRepository.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import ru.practicum.explorewithme.model.Category;
5 |
6 | public interface CategoryRepository extends JpaRepository {
7 | boolean existsCategoriesByName(String name);
8 | }
9 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/request/EventRequestStatusUpdateRequest.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.request;
2 |
3 | import lombok.Data;
4 | import ru.practicum.explorewithme.model.enums.RequestStatus;
5 |
6 | import java.util.List;
7 |
8 | @Data
9 | public class EventRequestStatusUpdateRequest {
10 | private List requestIds;
11 | private RequestStatus status;
12 | }
13 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/user/UserDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.user;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | import javax.validation.constraints.NotNull;
7 |
8 | @Data
9 | @Builder
10 | public class UserDto {
11 | @NotNull
12 | private String email;
13 | @NotNull
14 | private Long id;
15 | @NotNull
16 | private String name;
17 | }
18 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/request/EventRequestStatusUpdateResult.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.request;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | import java.util.List;
7 |
8 | @Data
9 | @Builder
10 | public class EventRequestStatusUpdateResult {
11 | List confirmedRequests;
12 | List rejectedRequests;
13 | }
14 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/ExploreWithMeMain.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class ExploreWithMeMain {
8 | public static void main(String[] args) {
9 | SpringApplication.run(ExploreWithMeMain.class, args);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/compilation/UpdateCompilationRequest.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.compilation;
2 |
3 | import lombok.Data;
4 |
5 | import javax.validation.constraints.Size;
6 | import java.util.List;
7 |
8 | @Data
9 | public class UpdateCompilationRequest {
10 | private List events;
11 | private Boolean pinned;
12 | @Size(max = 50)
13 | private String title;
14 | }
15 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/category/CategoryDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.category;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | import javax.validation.constraints.NotBlank;
7 | import javax.validation.constraints.Size;
8 |
9 | @Data
10 | @Builder
11 | public class CategoryDto {
12 | private Long id;
13 | @NotBlank
14 | @Size(max = 50)
15 | private String name;
16 | }
17 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/ExploreWithMeStats.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class ExploreWithMeStats {
8 | public static void main(String[] args) {
9 | SpringApplication.run(ExploreWithMeStats.class, args);
10 | }
11 | }
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-dto/src/main/java/ru/practicum/explorewithme/dto/StatDtoWithHits.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto;
2 |
3 | import lombok.*;
4 |
5 | @Getter
6 | @Setter
7 | @ToString
8 | public class StatDtoWithHits {
9 | private String app;
10 | private String uri;
11 | private Long hits;
12 |
13 | public StatDtoWithHits(String app, String uri, Long hits) {
14 | this.app = app;
15 | this.uri = uri;
16 | this.hits = hits;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/compilation/NewCompilationDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.compilation;
2 |
3 | import lombok.Data;
4 |
5 | import javax.validation.constraints.NotBlank;
6 | import javax.validation.constraints.Size;
7 | import java.util.List;
8 |
9 | @Data
10 | public class NewCompilationDto {
11 | private List events;
12 | private Boolean pinned;
13 | @NotBlank
14 | @Size(max = 50)
15 | private String title;
16 | }
17 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/location/LocationDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.location;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 | import ru.practicum.explorewithme.model.enums.LocationStatus;
6 |
7 | @Data
8 | @Builder
9 | public class LocationDto {
10 | private String name;
11 | private Double lat;
12 | private Double lon;
13 | private Double rad;
14 | private Long id;
15 | private LocationStatus status;
16 | }
17 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/location/LocationUpdateRequest.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.location;
2 |
3 | import lombok.Data;
4 |
5 | import javax.validation.constraints.Size;
6 |
7 | @Data
8 | public class LocationUpdateRequest {
9 | @Size(min = 5, max = 100)
10 | private String name;
11 | private Double rad;
12 | private AdminStatusUpdate status;
13 |
14 | enum AdminStatusUpdate {
15 | APPROVED, CANCELED
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/location/NewCoordinatesDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.location;
2 |
3 | import lombok.Data;
4 |
5 | import javax.validation.constraints.Max;
6 | import javax.validation.constraints.Min;
7 | import javax.validation.constraints.NotNull;
8 |
9 | @Data
10 | public class NewCoordinatesDto {
11 | @NotNull
12 | @Min(-90) @Max(90)
13 | private Double lat;
14 | @NotNull
15 | @Min(-180) @Max(180)
16 | private Double lon;
17 | }
18 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/service/user/UserService.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.service.user;
2 |
3 | import ru.practicum.explorewithme.dto.user.NewUserRequest;
4 | import ru.practicum.explorewithme.dto.user.UserDto;
5 |
6 | import java.util.List;
7 |
8 | public interface UserService {
9 | List getUsersByAdmin(List ids, int from, int size);
10 |
11 | UserDto addNewUserByAdmin(NewUserRequest userRequest);
12 |
13 | void deleteUserByAdmin(long userId);
14 | }
15 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/user/NewUserRequest.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.user;
2 |
3 | import lombok.Data;
4 |
5 | import javax.validation.constraints.Email;
6 | import javax.validation.constraints.NotBlank;
7 | import javax.validation.constraints.Size;
8 |
9 | @Data
10 | public class NewUserRequest {
11 | @NotBlank
12 | @Email
13 | @Size(min = 6, max = 254)
14 | private String email;
15 | @NotBlank
16 | @Size(min = 2, max = 250)
17 | private String name;
18 | }
19 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/repository/UserRepository.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import ru.practicum.explorewithme.model.User;
5 |
6 | import org.springframework.data.domain.Pageable;
7 | import java.util.List;
8 |
9 | public interface UserRepository extends JpaRepository {
10 | List findAllByIdIn(List ids, Pageable pageable);
11 |
12 | boolean existsUserByName(String name);
13 | }
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/Category.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 | import javax.validation.constraints.NotBlank;
7 |
8 | @Entity
9 | @Getter
10 | @Setter
11 | @Builder
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | @Table(name = "categories")
15 | public class Category {
16 | @Id
17 | @GeneratedValue(strategy = GenerationType.IDENTITY)
18 | private Long id;
19 | @NotBlank
20 | private String name;
21 | }
22 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/service/StatsService.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.service;
2 |
3 |
4 | import ru.practicum.explorewithme.dto.StatDto;
5 | import ru.practicum.explorewithme.dto.StatDtoWithHits;
6 |
7 | import java.time.LocalDateTime;
8 | import java.util.List;
9 |
10 | public interface StatsService {
11 |
12 | StatDto saveStats(StatDto statDto);
13 |
14 | List getStats(LocalDateTime start, LocalDateTime end, List uris, Boolean unique);
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/request/ParticipationRequestDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.request;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.Builder;
5 | import lombok.Data;
6 |
7 | import java.time.LocalDateTime;
8 |
9 | @Data
10 | @Builder
11 | public class ParticipationRequestDto {
12 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
13 | private LocalDateTime created;
14 | private Long event;
15 | private Long id;
16 | private Long requester;
17 | private String status;
18 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/service/request/ParticipationRequestService.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.service.request;
2 |
3 | import ru.practicum.explorewithme.dto.request.ParticipationRequestDto;
4 |
5 | import java.util.List;
6 |
7 | public interface ParticipationRequestService {
8 | List getRequestsByUserId(long userId);
9 |
10 | ParticipationRequestDto addNewParticipationRequest(long userId, long eventId);
11 |
12 | ParticipationRequestDto cancelParticipationRequest(long userId, long requestId);
13 | }
14 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/compilation/CompilationDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.compilation;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 | import ru.practicum.explorewithme.dto.event.EventShortDto;
6 |
7 | import javax.validation.constraints.NotNull;
8 | import java.util.List;
9 |
10 | @Data
11 | @Builder
12 | public class CompilationDto {
13 | private List events;
14 | @NotNull
15 | private Long id;
16 | @NotNull
17 | private Boolean pinned;
18 | @NotNull
19 | private String title;
20 | }
21 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/annotations/AfterNowValidator.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event.annotations;
2 |
3 | import javax.validation.ConstraintValidator;
4 | import javax.validation.ConstraintValidatorContext;
5 | import java.time.LocalDateTime;
6 |
7 | public class AfterNowValidator implements ConstraintValidator {
8 |
9 | @Override
10 | public boolean isValid(LocalDateTime value, ConstraintValidatorContext context) {
11 | return value == null || value.isAfter(LocalDateTime.now());
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/location/NewLocationDtoAdmin.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.location;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | import javax.validation.constraints.*;
7 |
8 | @Data
9 | @Builder
10 | public class NewLocationDtoAdmin {
11 | @NotBlank
12 | @Size(min = 5, max = 100)
13 | private String name;
14 | @NotNull
15 | @Min(-90) @Max(90)
16 | private Double lat;
17 | @NotNull
18 | @Min(-180) @Max(180)
19 | private Double lon;
20 | @PositiveOrZero
21 | private Double rad;
22 | }
23 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/model/Stat.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 | import java.time.LocalDateTime;
7 |
8 | @Entity
9 | @Table(name = "stats")
10 | @Getter
11 | @Setter
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class Stat {
16 | @Id
17 | @GeneratedValue(strategy = GenerationType.IDENTITY)
18 | private Long id;
19 | private String app;
20 | private String uri;
21 | private String ip;
22 | private LocalDateTime timestamp;
23 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/User.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 | import javax.validation.constraints.Email;
7 | import javax.validation.constraints.NotNull;
8 |
9 | @Entity
10 | @Getter
11 | @Setter
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | @Table(name = "users")
16 | public class User {
17 | @Id
18 | @GeneratedValue(strategy = GenerationType.IDENTITY)
19 | private Long id;
20 | @NotNull
21 | @Email
22 | private String email;
23 | private String name;
24 | }
25 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/annotations/AfterNow.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event.annotations;
2 |
3 | import javax.validation.Constraint;
4 | import javax.validation.Payload;
5 | import java.lang.annotation.*;
6 |
7 | @Documented
8 | @Constraint(validatedBy = AfterNowValidator.class)
9 | @Target({ElementType.FIELD})
10 | @Retention(RetentionPolicy.RUNTIME)
11 | public @interface AfterNow {
12 | String message() default "Date and time must be after current date and time";
13 | Class>[] groups() default {};
14 | Class extends Payload>[] payload() default {};
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/service/category/CategoryService.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.service.category;
2 |
3 | import ru.practicum.explorewithme.dto.category.CategoryDto;
4 | import ru.practicum.explorewithme.dto.category.NewCategoryDto;
5 |
6 | import java.util.List;
7 |
8 | public interface CategoryService {
9 | CategoryDto addNewCategory(NewCategoryDto dto);
10 |
11 | void deleteCategory(long catId);
12 |
13 | CategoryDto updateCategory(long catId, CategoryDto dto);
14 |
15 | List getCategories(int from, int size);
16 |
17 | CategoryDto getCategory(long catId);
18 | }
19 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-dto/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### IntelliJ IDEA ###
7 | .idea/modules.xml
8 | .idea/jarRepositories.xml
9 | .idea/compiler.xml
10 | .idea/libraries/
11 | *.iws
12 | *.iml
13 | *.ipr
14 |
15 | ### Eclipse ###
16 | .apt_generated
17 | .classpath
18 | .factorypath
19 | .project
20 | .settings
21 | .springBeans
22 | .sts4-cache
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 | !**/src/main/**/build/
32 | !**/src/test/**/build/
33 |
34 | ### VS Code ###
35 | .vscode/
36 |
37 | ### Mac OS ###
38 | .DS_Store
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-dto/src/main/java/ru/practicum/explorewithme/dto/StatDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.*;
5 |
6 | import javax.validation.constraints.NotBlank;
7 | import javax.validation.constraints.NotNull;
8 | import java.time.LocalDateTime;
9 |
10 | @Data
11 | @Builder
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class StatDto {
15 | @NotBlank
16 | private String app;
17 | @NotBlank
18 | private String uri;
19 | @NotBlank
20 | private String ip;
21 | @NotNull
22 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
23 | private LocalDateTime timestamp;
24 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/repository/CompilationRepository.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.repository;
2 |
3 | import org.springframework.data.domain.Pageable;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import ru.practicum.explorewithme.model.Compilation;
6 |
7 | import java.util.List;
8 | import java.util.Optional;
9 |
10 | public interface CompilationRepository extends JpaRepository {
11 |
12 | List findAllByPinned(Boolean pinned, Pageable pageable);
13 |
14 | Optional getCompilationById(long compId);
15 |
16 | Optional findCompilationByTitle(String title);
17 | }
18 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/annotations/DateTime.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event.annotations;
2 |
3 | import javax.validation.Constraint;
4 | import javax.validation.Payload;
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | @Target({ElementType.TYPE})
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Constraint(validatedBy = DateTimeValidator.class)
13 | public @interface DateTime {
14 | String message() default "Invalid date range";
15 |
16 | Class>[] groups() default {};
17 |
18 | Class extends Payload>[] payload() default {};
19 | }
20 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/Compilation.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model;
2 |
3 | import lombok.*;
4 |
5 | import javax.persistence.*;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | @Entity
10 | @Getter
11 | @Setter
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | @Table(name = "compilations")
16 | public class Compilation {
17 | @Id
18 | @GeneratedValue(strategy = GenerationType.IDENTITY)
19 | private Long id;
20 | private String title;
21 | @Column(columnDefinition = "BOOLEAN DEFAULT false")
22 | private Boolean pinned;
23 |
24 | @ManyToMany(mappedBy = "compilationList")
25 | private List eventList = new ArrayList<>();
26 | }
27 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/service/location/LocationService.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.service.location;
2 |
3 | import ru.practicum.explorewithme.dto.location.LocationDto;
4 | import ru.practicum.explorewithme.dto.location.LocationUpdateRequest;
5 | import ru.practicum.explorewithme.dto.location.NewLocationDtoAdmin;
6 | import ru.practicum.explorewithme.dto.location.LocationDtoWithEvents;
7 |
8 | import java.util.List;
9 |
10 | public interface LocationService {
11 |
12 | LocationDto addNewLocation(NewLocationDtoAdmin locationDto);
13 |
14 | List getLocations(int from, int size);
15 |
16 | LocationDto updateLocation(long id, LocationUpdateRequest request);
17 |
18 | void deleteLocation(long locationId);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/service/compilation/CompilationService.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.service.compilation;
2 |
3 | import ru.practicum.explorewithme.dto.compilation.CompilationDto;
4 | import ru.practicum.explorewithme.dto.compilation.NewCompilationDto;
5 | import ru.practicum.explorewithme.dto.compilation.UpdateCompilationRequest;
6 |
7 | import java.util.List;
8 |
9 | public interface CompilationService {
10 |
11 | CompilationDto addNewCompilation(NewCompilationDto newCompilationDto);
12 |
13 | void deleteCompilation(long compId);
14 |
15 | CompilationDto updateCompilation(long compId, UpdateCompilationRequest updateRequest);
16 |
17 | List getCompilations(Boolean pinned, int from, int size);
18 |
19 | CompilationDto getCompilation(long compId);
20 | }
21 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/repository/ParticipationRequestRepository.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import ru.practicum.explorewithme.model.ParticipationRequest;
5 | import ru.practicum.explorewithme.model.enums.RequestStatus;
6 |
7 | import java.util.List;
8 |
9 | public interface ParticipationRequestRepository extends JpaRepository {
10 | List findAllByRequesterId(long userId);
11 |
12 | List findAllByEventIdAndStatus(long eventId, RequestStatus status);
13 |
14 | List findAllByEventInitiatorIdAndEventId(long userId, long eventId);
15 |
16 | boolean existsByRequesterIdAndEventId(long userId, long eventId);
17 | }
18 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/model/StatMapper.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model;
2 |
3 | import lombok.experimental.UtilityClass;
4 | import ru.practicum.explorewithme.dto.StatDto;
5 |
6 | @UtilityClass
7 | public class StatMapper {
8 |
9 | public Stat fromStatDto(StatDto statDto) {
10 | return Stat.builder()
11 | .app(statDto.getApp())
12 | .uri(statDto.getUri())
13 | .ip(statDto.getIp())
14 | .timestamp(statDto.getTimestamp())
15 | .build();
16 | }
17 |
18 | public StatDto toStatDto(Stat stat) {
19 | return StatDto.builder()
20 | .app(stat.getApp())
21 | .uri(stat.getUri())
22 | .ip(stat.getIp())
23 | .timestamp(stat.getTimestamp())
24 | .build();
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/Location.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model;
2 |
3 | import lombok.*;
4 | import ru.practicum.explorewithme.model.enums.LocationStatus;
5 |
6 | import javax.persistence.*;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | @Entity
11 | @Getter
12 | @Setter
13 | @Builder
14 | @ToString
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | @Table(name = "locations")
18 | public class Location {
19 | @Id
20 | @GeneratedValue(strategy = GenerationType.IDENTITY)
21 | private Long id;
22 | private Double lat;
23 | private Double lon;
24 | private Double rad;
25 | private String name;
26 | @Enumerated(EnumType.STRING)
27 | @Column(name = "status", nullable = false)
28 | private LocationStatus status;
29 |
30 | @ManyToMany(mappedBy = "locationList")
31 | private List eventList = new ArrayList<>();
32 | }
33 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/EventShortDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import ru.practicum.explorewithme.dto.category.CategoryDto;
7 | import ru.practicum.explorewithme.dto.user.UserShortDto;
8 |
9 | import javax.validation.constraints.NotNull;
10 | import java.time.LocalDateTime;
11 |
12 | @Data
13 | @Builder
14 | public class EventShortDto {
15 | @NotNull
16 | private String annotation;
17 | @NotNull
18 | private CategoryDto category;
19 | private Integer confirmedRequests;
20 | @NotNull
21 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
22 | private LocalDateTime eventDate;
23 | private Long id;
24 | @NotNull
25 | private UserShortDto initiator;
26 | private Boolean paid;
27 | @NotNull
28 | private String title;
29 | private Integer views;
30 | }
31 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/controller/exception/ErrorHandler.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.controller.exception;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ExceptionHandler;
5 | import org.springframework.web.bind.annotation.ResponseStatus;
6 | import org.springframework.web.bind.annotation.RestControllerAdvice;
7 |
8 | @RestControllerAdvice
9 | public class ErrorHandler {
10 | @ExceptionHandler
11 | @ResponseStatus(HttpStatus.BAD_REQUEST)
12 | public ErrorResponse handleLocalDateTimeException(final LocalDateTimeException e) {
13 | e.printStackTrace();
14 | return new ErrorResponse(e.getMessage());
15 | }
16 |
17 | @ExceptionHandler
18 | @ResponseStatus(HttpStatus.BAD_REQUEST)
19 | public ErrorResponse handleThrowableException(final Throwable e) {
20 | e.printStackTrace();
21 | return new ErrorResponse(e.getMessage());
22 | }
23 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/UpdateEventUserRequest.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.Data;
5 | import ru.practicum.explorewithme.dto.event.annotations.AfterNow;
6 | import ru.practicum.explorewithme.dto.location.NewCoordinatesDto;
7 |
8 | import javax.validation.constraints.Size;
9 | import java.time.LocalDateTime;
10 |
11 | @Data
12 | public class UpdateEventUserRequest {
13 | @Size(min = 20, max = 2000)
14 | private String annotation;
15 | private Long category;
16 | @Size(min = 20, max = 7000)
17 | private String description;
18 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
19 | @AfterNow
20 | private LocalDateTime eventDate;
21 | private NewCoordinatesDto location;
22 | private Boolean paid;
23 | private Integer participantLimit;
24 | private Boolean requestModeration;
25 | private String stateAction;
26 | @Size(min = 3, max = 120)
27 | private String title;
28 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/model/ParticipationRequest.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.*;
5 | import ru.practicum.explorewithme.model.enums.RequestStatus;
6 |
7 | import javax.persistence.*;
8 | import javax.validation.constraints.NotNull;
9 | import java.time.LocalDateTime;
10 |
11 | @Entity
12 | @Getter
13 | @Setter
14 | @Builder
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | @Table(name = "requests")
18 | public class ParticipationRequest {
19 | @NotNull
20 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
21 | private LocalDateTime created;
22 | @ManyToOne(fetch = FetchType.LAZY)
23 | private Event event;
24 | @Id
25 | @GeneratedValue(strategy = GenerationType.IDENTITY)
26 | private Long id;
27 | @ManyToOne(fetch = FetchType.LAZY)
28 | private User requester;
29 | @Enumerated(EnumType.STRING)
30 | @Column(name = "status", nullable = false)
31 | private RequestStatus status;
32 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/annotations/DateTimeValidator.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event.annotations;
2 |
3 | import ru.practicum.explorewithme.dto.event.NewEventDto;
4 |
5 | import javax.validation.ConstraintValidator;
6 | import javax.validation.ConstraintValidatorContext;
7 | import java.time.LocalDateTime;
8 |
9 | public class DateTimeValidator implements ConstraintValidator {
10 |
11 | @Override
12 | public boolean isValid(Object value, ConstraintValidatorContext context) {
13 | if (value == null) {
14 | return true;
15 | }
16 |
17 | if (!(value instanceof NewEventDto)) {
18 | throw new IllegalArgumentException("Invalid validation type");
19 | }
20 |
21 | NewEventDto entity = (NewEventDto) value;
22 | LocalDateTime now = LocalDateTime.now();
23 | LocalDateTime eventDate = entity.getEventDate();
24 |
25 | return eventDate != null && eventDate.minusHours(2L).isAfter(now);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=9090
2 |
3 | spring.jpa.hibernate.ddl-auto=none
4 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
5 | spring.jpa.properties.hibernate.format_sql=true
6 | spring.sql.init.mode=always
7 | spring.jpa.show-sql=true
8 |
9 | logging.level.org.springframework.orm.jpa=INFO
10 | logging.level.org.springframework.transaction=INFO
11 | logging.level.org.springframework.transaction.interceptor=TRACE
12 | logging.level.org.springframework.orm.jpa.JpaTransactionManager=DEBUG
13 |
14 | spring.datasource.driverClassName=org.postgresql.Driver
15 | spring.datasource.url=${SPRING_DATASOURCE_URL}
16 | spring.datasource.username=${USERNAME_DB}
17 | spring.datasource.password=${PASSWORD_DB}
18 |
19 | #---
20 | spring.config.activate.on-profile=ci,test
21 | spring.datasource.driverClassName=org.h2.Driver
22 | spring.datasource.url=jdbc:h2:mem:emw
23 | spring.datasource.username=test
24 | spring.datasource.password=test
25 | spring.h2.console.enabled=true
26 | spring.h2.console.path=/h2-console
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/request/mapper/RequestMapper.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.request.mapper;
2 |
3 | import lombok.experimental.UtilityClass;
4 | import ru.practicum.explorewithme.dto.request.ParticipationRequestDto;
5 | import ru.practicum.explorewithme.model.ParticipationRequest;
6 |
7 | import java.util.List;
8 | import java.util.stream.Collectors;
9 |
10 | @UtilityClass
11 | public class RequestMapper {
12 | public ParticipationRequestDto mapToDto(ParticipationRequest entity) {
13 | return ParticipationRequestDto.builder()
14 | .id(entity.getId())
15 | .requester(entity.getRequester().getId())
16 | .event(entity.getEvent().getId())
17 | .created(entity.getCreated())
18 | .status(String.valueOf(entity.getStatus()))
19 | .build();
20 | }
21 |
22 | public List mapToDto(List entities) {
23 | return entities.stream()
24 | .map(RequestMapper::mapToDto)
25 | .collect(Collectors.toList());
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/util/exception/handler/ErrorHandler.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.util.exception.handler;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ExceptionHandler;
5 | import org.springframework.web.bind.annotation.ResponseStatus;
6 | import org.springframework.web.bind.annotation.RestControllerAdvice;
7 | import ru.practicum.explorewithme.util.exception.ClientErrorException;
8 | import ru.practicum.explorewithme.util.exception.EntityNotFoundException;
9 |
10 | @RestControllerAdvice
11 | public class ErrorHandler {
12 |
13 | @ExceptionHandler
14 | @ResponseStatus(HttpStatus.NOT_FOUND)
15 | public ErrorResponse handleEventNotFoundException(final EntityNotFoundException e) {
16 | e.printStackTrace();
17 | return new ErrorResponse(e.getMessage());
18 | }
19 |
20 | @ExceptionHandler
21 | @ResponseStatus(HttpStatus.CONFLICT)
22 | public ErrorResponse handleClientErrorException(final ClientErrorException e) {
23 | e.printStackTrace();
24 | return new ErrorResponse(e.getMessage());
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/user/mapper/UserMapper.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.user.mapper;
2 |
3 | import lombok.experimental.UtilityClass;
4 | import ru.practicum.explorewithme.dto.user.NewUserRequest;
5 | import ru.practicum.explorewithme.dto.user.UserDto;
6 | import ru.practicum.explorewithme.dto.user.UserShortDto;
7 | import ru.practicum.explorewithme.model.User;
8 |
9 | @UtilityClass
10 | public class UserMapper {
11 |
12 | public User mapFromUserDto(NewUserRequest dto) {
13 | return User.builder()
14 | .name(dto.getName())
15 | .email(dto.getEmail())
16 | .build();
17 | }
18 |
19 | public UserDto mapToUserDto(User user) {
20 | return UserDto.builder()
21 | .id(user.getId())
22 | .email(user.getEmail())
23 | .name(user.getName())
24 | .build();
25 | }
26 |
27 | public UserShortDto mapToUserShortDto(User user) {
28 | return UserShortDto.builder()
29 | .id(user.getId())
30 | .name(user.getName())
31 | .build();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/repository/LocationRepository.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import org.springframework.data.jpa.repository.Query;
5 | import org.springframework.data.repository.query.Param;
6 | import ru.practicum.explorewithme.model.Location;
7 |
8 | import org.springframework.data.domain.Pageable;
9 | import java.util.List;
10 |
11 | public interface LocationRepository extends JpaRepository {
12 |
13 | List findAllByNameNotNull(Pageable pageable);
14 |
15 | @Query("SELECT l FROM Location l " +
16 | "WHERE FUNCTION('distance', :lat, :lon, l.lat, l.lon) <= l.rad " +
17 | "ORDER BY FUNCTION('distance', :lat, :lon, l.lat, l.lon) ASC ")
18 | List findLocationsWithinRadius(
19 | @Param("lat") Double lat,
20 | @Param("lon") Double lon
21 | );
22 |
23 | Location findByLatAndLon(Double lat, Double lon);
24 |
25 | boolean existsByLatAndLon(Double lat, Double lon);
26 |
27 | boolean existsByNameAndLatAndLon(String name, Double lat, Double lon);
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/category/mapper/CategoryMapper.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.category.mapper;
2 |
3 | import lombok.experimental.UtilityClass;
4 | import ru.practicum.explorewithme.dto.category.CategoryDto;
5 | import ru.practicum.explorewithme.dto.category.NewCategoryDto;
6 | import ru.practicum.explorewithme.model.Category;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | @UtilityClass
12 | public class CategoryMapper {
13 | public Category mapEntityFromDto(NewCategoryDto dto) {
14 | return Category.builder()
15 | .name(dto.getName())
16 | .build();
17 | }
18 |
19 | public CategoryDto mapDtoFromEntity(Category entity) {
20 | return CategoryDto.builder()
21 | .id(entity.getId())
22 | .name(entity.getName())
23 | .build();
24 | }
25 |
26 | public List mapDtoFromEntity(Iterable entities) {
27 | List ans = new ArrayList<>();
28 | for (Category c : entities) {
29 | ans.add(mapDtoFromEntity(c));
30 | }
31 | return ans;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/controller/CategoriesController.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.controller;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.web.bind.annotation.*;
6 | import ru.practicum.explorewithme.dto.category.CategoryDto;
7 | import ru.practicum.explorewithme.service.category.CategoryService;
8 |
9 | import java.util.List;
10 |
11 | @Slf4j
12 | @RestController
13 | @RequiredArgsConstructor
14 | @RequestMapping(path = "/categories")
15 | public class CategoriesController {
16 |
17 | private final CategoryService categoryService;
18 |
19 | @GetMapping
20 | public List getCategories(
21 | @RequestParam(required = false, defaultValue = "0") int from,
22 | @RequestParam(required = false, defaultValue = "10") int size
23 | ) {
24 | log.info("GET | Get Categories");
25 | return categoryService.getCategories(from, size);
26 | }
27 |
28 | @GetMapping(path = "/{catId}")
29 | public CategoryDto getCategory(
30 | @PathVariable(name = "catId") long catId
31 | ) {
32 | return categoryService.getCategory(catId);
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/NewEventDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.Data;
5 | import ru.practicum.explorewithme.dto.event.annotations.DateTime;
6 | import ru.practicum.explorewithme.dto.location.NewCoordinatesDto;
7 |
8 | import javax.validation.Valid;
9 | import javax.validation.constraints.NotBlank;
10 | import javax.validation.constraints.NotNull;
11 | import javax.validation.constraints.PositiveOrZero;
12 | import javax.validation.constraints.Size;
13 | import java.time.LocalDateTime;
14 |
15 | @Data
16 | @DateTime
17 | public class NewEventDto {
18 | @NotBlank
19 | @Size(min = 20, max = 2000)
20 | private String annotation;
21 | @NotNull
22 | private Long category;
23 | @NotBlank
24 | @Size(min = 20)
25 | private String description;
26 | @NotNull
27 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
28 | private LocalDateTime eventDate;
29 | @NotNull
30 | @Valid
31 | private NewCoordinatesDto location;
32 | private Boolean paid;
33 | @PositiveOrZero
34 | private Integer participantLimit;
35 | private Boolean requestModeration;
36 | @NotNull
37 | @Size(min = 3, max = 120)
38 | private String title;
39 | }
40 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | logging.level.org.springframework.web.client.RestTemplate=DEBUG
2 | server.port=8080
3 | explore-with-me-stats-service.url=${EWM_SERVER_URL}
4 | app-name=ewm-main-service
5 |
6 | spring.jpa.hibernate.ddl-auto=none
7 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
8 | spring.jpa.properties.hibernate.format_sql=true
9 | spring.sql.init.mode=always
10 | spring.jpa.show-sql=true
11 |
12 | logging.level.org.springframework.orm.jpa=INFO
13 | logging.level.org.springframework.transaction=INFO
14 | logging.level.org.springframework.transaction.interceptor=TRACE
15 | logging.level.org.springframework.orm.jpa.JpaTransactionManager=DEBUG
16 |
17 | spring.datasource.driverClassName=org.postgresql.Driver
18 | spring.datasource.url=${SPRING_DATASOURCE_URL}
19 | spring.datasource.username=${USERNAME_DB}
20 | spring.datasource.password=${PASSWORD_DB}
21 |
22 | #---
23 | explore-with-me-stats-service.url=http://localhost:9090
24 | spring.config.activate.on-profile=ci,test
25 | spring.datasource.url=jdbc:postgresql://localhost:5432/ewmmain
26 | spring.datasource.username=postgres
27 | spring.datasource.password=iamroot
28 | #spring.datasource.driverClassName=org.h2.Driver
29 | #spring.datasource.url=jdbc:h2:mem:emw-main
30 | #spring.datasource.username=test
31 | #spring.datasource.password=test
32 | #spring.h2.console.enabled=true
33 | #spring.h2.console.path=/h2-console
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/event/EventFullDto.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.event;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import ru.practicum.explorewithme.dto.category.CategoryDto;
7 | import ru.practicum.explorewithme.dto.location.CoordinatesResponseDto;
8 | import ru.practicum.explorewithme.dto.user.UserShortDto;
9 |
10 | import javax.validation.constraints.NotNull;
11 | import java.time.LocalDateTime;
12 |
13 | @Data
14 | @Builder
15 | public class EventFullDto {
16 | @NotNull
17 | private String annotation;
18 | @NotNull
19 | private CategoryDto category;
20 | private Integer confirmedRequests;
21 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
22 | private LocalDateTime createdOn;
23 | @NotNull
24 | private String description;
25 | @NotNull
26 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
27 | private LocalDateTime eventDate;
28 | private Long id;
29 | private UserShortDto initiator;
30 | @NotNull
31 | private CoordinatesResponseDto location;
32 | private Boolean paid;
33 | private Integer participantLimit;
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
35 | private LocalDateTime publishedOn;
36 | private Boolean requestModeration;
37 | private String state;
38 | @NotNull
39 | private String title;
40 | private Integer views;
41 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/location/mapper/LocationMapper.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.location.mapper;
2 |
3 | import lombok.experimental.UtilityClass;
4 | import ru.practicum.explorewithme.dto.location.LocationDto;
5 | import ru.practicum.explorewithme.dto.location.NewLocationDtoAdmin;
6 | import ru.practicum.explorewithme.dto.location.NewCoordinatesDto;
7 | import ru.practicum.explorewithme.model.Location;
8 |
9 | @UtilityClass
10 | public class LocationMapper {
11 |
12 | public Location mapFromLocationDto(NewLocationDtoAdmin dto) {
13 | return Location.builder()
14 | .name(dto.getName())
15 | .lon(dto.getLon())
16 | .lat(dto.getLat())
17 | .rad(dto.getRad())
18 | .build();
19 | }
20 |
21 | public Location mapFromLocationShortDto(NewCoordinatesDto dto) {
22 | return Location.builder()
23 | .lat(dto.getLat())
24 | .lon(dto.getLon())
25 | .build();
26 | }
27 |
28 | public LocationDto mapFullDtoFromEntity(Location entity) {
29 | return LocationDto.builder()
30 | .id(entity.getId())
31 | .name((entity.getName()))
32 | .lat(entity.getLat())
33 | .lon(entity.getLon())
34 | .rad(entity.getRad())
35 | .status(entity.getStatus())
36 | .build();
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/controller/LocationsController.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.controller;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.validation.annotation.Validated;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestParam;
9 | import org.springframework.web.bind.annotation.RestController;
10 | import ru.practicum.explorewithme.dto.location.LocationDtoWithEvents;
11 | import ru.practicum.explorewithme.service.location.LocationService;
12 |
13 | import javax.validation.constraints.Positive;
14 | import javax.validation.constraints.PositiveOrZero;
15 | import java.util.List;
16 |
17 | @Slf4j
18 | @Validated
19 | @RestController
20 | @RequiredArgsConstructor
21 | @RequestMapping(path = "/locations")
22 | public class LocationsController {
23 |
24 | private final LocationService locationService;
25 |
26 | @GetMapping
27 | public List getLocations(
28 | @RequestParam(defaultValue = "0") @PositiveOrZero int from,
29 | @RequestParam(defaultValue = "10") @Positive int size
30 | ) {
31 | log.info("GET | Locations");
32 | List response = locationService.getLocations(from, size);
33 | log.info("{}", response);
34 | return response;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.1'
2 | services:
3 | stats-server:
4 | build:
5 | context: ./explore-with-me-stats/stats-service
6 | dockerfile: Dockerfile-stats
7 | image: ewm-stats-service
8 | ports:
9 | - "9090:9090"
10 | depends_on:
11 | - stats-db
12 | environment:
13 | - SPRING_DATASOURCE_URL=jdbc:postgresql://stats-db:5432/ewmstats
14 | - USERNAME_DB=postgres
15 | - PASSWORD_DB=iamroot
16 |
17 | stats-db:
18 | image: postgres:14-alpine
19 | build:
20 | context: ./
21 | dockerfile: Dockerfile-postgres-stats
22 | volumes:
23 | - /var/lib/postgresql/data/
24 | ports:
25 | - "6541:5432"
26 | environment:
27 | - POSTGRES_DB=ewmstats
28 | - POSTGRES_USER=postgres
29 | - POSTGRES_PASSWORD=iamroot
30 |
31 | ewm-service:
32 | build:
33 | context: ./explore-wth-me-main
34 | dockerfile: Dockerfile-main
35 | image: ewm-main-service
36 | ports:
37 | - "8080:8080"
38 | depends_on:
39 | - stats-server
40 | - ewm-db
41 | environment:
42 | - EWM_SERVER_URL=http://stats-server:9090
43 | - SPRING_DATASOURCE_URL=jdbc:postgresql://ewm-db:5432/ewmmain
44 | - USERNAME_DB=postgres
45 | - PASSWORD_DB=iamroot
46 |
47 | ewm-db:
48 | image: postgres:14-alpine
49 | build:
50 | context: ./
51 | dockerfile: Dockerfile-postgres-main
52 | volumes:
53 | - /var/lib/postgresql/data/
54 | ports:
55 | - "6542:5432"
56 | environment:
57 | - POSTGRES_DB=ewmmain
58 | - POSTGRES_USER=postgres
59 | - POSTGRES_PASSWORD=iamroot
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/controller/CompilationsController.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.controller;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.web.bind.annotation.*;
6 | import ru.practicum.explorewithme.dto.compilation.CompilationDto;
7 | import ru.practicum.explorewithme.service.compilation.CompilationService;
8 |
9 | import java.util.List;
10 |
11 | @Slf4j
12 | @RestController
13 | @RequiredArgsConstructor
14 | @RequestMapping(path = "/compilations")
15 | public class CompilationsController {
16 |
17 | private final CompilationService compilationService;
18 |
19 | @GetMapping
20 | public List getCompilations(
21 | @RequestParam(required = false, name = "pinned") Boolean pinned,
22 | @RequestParam(required = false, defaultValue = "0") int from,
23 | @RequestParam(required = false, defaultValue = "10") int size
24 | ) {
25 | log.info("GET | Get Compilations");
26 | List response = compilationService.getCompilations(pinned, from, size);
27 | log.info("Get Compilations: {}", response);
28 | return response;
29 | }
30 |
31 | @GetMapping(path = "/{compId}")
32 | public CompilationDto getCompilation(
33 | @PathVariable(name = "compId") long compId
34 | ) {
35 | log.info("GET | Get Compilation");
36 | CompilationDto response = compilationService.getCompilation(compId);
37 | log.info("Get Compilation: {}", response);
38 | return response;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/dto/compilation/mapper/CompilationMapper.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.dto.compilation.mapper;
2 |
3 | import lombok.experimental.UtilityClass;
4 | import ru.practicum.explorewithme.dto.compilation.CompilationDto;
5 | import ru.practicum.explorewithme.dto.compilation.NewCompilationDto;
6 | import ru.practicum.explorewithme.dto.event.mapper.EventMapper;
7 | import ru.practicum.explorewithme.model.Compilation;
8 | import ru.practicum.explorewithme.model.Event;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.stream.Collectors;
13 |
14 | @UtilityClass
15 | public class CompilationMapper {
16 |
17 | public CompilationDto mapEntityToDto(Compilation compilation) {
18 | List eventList = compilation.getEventList() != null ? compilation.getEventList() : new ArrayList<>();
19 |
20 | return CompilationDto.builder()
21 | .events(EventMapper.mapToEventShortDto(eventList))
22 | .id(compilation.getId())
23 | .pinned(compilation.getPinned())
24 | .title(compilation.getTitle())
25 | .build();
26 | }
27 |
28 | public List mapEntityToDto(List compilations) {
29 | return compilations.stream()
30 | .map(CompilationMapper::mapEntityToDto)
31 | .collect(Collectors.toList());
32 | }
33 |
34 | public Compilation mapFromNewCompilationDto(NewCompilationDto dto) {
35 | return Compilation.builder()
36 | .title(dto.getTitle())
37 | .pinned(dto.getPinned() != null ? dto.getPinned() : false)
38 | .build();
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/explore-with-me-stats/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | ru.practicum
9 | explore-with-me
10 | 0.0.1-SNAPSHOT
11 | ../pom.xml
12 |
13 |
14 | pom
15 |
16 | Explore With Me Statistics
17 |
18 | stats-dto
19 | stats-client
20 | stats-service
21 |
22 | explore-with-me-stats
23 |
24 |
25 | 11
26 | 11
27 | UTF-8
28 |
29 |
30 |
31 |
32 |
33 |
34 | com.fasterxml.jackson.core
35 | jackson-databind
36 | 2.13.4.1
37 |
38 |
39 |
40 | ru.practicum
41 | stats-dto
42 | ${project.version}
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-dto/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | ru.practicum
8 | explore-with-me-stats
9 | 0.0.1-SNAPSHOT
10 | ../pom.xml
11 |
12 |
13 | stats-dto
14 | jar
15 |
16 |
17 | 11
18 | 11
19 | UTF-8
20 |
21 |
22 |
23 |
24 | org.projectlombok
25 | lombok
26 | true
27 |
28 |
29 |
30 | com.fasterxml.jackson.core
31 | jackson-databind
32 |
33 |
34 |
35 | jakarta.validation
36 | jakarta.validation-api
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-test
42 | test
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/controller/StatsController.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.controller;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.format.annotation.DateTimeFormat;
6 | import org.springframework.http.HttpStatus;
7 | import org.springframework.web.bind.annotation.*;
8 | import ru.practicum.explorewithme.dto.StatDto;
9 | import ru.practicum.explorewithme.dto.StatDtoWithHits;
10 | import ru.practicum.explorewithme.service.StatsService;
11 |
12 | import java.time.LocalDateTime;
13 | import java.util.List;
14 |
15 | @RestController
16 | @Slf4j
17 | @RequiredArgsConstructor
18 | public class StatsController {
19 |
20 | private final StatsService service;
21 |
22 | @PostMapping(path = "/hit")
23 | @ResponseStatus(HttpStatus.CREATED)
24 | public StatDto saveStats(@RequestBody StatDto statDto) {
25 | log.info("POST request for stats received: {}", statDto);
26 | StatDto response = service.saveStats(statDto);
27 | log.info("Stats saved: {}", response);
28 | return response;
29 | }
30 |
31 | @GetMapping(path = "/stats")
32 | public List getStats(
33 | @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime start,
34 | @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime end,
35 | @RequestParam(required = false) List uris,
36 | @RequestParam(required = false, defaultValue = "false") Boolean unique
37 | ) {
38 | log.info("GET request for stats received from {} to {} with uris: {}", start, end, uris);
39 | List response = service.getStats(start, end, uris, unique);
40 | log.info("{}", response);
41 | return response;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/explore-with-me-stats/stats-service/src/main/java/ru/practicum/explorewithme/repository/StatsRepository.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.repository;
2 |
3 | import org.springframework.data.jpa.repository.Query;
4 | import org.springframework.data.repository.query.Param;
5 | import ru.practicum.explorewithme.dto.StatDtoWithHitsProjection;
6 | import ru.practicum.explorewithme.model.Stat;
7 | import org.springframework.data.jpa.repository.JpaRepository;
8 |
9 | import java.time.LocalDateTime;
10 | import java.util.List;
11 |
12 | public interface StatsRepository extends JpaRepository {
13 | @Query(value =
14 | "SELECT st.app AS app, st.uri AS uri, count(DISTINCT st.ip) AS hits " +
15 | "FROM stats st " +
16 | "WHERE (:uris IS NULL OR st.uri IN :uris) " +
17 | "AND (CAST(st.timestamp AS DATE) BETWEEN :start AND :end) " +
18 | "GROUP BY st.app, st.uri " +
19 | "ORDER BY hits DESC",
20 | nativeQuery = true)
21 | List getStatsForTimeIntervalUnique(
22 | @Param("start") LocalDateTime start,
23 | @Param("end") LocalDateTime end,
24 | @Param("uris") List uris
25 | );
26 |
27 | @Query(value =
28 | "SELECT st.app AS app, st.uri AS uri, count(st.ip) AS hits " +
29 | "FROM stats st " +
30 | "WHERE (:uris IS NULL OR st.uri IN :uris) " +
31 | "AND (CAST(st.timestamp AS DATE) BETWEEN :start AND :end) " +
32 | "GROUP BY st.app, st.uri " +
33 | "ORDER BY hits DESC",
34 | nativeQuery = true)
35 | List getStatsForTimeInterval(
36 | @Param("start") LocalDateTime start,
37 | @Param("end") LocalDateTime end,
38 | @Param("uris") List uris
39 | );
40 | }
--------------------------------------------------------------------------------
/explore-wth-me-main/src/main/java/ru/practicum/explorewithme/service/event/StatsServiceClient.java:
--------------------------------------------------------------------------------
1 | package ru.practicum.explorewithme.service.event;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import lombok.NonNull;
6 | import lombok.RequiredArgsConstructor;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.stereotype.Component;
9 | import ru.practicum.explorewithme.StatsClient;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 | import java.time.LocalDateTime;
13 | import java.util.List;
14 | import java.util.Map;
15 |
16 | @Component
17 | @RequiredArgsConstructor
18 | public class StatsServiceClient {
19 |
20 | private final StatsClient statsClient;
21 |
22 | protected int getHits(@NonNull ResponseEntity