From dccc42d8739f17a749f87ac66534b6418241912b Mon Sep 17 00:00:00 2001 From: Konstantin Albatov Date: Sat, 23 Mar 2024 19:21:47 +0300 Subject: [PATCH] :zap: Refactor + Vaadin Stable --- .gitignore | 3 ++ build.gradle.kts | 14 ++++-- docker-compose.dev.yaml | 5 +- docker-compose.local.yaml | 1 + .../SpringSecurityApplication.kt | 4 +- .../config/cache/CacheManagerConfig.kt | 1 - .../config/webclient/TenderApiConfig.kt | 19 +++++++ .../config/webclient/WebClientConfig.kt | 37 ++++++++++++++ .../controller/UserController.kt | 45 ----------------- .../model/database/AbstractEntity.kt | 2 +- .../data/model/dto/TenderDto.java | 22 +++++++++ .../data/model/dto/TenderProviderDto.kt | 13 +++++ .../model/exception/AbstractApiException.kt | 4 +- .../model/exception/NotFoundException.kt | 2 +- .../exception/ValidationErrorException.kt | 2 +- .../model/response/ApiResponse.kt | 2 +- .../repository/CommonRepository.kt | 4 +- .../data/service/TenderService.kt | 25 ++++++++++ .../domain/model/database/User.kt | 19 ------- .../domain/repository/UserRepository.kt | 7 --- .../domain/service/UserService.kt | 17 ------- .../domain/service/impl/UserServiceImpl.kt | 49 ------------------- .../controller/TenderController.kt | 17 +++++++ .../exception}/ExceptionResolver.kt | 8 +-- .../presentation/route/MainRoute.kt | 35 +++++++++++++ src/main/resources/application.yaml | 12 +++-- 26 files changed, 208 insertions(+), 161 deletions(-) create mode 100644 src/main/kotlin/com/albatros/springsecurity/config/webclient/TenderApiConfig.kt create mode 100644 src/main/kotlin/com/albatros/springsecurity/config/webclient/WebClientConfig.kt delete mode 100644 src/main/kotlin/com/albatros/springsecurity/controller/UserController.kt rename src/main/kotlin/com/albatros/springsecurity/{domain => data}/model/database/AbstractEntity.kt (89%) create mode 100644 src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderDto.java create mode 100644 src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderProviderDto.kt rename src/main/kotlin/com/albatros/springsecurity/{domain => data}/model/exception/AbstractApiException.kt (75%) rename src/main/kotlin/com/albatros/springsecurity/{domain => data}/model/exception/NotFoundException.kt (79%) rename src/main/kotlin/com/albatros/springsecurity/{domain => data}/model/exception/ValidationErrorException.kt (86%) rename src/main/kotlin/com/albatros/springsecurity/{domain => data}/model/response/ApiResponse.kt (80%) rename src/main/kotlin/com/albatros/springsecurity/{domain => data}/repository/CommonRepository.kt (66%) create mode 100644 src/main/kotlin/com/albatros/springsecurity/data/service/TenderService.kt delete mode 100644 src/main/kotlin/com/albatros/springsecurity/domain/model/database/User.kt delete mode 100644 src/main/kotlin/com/albatros/springsecurity/domain/repository/UserRepository.kt delete mode 100644 src/main/kotlin/com/albatros/springsecurity/domain/service/UserService.kt delete mode 100644 src/main/kotlin/com/albatros/springsecurity/domain/service/impl/UserServiceImpl.kt create mode 100644 src/main/kotlin/com/albatros/springsecurity/presentation/controller/TenderController.kt rename src/main/kotlin/com/albatros/springsecurity/{controller => presentation/exception}/ExceptionResolver.kt (83%) create mode 100644 src/main/kotlin/com/albatros/springsecurity/presentation/route/MainRoute.kt diff --git a/.gitignore b/.gitignore index 93d73c9..c140506 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ +./frontend +frontend +./frontend/ ### STS ### .apt_generated diff --git a/build.gradle.kts b/build.gradle.kts index cadcabf..75b9dfa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,6 +15,7 @@ plugins { kotlin("plugin.noarg") version "1.9.10" kotlin("plugin.allopen") version "1.9.10" id("com.google.cloud.tools.jib") version "3.3.1" + id("com.vaadin") version "24.3.7" } allOpen { @@ -63,18 +64,23 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-data-elasticsearch") // Vaadin - //implementation("com.vaadin:vaadin-spring-boot-starter") + implementation("com.vaadin:vaadin-spring-boot-starter") - // Lombok - compileOnly("org.projectlombok:lombok") + // Kotlin implementation("org.jetbrains.kotlin:kotlin-reflect") + + // Lombok annotationProcessor("org.projectlombok:lombok") + compileOnly("org.projectlombok:lombok") // Persistence implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-data-redis") runtimeOnly("org.postgresql:postgresql") + // WebClient + implementation("org.springframework.boot:spring-boot-starter-webflux") + // Swagger-UI + OpenApi implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0") @@ -95,7 +101,7 @@ dependencies { dependencyManagement { imports { - // mavenBom("com.vaadin:vaadin-bom:24.3.7") + mavenBom("com.vaadin:vaadin-bom:24.3.7") mavenBom("org.springframework.ai:spring-ai-bom:0.8.1") } } diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml index 1f1aacd..5bbdabc 100644 --- a/docker-compose.dev.yaml +++ b/docker-compose.dev.yaml @@ -11,6 +11,7 @@ services: depends_on: - db - redis + - search environment: - 'SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/database' - 'SPRING_DATASOURCE_USERNAME=user' @@ -47,7 +48,7 @@ services: max-file: "10" environment: - 'discovery.type=single-node' + - 'xpack.security.enabled=false' ports: - "9200:9200" - - "9600:9600" - + - "9600:9600" \ No newline at end of file diff --git a/docker-compose.local.yaml b/docker-compose.local.yaml index 9b21e53..214d993 100644 --- a/docker-compose.local.yaml +++ b/docker-compose.local.yaml @@ -9,6 +9,7 @@ services: depends_on: - db - redis + - search environment: - 'SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/database' - 'SPRING_DATASOURCE_USERNAME=user' diff --git a/src/main/kotlin/com/albatros/springsecurity/SpringSecurityApplication.kt b/src/main/kotlin/com/albatros/springsecurity/SpringSecurityApplication.kt index ffb7728..b4b1a37 100644 --- a/src/main/kotlin/com/albatros/springsecurity/SpringSecurityApplication.kt +++ b/src/main/kotlin/com/albatros/springsecurity/SpringSecurityApplication.kt @@ -1,14 +1,16 @@ package com.albatros.springsecurity import com.albatros.springsecurity.config.api.ApiInfoConfig +import com.albatros.springsecurity.config.webclient.TenderApiConfig import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.runApplication import org.springframework.cache.annotation.EnableCaching import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories +@EnableCaching @SpringBootApplication -@EnableConfigurationProperties(ApiInfoConfig::class) +@EnableConfigurationProperties(ApiInfoConfig::class, TenderApiConfig::class) @EnableElasticsearchRepositories class SpringSecurityApplication diff --git a/src/main/kotlin/com/albatros/springsecurity/config/cache/CacheManagerConfig.kt b/src/main/kotlin/com/albatros/springsecurity/config/cache/CacheManagerConfig.kt index 5b9414a..4d99b33 100644 --- a/src/main/kotlin/com/albatros/springsecurity/config/cache/CacheManagerConfig.kt +++ b/src/main/kotlin/com/albatros/springsecurity/config/cache/CacheManagerConfig.kt @@ -11,7 +11,6 @@ import java.util.Collections @Configuration class CacheManagerConfig { - companion object { val timeToLiveDuration: Duration = Duration.ofSeconds(40_000) } diff --git a/src/main/kotlin/com/albatros/springsecurity/config/webclient/TenderApiConfig.kt b/src/main/kotlin/com/albatros/springsecurity/config/webclient/TenderApiConfig.kt new file mode 100644 index 0000000..09e9cbc --- /dev/null +++ b/src/main/kotlin/com/albatros/springsecurity/config/webclient/TenderApiConfig.kt @@ -0,0 +1,19 @@ +package com.albatros.springsecurity.config.webclient + +import jakarta.validation.constraints.Min +import jakarta.validation.constraints.NotEmpty +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.validation.annotation.Validated + +@Validated +@EnableConfigurationProperties(TenderApiConfig::class) +@ConfigurationProperties(prefix = "tender-config") +data class TenderApiConfig( + @field:NotEmpty + val apiUrl: String, + @field:NotEmpty + val apiKey: String, + @field:Min(0) + val timeoutMs: Int +) diff --git a/src/main/kotlin/com/albatros/springsecurity/config/webclient/WebClientConfig.kt b/src/main/kotlin/com/albatros/springsecurity/config/webclient/WebClientConfig.kt new file mode 100644 index 0000000..8abd78f --- /dev/null +++ b/src/main/kotlin/com/albatros/springsecurity/config/webclient/WebClientConfig.kt @@ -0,0 +1,37 @@ +package com.albatros.springsecurity.config.webclient + +import io.netty.channel.ChannelOption +import io.netty.handler.timeout.ReadTimeoutHandler +import io.netty.handler.timeout.WriteTimeoutHandler +import java.util.concurrent.TimeUnit +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.client.reactive.ReactorClientHttpConnector +import org.springframework.http.codec.xml.Jaxb2XmlDecoder +import org.springframework.http.codec.xml.Jaxb2XmlEncoder +import org.springframework.web.reactive.function.client.ExchangeStrategies +import org.springframework.web.reactive.function.client.WebClient +import reactor.netty.http.client.HttpClient + +@Configuration +class WebClientConfig( + private val tenderApiConfig: TenderApiConfig +) { + + fun clientHttpConnector() = ReactorClientHttpConnector( + HttpClient.create().apply { + option(ChannelOption.CONNECT_TIMEOUT_MILLIS, tenderApiConfig.timeoutMs).doOnConnected { + it.addHandlerLast(ReadTimeoutHandler(tenderApiConfig.timeoutMs.toLong(), TimeUnit.MILLISECONDS)) + it.addHandlerLast(WriteTimeoutHandler(tenderApiConfig.timeoutMs.toLong(), TimeUnit.MILLISECONDS)) + } + } + ) + + @Bean + fun webClientWithTimeOut() = WebClient.builder().exchangeStrategies( + ExchangeStrategies.builder().codecs { + it.defaultCodecs().jaxb2Decoder(Jaxb2XmlDecoder()) + it.defaultCodecs().jaxb2Encoder(Jaxb2XmlEncoder()) + }.build() + ).clientConnector(clientHttpConnector()).baseUrl(tenderApiConfig.apiUrl).build() +} \ No newline at end of file diff --git a/src/main/kotlin/com/albatros/springsecurity/controller/UserController.kt b/src/main/kotlin/com/albatros/springsecurity/controller/UserController.kt deleted file mode 100644 index 1bd3709..0000000 --- a/src/main/kotlin/com/albatros/springsecurity/controller/UserController.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.albatros.springsecurity.controller - -import com.albatros.springsecurity.domain.model.database.User -import com.albatros.springsecurity.domain.service.UserService -import jakarta.validation.Valid -import org.springframework.ai.chat.ChatClient -import org.springframework.ai.chat.prompt.Prompt -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.data.domain.Pageable -import org.springframework.validation.annotation.Validated -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@Validated -@RestController -@RequestMapping("/user") -class UserController(private val service: UserService) { - - @Autowired - lateinit var client: ChatClient - - @GetMapping("/ai/{command}") - fun command(@PathVariable command: String): String? { - return client.call("Привет, можешь рассказать анекдот о русском и американце?") - } - - @GetMapping("/get/all") - fun getAll() = service.list() - - @GetMapping("/get/all/paginated") - fun getAllPaginated(page: Pageable) = service.listPaginated(page) - - @GetMapping("/delete/{userId}") - fun deleteUser(@PathVariable userId: Long) = service.deleteById(userId) - - @PostMapping("/save", consumes = ["application/json"]) - fun saveUser(@Valid @RequestBody user: User) = service.saveUser(user) - - @GetMapping("/get/{userId}") - fun getById(@PathVariable userId: Long) = service.getUserById(userId) -} diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/model/database/AbstractEntity.kt b/src/main/kotlin/com/albatros/springsecurity/data/model/database/AbstractEntity.kt similarity index 89% rename from src/main/kotlin/com/albatros/springsecurity/domain/model/database/AbstractEntity.kt rename to src/main/kotlin/com/albatros/springsecurity/data/model/database/AbstractEntity.kt index c454310..16d7eed 100644 --- a/src/main/kotlin/com/albatros/springsecurity/domain/model/database/AbstractEntity.kt +++ b/src/main/kotlin/com/albatros/springsecurity/data/model/database/AbstractEntity.kt @@ -1,4 +1,4 @@ -package com.albatros.springsecurity.domain.model.database +package com.albatros.springsecurity.data.model.database import jakarta.persistence.Column import jakarta.persistence.GeneratedValue diff --git a/src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderDto.java b/src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderDto.java new file mode 100644 index 0000000..464525c --- /dev/null +++ b/src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderDto.java @@ -0,0 +1,22 @@ +package com.albatros.springsecurity.data.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class TenderDto { + private int ID; + private String Date; + private String TenderName; + private String Customer; + private String Category; + private String Region; + private Long Price; + private String EndTime; + private String Etp; + private String TenderLink; + private String TenderLinkInner; + @JsonProperty("User_id") + private int UserId; + private String CustomerINN; +} diff --git a/src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderProviderDto.kt b/src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderProviderDto.kt new file mode 100644 index 0000000..f7a8a13 --- /dev/null +++ b/src/main/kotlin/com/albatros/springsecurity/data/model/dto/TenderProviderDto.kt @@ -0,0 +1,13 @@ +package com.albatros.springsecurity.data.model.dto + +import com.fasterxml.jackson.annotation.JsonProperty +import java.io.Serializable + +class TenderProviderDto( + @JsonProperty("ID") + var id: Int, + @JsonProperty("EtpName") + var etpName: String, + @JsonProperty("EtpLink") + var etpLink: String +) : Serializable diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/model/exception/AbstractApiException.kt b/src/main/kotlin/com/albatros/springsecurity/data/model/exception/AbstractApiException.kt similarity index 75% rename from src/main/kotlin/com/albatros/springsecurity/domain/model/exception/AbstractApiException.kt rename to src/main/kotlin/com/albatros/springsecurity/data/model/exception/AbstractApiException.kt index 2713537..3331bbe 100644 --- a/src/main/kotlin/com/albatros/springsecurity/domain/model/exception/AbstractApiException.kt +++ b/src/main/kotlin/com/albatros/springsecurity/data/model/exception/AbstractApiException.kt @@ -1,6 +1,6 @@ -package com.albatros.springsecurity.domain.model.exception +package com.albatros.springsecurity.data.model.exception -import com.albatros.springsecurity.domain.model.response.ApiResponse +import com.albatros.springsecurity.data.model.response.ApiResponse import com.fasterxml.jackson.annotation.JsonIgnoreProperties import org.springframework.http.HttpStatus diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/model/exception/NotFoundException.kt b/src/main/kotlin/com/albatros/springsecurity/data/model/exception/NotFoundException.kt similarity index 79% rename from src/main/kotlin/com/albatros/springsecurity/domain/model/exception/NotFoundException.kt rename to src/main/kotlin/com/albatros/springsecurity/data/model/exception/NotFoundException.kt index 1c44250..eb1ad45 100644 --- a/src/main/kotlin/com/albatros/springsecurity/domain/model/exception/NotFoundException.kt +++ b/src/main/kotlin/com/albatros/springsecurity/data/model/exception/NotFoundException.kt @@ -1,4 +1,4 @@ -package com.albatros.springsecurity.domain.model.exception +package com.albatros.springsecurity.data.model.exception import org.springframework.http.HttpStatus diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/model/exception/ValidationErrorException.kt b/src/main/kotlin/com/albatros/springsecurity/data/model/exception/ValidationErrorException.kt similarity index 86% rename from src/main/kotlin/com/albatros/springsecurity/domain/model/exception/ValidationErrorException.kt rename to src/main/kotlin/com/albatros/springsecurity/data/model/exception/ValidationErrorException.kt index bef15bc..aea052b 100644 --- a/src/main/kotlin/com/albatros/springsecurity/domain/model/exception/ValidationErrorException.kt +++ b/src/main/kotlin/com/albatros/springsecurity/data/model/exception/ValidationErrorException.kt @@ -1,4 +1,4 @@ -package com.albatros.springsecurity.domain.model.exception +package com.albatros.springsecurity.data.model.exception import org.springframework.http.HttpStatus diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/model/response/ApiResponse.kt b/src/main/kotlin/com/albatros/springsecurity/data/model/response/ApiResponse.kt similarity index 80% rename from src/main/kotlin/com/albatros/springsecurity/domain/model/response/ApiResponse.kt rename to src/main/kotlin/com/albatros/springsecurity/data/model/response/ApiResponse.kt index b3c45a9..ce06e5f 100644 --- a/src/main/kotlin/com/albatros/springsecurity/domain/model/response/ApiResponse.kt +++ b/src/main/kotlin/com/albatros/springsecurity/data/model/response/ApiResponse.kt @@ -1,4 +1,4 @@ -package com.albatros.springsecurity.domain.model.response +package com.albatros.springsecurity.data.model.response import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/repository/CommonRepository.kt b/src/main/kotlin/com/albatros/springsecurity/data/repository/CommonRepository.kt similarity index 66% rename from src/main/kotlin/com/albatros/springsecurity/domain/repository/CommonRepository.kt rename to src/main/kotlin/com/albatros/springsecurity/data/repository/CommonRepository.kt index 13cd1e9..61dc4eb 100644 --- a/src/main/kotlin/com/albatros/springsecurity/domain/repository/CommonRepository.kt +++ b/src/main/kotlin/com/albatros/springsecurity/data/repository/CommonRepository.kt @@ -1,6 +1,6 @@ -package com.albatros.springsecurity.domain.repository +package com.albatros.springsecurity.data.repository -import com.albatros.springsecurity.domain.model.database.AbstractEntity +import com.albatros.springsecurity.data.model.database.AbstractEntity import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.repository.NoRepositoryBean diff --git a/src/main/kotlin/com/albatros/springsecurity/data/service/TenderService.kt b/src/main/kotlin/com/albatros/springsecurity/data/service/TenderService.kt new file mode 100644 index 0000000..5729ac4 --- /dev/null +++ b/src/main/kotlin/com/albatros/springsecurity/data/service/TenderService.kt @@ -0,0 +1,25 @@ +package com.albatros.springsecurity.data.service + +import com.albatros.springsecurity.config.webclient.TenderApiConfig +import com.albatros.springsecurity.data.model.dto.TenderProviderDto +import org.springframework.http.MediaType +import org.springframework.stereotype.Service +import org.springframework.web.reactive.function.client.WebClient + +@Service +class TenderService( + private val tenderApiConfig: TenderApiConfig, + private val webClient: WebClient +) { + fun getAllTenderProviders(mode: String = "eauc"): MutableList? = webClient + .get() + .uri("/export?mode=$mode&api_code=${tenderApiConfig.apiKey}&dtype=json") + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToFlux(TenderProviderDto::class.java) + .collectList() + .block() + + + +} \ No newline at end of file diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/model/database/User.kt b/src/main/kotlin/com/albatros/springsecurity/domain/model/database/User.kt deleted file mode 100644 index 88f55b0..0000000 --- a/src/main/kotlin/com/albatros/springsecurity/domain/model/database/User.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.albatros.springsecurity.domain.model.database - -import jakarta.persistence.Column -import jakarta.persistence.Entity -import jakarta.validation.constraints.Email -import jakarta.validation.constraints.NotBlank -import org.springframework.validation.annotation.Validated -import java.io.Serializable - -@Entity(name = "users") -@Validated -class User( - @Column(nullable = false, length = 30) - @field:NotBlank - var name: String, - @Column(nullable = false, length = 125) - @field:Email - var email: String, -) : AbstractEntity(), Serializable diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/repository/UserRepository.kt b/src/main/kotlin/com/albatros/springsecurity/domain/repository/UserRepository.kt deleted file mode 100644 index 598788c..0000000 --- a/src/main/kotlin/com/albatros/springsecurity/domain/repository/UserRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.albatros.springsecurity.domain.repository - -import com.albatros.springsecurity.domain.model.database.User -import org.springframework.stereotype.Repository - -@Repository -interface UserRepository : CommonRepository diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/service/UserService.kt b/src/main/kotlin/com/albatros/springsecurity/domain/service/UserService.kt deleted file mode 100644 index d8c57ae..0000000 --- a/src/main/kotlin/com/albatros/springsecurity/domain/service/UserService.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.albatros.springsecurity.domain.service - -import com.albatros.springsecurity.domain.model.database.User -import jakarta.validation.Valid -import org.springframework.data.domain.Pageable -import org.springframework.data.domain.Slice -import org.springframework.validation.annotation.Validated - -@Validated -interface UserService { - fun deleteById(userId: Long) - fun saveUser(@Valid user: User): User - fun getUserById(userId: Long): User - fun list(): List - fun listPaginated(page: Pageable): Slice - fun updateUser(@Valid user: User, userId: Long): User -} diff --git a/src/main/kotlin/com/albatros/springsecurity/domain/service/impl/UserServiceImpl.kt b/src/main/kotlin/com/albatros/springsecurity/domain/service/impl/UserServiceImpl.kt deleted file mode 100644 index 99cc568..0000000 --- a/src/main/kotlin/com/albatros/springsecurity/domain/service/impl/UserServiceImpl.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.albatros.springsecurity.domain.service.impl - -import com.albatros.springsecurity.domain.model.database.User -import com.albatros.springsecurity.domain.model.exception.NotFoundException -import com.albatros.springsecurity.domain.repository.UserRepository -import com.albatros.springsecurity.domain.service.UserService -import jakarta.validation.Valid -import org.springframework.cache.annotation.CacheEvict -import org.springframework.cache.annotation.CachePut -import org.springframework.cache.annotation.Cacheable -import org.springframework.cache.annotation.Caching -import org.springframework.data.domain.Pageable -import org.springframework.data.domain.Slice -import org.springframework.stereotype.Service -import org.springframework.validation.annotation.Validated - -@Service -@Validated -class UserServiceImpl(private val repository: UserRepository) : UserService { - - @Caching( - put = [CachePut(value = ["User"], key = "#user.id")], - evict = [CacheEvict(value = ["Users"], allEntries = true)] - ) - override fun saveUser(@Valid user: User) = repository.save(user) - - @Cacheable(value = ["User"], key = "#userId") - override fun getUserById(userId: Long): User = repository.findEntityById(userId) ?: throw NotFoundException() - - @Cacheable(value = ["Users"]) - override fun list(): List = repository.findAll() - - override fun listPaginated(page: Pageable): Slice = repository.findAll(page) - - @Caching( - evict = [ - CacheEvict(value = ["Users"], allEntries = true), - CacheEvict(value = ["User"], key = "#userId") - ] - ) - override fun deleteById(userId: Long) = repository.deleteById(userId) - - @CachePut(value = ["User"], key = "#userId") - override fun updateUser(@Valid user: User, userId: Long): User { - val found = repository.findEntityById(userId) ?: throw NotFoundException() - found.name = user.name - return repository.save(found) - } -} diff --git a/src/main/kotlin/com/albatros/springsecurity/presentation/controller/TenderController.kt b/src/main/kotlin/com/albatros/springsecurity/presentation/controller/TenderController.kt new file mode 100644 index 0000000..b841a31 --- /dev/null +++ b/src/main/kotlin/com/albatros/springsecurity/presentation/controller/TenderController.kt @@ -0,0 +1,17 @@ +package com.albatros.springsecurity.presentation.controller + +import com.albatros.springsecurity.data.service.TenderService +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/api/tender") +class TenderController( + private val tenderService: TenderService +) { + + @GetMapping("/") + fun getAll() = tenderService.getAllTenderProviders() + +} \ No newline at end of file diff --git a/src/main/kotlin/com/albatros/springsecurity/controller/ExceptionResolver.kt b/src/main/kotlin/com/albatros/springsecurity/presentation/exception/ExceptionResolver.kt similarity index 83% rename from src/main/kotlin/com/albatros/springsecurity/controller/ExceptionResolver.kt rename to src/main/kotlin/com/albatros/springsecurity/presentation/exception/ExceptionResolver.kt index 3171236..f7c7d35 100644 --- a/src/main/kotlin/com/albatros/springsecurity/controller/ExceptionResolver.kt +++ b/src/main/kotlin/com/albatros/springsecurity/presentation/exception/ExceptionResolver.kt @@ -1,8 +1,8 @@ -package com.albatros.springsecurity.controller +package com.albatros.springsecurity.presentation.exception -import com.albatros.springsecurity.domain.model.exception.AbstractApiException -import com.albatros.springsecurity.domain.model.exception.ValidationErrorException -import com.albatros.springsecurity.domain.model.response.ApiResponse +import com.albatros.springsecurity.data.model.exception.AbstractApiException +import com.albatros.springsecurity.data.model.exception.ValidationErrorException +import com.albatros.springsecurity.data.model.response.ApiResponse import jakarta.validation.ConstraintViolationException import org.springframework.http.ResponseEntity import org.springframework.web.bind.MethodArgumentNotValidException diff --git a/src/main/kotlin/com/albatros/springsecurity/presentation/route/MainRoute.kt b/src/main/kotlin/com/albatros/springsecurity/presentation/route/MainRoute.kt new file mode 100644 index 0000000..978dbb4 --- /dev/null +++ b/src/main/kotlin/com/albatros/springsecurity/presentation/route/MainRoute.kt @@ -0,0 +1,35 @@ +package com.albatros.springsecurity.presentation.route + +import com.albatros.springsecurity.data.model.dto.TenderProviderDto +import com.albatros.springsecurity.data.service.TenderService +import com.vaadin.flow.component.Text +import com.vaadin.flow.component.button.Button +import com.vaadin.flow.component.grid.Grid +import com.vaadin.flow.component.notification.Notification +import com.vaadin.flow.component.orderedlayout.VerticalLayout +import com.vaadin.flow.router.Route + +@Route("") +class MainRoute( + tenderService: TenderService +) : VerticalLayout() { + + init { + add( + Text("Lig ma who?"), + Button( + "Lig ma Balls" + ) { + Notification.show("CDs nuts").open() + }, + Grid().apply { + addColumn(TenderProviderDto::id).setHeader("Id") + addColumn(TenderProviderDto::etpName).setHeader("Name") + + setItems( + tenderService.getAllTenderProviders() + ) + } + ) + } +} \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 4954815..c12c14f 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -3,7 +3,6 @@ server: spring: - application: name: spring-security @@ -75,13 +74,18 @@ api-info: contact-email: ${INFO_EMAIL:albatovkonstantin@yandex.ru} contact-url: ${INFO_CONTACT:https://idk.com} contact-name: ${INFO_NAME:Albatov Konstantin} - description: ${INFO_DESCR:Spring Security App On Steroids} - external-docs-description: ${INFO_EXT_DESCR:External docs :)} + description: ${INFO_DESCR:Spring boot app for Tender Hackathon} + external-docs-description: ${INFO_EXT_DESCR:Some docs that are not written yet} license-url: ${INFO_LICENSE_URL:https://idk.com} external-docs-url: ${INFO_EXT_URL:https://idk.com} license-name: ${INFO_LICENSE_NAME:License Name} - title: ${INFO_TITLE:Spring Security} + title: ${INFO_TITLE:Tender Hackathon} version: ${INFO_VERSION:v0.0.1} tender-config: api-key: ${TENDER_API_KEY:a1PpB1yRL59q42A2} + api-url: ${TENDER_API_URL:https://www.tenderguru.ru/api2.3/} + timeout-ms: 10000 + +vaadin: + exclude-urls: /swagger-ui/*, /api/*, /swagger-ui/index.html, /api-docs, v3/api-docs \ No newline at end of file