Skip to content

Commit

Permalink
Merge branch 'feature/45-inquiries'
Browse files Browse the repository at this point in the history
  • Loading branch information
Veselovnd88 committed Jan 30, 2024
2 parents 3a278b8 + 518cce0 commit 799a984
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 27 deletions.
15 changes: 15 additions & 0 deletions src/main/java/ru/veselov/companybot/annotation/PagingParam.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.veselov.companybot.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Mark object that receives Request Params: page и size
* and send it to PagingRequestParamResolver
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface PagingParam {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package ru.veselov.companybot.config;

import org.springframework.core.MethodParameter;
import org.springframework.lang.NonNull;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.RequestParamMethodArgumentResolver;
import ru.veselov.companybot.annotation.PagingParam;
import ru.veselov.companybot.dto.PagingParams;

/**
* Resolve request params to object marked with {@link PagingParam} annotation
*
* @see PagingParam
* @see PagingParams
*/
public class PagingRequestParamsResolver extends RequestParamMethodArgumentResolver {

private static final String PAGE = "page";

private static final String SIZE = "size";


public PagingRequestParamsResolver(boolean useDefaultResolution) {
super(useDefaultResolution);
}

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(PagingParam.class);
}

@Override
protected Object resolveName(@NonNull String name,
@NonNull MethodParameter parameter,
@NonNull NativeWebRequest request) {
return new PagingParams(
resolvePage(request),
resolveSize(request)
);
}

private Integer resolvePage(NativeWebRequest request) {
String page = request.getParameter(PAGE);
return page == null ? 0 : Integer.parseInt(page);
}

private Integer resolveSize(NativeWebRequest request) {
String size = request.getParameter(SIZE);
return size == null ? 20 : Integer.parseInt(size);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ru.veselov.companybot.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
@Slf4j
public class WebMvcConfiguration implements WebMvcConfigurer {

@Override
public void addArgumentResolvers(@NonNull List<HandlerMethodArgumentResolver> resolvers) {
WebMvcConfigurer.super.addArgumentResolvers(resolvers);
resolvers.add(new PagingRequestParamsResolver(true));
log.debug("Setting up Request Param resolvers");
}

@Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true);
filter.setIncludePayload(false);
filter.setMaxPayloadLength(10000);
filter.setIncludeHeaders(false);
filter.setIncludeClientInfo(true);
log.debug("Setting up Request filter for logging http request/response");
return filter;
}

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package ru.veselov.companybot.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.veselov.companybot.annotation.PagingParam;
import ru.veselov.companybot.dto.InquiryResponseDTO;
import ru.veselov.companybot.dto.PagingParams;
import ru.veselov.companybot.service.InquiryService;

import java.util.List;
Expand All @@ -27,16 +32,17 @@ public class InquiryController {

private final InquiryService inquiryService;

@Operation(summary = "Добавить новый отдел",
description = "Принимает название и описание отдела")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "Отдел создан",
content = {@Content(array = @ArraySchema(schema = @Schema(implementation = InquiryResponseDTO.class)),
mediaType = MediaType.APPLICATION_JSON_VALUE)})
})
@Operation(summary = "Получить все запросы",
description = "Выгружает все запросы",
parameters = {
@Parameter(in = ParameterIn.QUERY, name = "page"),
@Parameter(in = ParameterIn.QUERY, name = "size")})
@ApiResponse(responseCode = "200", description = "Запросы успешно получены",
content = {@Content(array = @ArraySchema(schema = @Schema(implementation = InquiryResponseDTO.class)),
mediaType = MediaType.APPLICATION_JSON_VALUE)})
@GetMapping
public List<InquiryResponseDTO> getAll() {
return inquiryService.findAll();
public Page<InquiryResponseDTO> getAll(@Schema(hidden = true) @Valid @PagingParam PagingParams pagingParams) {
return inquiryService.findAll(pagingParams);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.veselov.companybot.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -15,10 +16,13 @@
@AllArgsConstructor
public class ContactResponseDto implements Serializable {

@Schema(description = "Id контакта", example = "8b19a7cf-67f2-47b3-9ddb-9e3d9514d375")
private UUID contactId;

@Schema(description = "Телефонный номер", example = "+7 916 555 55 55")
private String phone;

@Schema(description = "E-mail", example = "email@email.com")
private String email;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ru.veselov.companybot.dto;

import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -14,15 +16,19 @@
@NoArgsConstructor
@AllArgsConstructor
public class CustomerResponseDTO implements Serializable {

@Schema(description = "Id клиента", example = "1000")
private Long id;

@Schema(description = "Имя клиента", example = "Иван")
private String firstName;

@Schema(description = "Фамилия клиента", example = "Петров")
private String lastName;

@Schema(description = "Юзернейм клиента", example = "Ivan")
private String userName;

@ArraySchema(arraySchema = @Schema(implementation = ContactResponseDto.class, description = "Контакты"))
private Set<ContactResponseDto> contacts;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ru.veselov.companybot.dto;

import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -17,14 +19,19 @@
@ToString
public class InquiryResponseDTO implements Serializable {

@Schema(description = "Id запроса", example = "d15a43eb-0bb9-4b15-ac3a-abdf3b77137f")
private UUID inquiryId;

@Schema(description = "Дата запроса", example = "130f4ee4-037f-47b3-9b63-8c3b0ac02574")
private LocalDateTime date;

@Schema(implementation = DivisionModel.class, description = "Отдел")
private DivisionModel division;

@ArraySchema(arraySchema = @Schema(implementation = MessageResponseDTO.class, description = "Сообщения"))
private Set<MessageResponseDTO> messages;

@Schema(implementation = CustomerResponseDTO.class, description = "Клиент")
private CustomerResponseDTO customer;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.veselov.companybot.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -15,8 +16,10 @@
@AllArgsConstructor
public class MessageResponseDTO implements Serializable {

@Schema(description = "Id сообщения", example = "3b4cb719-3489-445d-bb01-ef7958aca896")
private Integer messageId;

@Schema(description = "Текст сообщения", example = "Перезвоните мне")
private String text;

}
17 changes: 17 additions & 0 deletions src/main/java/ru/veselov/companybot/dto/PagingParams.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.veselov.companybot.dto;

import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class PagingParams {

@PositiveOrZero
private Integer page;

@Positive
private Integer size;
}
7 changes: 4 additions & 3 deletions src/main/java/ru/veselov/companybot/mapper/InquiryMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import org.springframework.data.domain.Page;
import ru.veselov.companybot.dto.InquiryResponseDTO;
import ru.veselov.companybot.entity.InquiryEntity;

import java.util.List;

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE,
uses = {CustomerMapper.class, MessageMapper.class})
public interface InquiryMapper {

InquiryResponseDTO entityToDTO(InquiryEntity inquiryEntity);

List<InquiryResponseDTO> entitiesToDTOS(List<InquiryEntity> entities);
default Page<InquiryResponseDTO> entitiesToDTOS(Page<InquiryEntity> entities) {
return entities.map(this::entityToDTO);
}

}
6 changes: 3 additions & 3 deletions src/main/java/ru/veselov/companybot/model/DivisionModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
@Builder
public class DivisionModel implements Serializable {

@Schema(description = "Id of division", example = "3b4cb719-3489-445d-bb01-ef7958aca896")
@Schema(description = "Id отдела", example = "3b4cb719-3489-445d-bb01-ef7958aca896")
private UUID divisionId;

@Schema(description = "Short name of division", example = "Common")
@Schema(description = "Короткое наименование отдела", example = "Common")
private String name;

@Schema(description = "Description of division", example = "Common questions here")
@Schema(description = "Описание отдела", example = "Common questions here")
private String description;

@JsonIgnore
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ru.veselov.companybot.service;

import org.springframework.data.domain.Page;
import ru.veselov.companybot.dto.InquiryResponseDTO;
import ru.veselov.companybot.dto.PagingParams;
import ru.veselov.companybot.model.InquiryModel;

import java.util.List;
Expand All @@ -9,6 +11,6 @@ public interface InquiryService {

InquiryResponseDTO save(InquiryModel inquiry);

List<InquiryResponseDTO> findAll();
Page<InquiryResponseDTO> findAll(PagingParams pagingParams);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.telegram.telegrambots.meta.api.objects.Message;
import ru.veselov.companybot.bot.util.BotUtils;
import ru.veselov.companybot.dto.InquiryResponseDTO;
import ru.veselov.companybot.dto.PagingParams;
import ru.veselov.companybot.entity.CustomerEntity;
import ru.veselov.companybot.entity.CustomerMessageEntity;
import ru.veselov.companybot.entity.DivisionEntity;
Expand All @@ -19,7 +23,6 @@
import ru.veselov.companybot.service.InquiryService;
import ru.veselov.companybot.util.LogMessageUtils;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

Expand Down Expand Up @@ -71,8 +74,9 @@ public InquiryResponseDTO save(InquiryModel inquiry) {
}

@Override
public List<InquiryResponseDTO> findAll() {
List<InquiryResponseDTO> inquiryResponseDTOS = inquiryMapper.entitiesToDTOS(inquiryRepository.findAll());
public Page<InquiryResponseDTO> findAll(PagingParams pagingParams) {
Pageable pageable = PageRequest.of(pagingParams.getPage(), pagingParams.getSize());
Page<InquiryResponseDTO> inquiryResponseDTOS = inquiryMapper.entitiesToDTOS(inquiryRepository.findAll(pageable));
log.debug("Retrieved inquiries from DB");
return inquiryResponseDTOS;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ru.veselov.companybot.it.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import ru.veselov.companybot.config.BotMocks;
import ru.veselov.companybot.config.EnableTestContainers;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@DirtiesContext
@Import({BotMocks.class})
@ActiveProfiles("test")
@EnableTestContainers
class InquiryControllerIntegrationTest {

@Autowired
MockMvc mockMvc;


}
Loading

0 comments on commit 799a984

Please sign in to comment.