Skip to content

Commit

Permalink
Java 21
Browse files Browse the repository at this point in the history
Improved Controller exceptions handling
Added REST endpoints versioning
  • Loading branch information
Denis Halitsky committed Dec 17, 2023
1 parent 9795645 commit 1805a86
Show file tree
Hide file tree
Showing 18 changed files with 198 additions and 112 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ jobs:
steps:
- name: Checkout Sources
uses: actions/checkout@v2
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'adopt'
java-version: '21' s
distribution: 'zulu'
cache: 'maven'
- name: Build All
run: mvn -B package -DskipTests --file pom.xml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ data class ErrorResponse(
var exception: String? = null,
var trace: String? = null
)


data class ErrorDetails(
var pointer: String? = null,
var error: String? = null,
)
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<kotlin.version>1.9.20</kotlin.version>

<spring.boot.version>3.2.0</spring.boot.version>
Expand Down
26 changes: 13 additions & 13 deletions webapp/family.http
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
### Login
POST http://{{server}}/api/v1/user/login
POST http://{{server}}/api/user/v1/login
Content-Type: application/json
Accept: */*

Expand All @@ -9,17 +9,17 @@ Accept: */*
}

### Get Families
GET http://{{server}}/api/v1/lineage/1/families
GET http://{{server}}/api/lineage/v1/1/families
Authorization: Bearer {{authToken}}
Accept: application/json

### Get Family
GET http://{{server}}/api/v1/lineage/1/families/1
GET http://{{server}}/api/lineage/v1/1/families/1
Authorization: Bearer {{authToken}}
Accept: application/json

### Create Family
POST http://{{server}}/api/v1/lineage/1/families
POST http://{{server}}/api/lineage/v1/1/families
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -30,7 +30,7 @@ Accept: application/json
}

### Update Family
POST http://{{server}}/api/v1/lineage/1/families/1
POST http://{{server}}/api/lineage/v1/1/families/1
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -41,11 +41,11 @@ Accept: application/json
}

### Delete Family
DELETE http://{{server}}/api/v1/lineage/1/families/2
DELETE http://{{server}}/api/lineage/v1/1/families/2
Authorization: Bearer {{authToken}}

### Create Child in Family
POST http://{{server}}/api/v1/lineage/1/families/1/children
POST http://{{server}}/api/lineage/v1/1/families/1/children
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -63,22 +63,22 @@ Accept: application/json
}

### Add Child to Family
PATCH http://{{server}}/api/v1/lineage/1/families/1/children/5
PATCH http://{{server}}/api/lineage/v1/1/families/1/children/5
Authorization: Bearer {{authToken}}
Accept: application/json

### Delete Child from Family
DELETE http://{{server}}/api/v1/lineage/1/families/1/children/5
DELETE http://{{server}}/api/lineage/v1/1/families/1/children/5
Authorization: Bearer {{authToken}}
Accept: application/json

###
GET http://{{server}}/api/v1/lineage/1/families/1/children
GET http://{{server}}/api/lineage/v1/1/families/1/children
Authorization: Bearer {{authToken}}
Accept: application/json

### Create Family Event
POST http://{{server}}/api/v1/lineage/1/families/1/events
POST http://{{server}}/api/lineage/v1/1/families/1/events
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -91,11 +91,11 @@ Accept: application/json
}

### Get Family Events
GET http://{{server}}/api/v1/lineage/1/families/1/events
GET http://{{server}}/api/lineage/v1/1/families/1/events
Authorization: Bearer {{authToken}}
Accept: application/json

### Delete Family Event
DELETE http://{{server}}/api/v1/lineage/1/families/1/events/6
DELETE http://{{server}}/api/lineage/v1/1/families/1/events/6
Authorization: Bearer {{authToken}}
Accept: application/json
16 changes: 8 additions & 8 deletions webapp/lineage.http
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
### User login
POST http://{{server}}/api/v1/user/login
POST http://{{server}}/api/user/v1/login
Content-Type: application/json

{
Expand All @@ -8,25 +8,25 @@ Content-Type: application/json
}

### Import Lineage
POST http://{{server}}/api/v1/lineage/import
POST http://{{server}}/api/lineage/v1/import
Authorization: Bearer {{authToken}}
Content-Type: text/ged
Lineage-Name: Test Lineage GED

< ../test-lineage.ged

### Get all Lineages
GET http://{{server}}/api/v1/lineage
GET http://{{server}}/api/lineage/v1
Authorization: Bearer {{authToken}}
Accept: application/json

### Get Lineage
GET http://{{server}}/api/v1/lineage/2
GET http://{{server}}/api/lineage/v1/2
Authorization: Bearer {{authToken}}
Accept: application/json

### Create new Lineage
POST http://{{server}}/api/v1/lineage
POST http://{{server}}/api/lineage/v1
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -37,11 +37,11 @@ Accept: application/json
}

### Delete Lineage
DELETE http://{{server}}/api/v1/lineage/4
DELETE http://{{server}}/api/lineage/v1/4
Authorization: Bearer {{authToken}}

### Update Lineage
PUT http://{{server}}/api/v1/lineage/import
PUT http://{{server}}/api/lineage/v1/import
Authorization: Bearer {{authToken}}
Content-Type: application/json

Expand All @@ -51,6 +51,6 @@ Content-Type: application/json
}

### Export Lineage
GET http://{{server}}/api/v1/lineage/2/export
GET http://{{server}}/api/lineage/v1/2/export
Authorization: Bearer {{authToken}}
Accept: text/ged
26 changes: 13 additions & 13 deletions webapp/person.http
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
### User registration
POST http://{{server}}/api/v1/user/registration
POST http://{{server}}/api/user/v1/registration
Content-Type: application/json

{
Expand All @@ -10,7 +10,7 @@ Content-Type: application/json
}

### User login
POST http://{{server}}/api/v1/user/login
POST http://{{server}}/api/user/v1/login
Content-Type: application/json

{
Expand All @@ -19,16 +19,16 @@ Content-Type: application/json
}

### Get All Persons
GET http://{{server}}/api/v1/lineage/1/persons
GET http://{{server}}/api/lineage/v1/1/persons
Authorization: Bearer {{authToken}}

### Get Person By ID
GET http://{{server}}/api/v1/lineage/1/persons/1
GET http://{{server}}/api/lineage/v1/1/persons/11
Authorization: Bearer {{authToken}}
Accept: application/json

### Create Person
POST http://{{server}}/api/v1/lineage/1/persons
POST http://{{server}}/api/lineage/v1/1/persons
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -46,7 +46,7 @@ Accept: application/json
}

### Update Person
PUT http://{{server}}/api/v1/lineage/1/persons/1
PUT http://{{server}}/api/lineage/v1/1/persons/1
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -64,10 +64,10 @@ Accept: application/json
}

### Delete Person
DELETE http://{{server}}/api/v1/lineage/1/persons/1
DELETE http://{{server}}/api/lineage/v1/1/persons/11

### Create Person Event
POST http://{{server}}/api/v1/lineage/1/persons/1/events
POST http://{{server}}/api/lineage/v1/1/persons/1/events
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand All @@ -80,28 +80,28 @@ Accept: application/json
}

### Get Person Events
GET http://{{server}}/api/v1/lineage/1/persons/1/events
GET http://{{server}}/api/lineage/v1/1/persons/1/events
Authorization: Bearer {{authToken}}
Accept: application/json

### Delete Person Event
DELETE http://{{server}}/api/v1/lineage/1/persons/1/events/1
DELETE http://{{server}}/api/lineage/v1/1/persons/1/events/1
Authorization: Bearer {{authToken}}
Accept: application/json

### Create Person Photo
POST http://{{server}}/api/v1/lineage/1/persons/1/photo
POST http://{{server}}/api/lineage/v1/1/persons/1/photo
Authorization: Bearer {{authToken}}
Content-Type: image/jpeg

< C:\Dist\avatar0.jpg

### Get Person Photo
GET http://{{server}}/api/v1/lineage/1/persons/1/photo
GET http://{{server}}/api/lineage/v1/1/persons/1/photo
Authorization: Bearer {{authToken}}

### Person Search
POST http://{{server}}/api/v1/lineage/1/persons/search
POST http://{{server}}/api/lineage/v1/1/persons/search
Authorization: Bearer {{authToken}}
Content-Type: application/json
Accept: application/json
Expand Down
10 changes: 2 additions & 8 deletions webapp/src/main/kotlin/com/koldyr/genealogy/GenealogyConfig.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.koldyr.genealogy

import ma.glasnost.orika.MapperFacade
import ma.glasnost.orika.impl.DefaultMapperFactory
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.EnableAspectJAutoProxy
Expand All @@ -10,11 +12,8 @@ import org.springframework.http.HttpMethod.HEAD
import org.springframework.http.HttpMethod.PATCH
import org.springframework.http.HttpMethod.POST
import org.springframework.http.HttpMethod.PUT
import org.springframework.web.servlet.HandlerExceptionResolver
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import ma.glasnost.orika.MapperFacade
import ma.glasnost.orika.impl.DefaultMapperFactory
import com.koldyr.genealogy.dto.FamilyDTO
import com.koldyr.genealogy.mapper.FamilyEventConverter
import com.koldyr.genealogy.mapper.PersonConverter
Expand All @@ -24,7 +23,6 @@ import com.koldyr.genealogy.persistence.FamilyEventRepository
import com.koldyr.genealogy.persistence.PersonRepository
import com.koldyr.genealogy.persistence.UserRepository
import com.koldyr.genealogy.services.AuthenticationUserDetailsService
import com.koldyr.genealogy.util.InternalExceptionResolver

/**
* Description of class GenealogyConfig
Expand Down Expand Up @@ -62,10 +60,6 @@ class GenealogyConfig {
fun corsConfigurer(): WebMvcConfigurer {
return object : WebMvcConfigurer {

override fun extendHandlerExceptionResolvers(resolvers: MutableList<HandlerExceptionResolver>) {
resolvers.add(InternalExceptionResolver())
}

override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**")
.allowedOrigins("*")
Expand Down
4 changes: 2 additions & 2 deletions webapp/src/main/kotlin/com/koldyr/genealogy/SecurityConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class SecurityConfig {
.headers { it.disable() }
.authorizeHttpRequests {
it.requestMatchers("/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs", "/v3/api-docs/**", "/error/**", "/favicon.ico").permitAll()
.requestMatchers(POST, "/api/v1/user/**").permitAll()
.requestMatchers("/api/v1/**").authenticated()
.requestMatchers(POST, "/api/user/v1/**").permitAll()
.requestMatchers("/api/lineage/v1/**").authenticated()
}
.oauth2ResourceServer { it.jwt { } }
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
package com.koldyr.genealogy.controllers

import java.time.Instant
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 jakarta.persistence.EntityNotFoundException
import jakarta.servlet.http.HttpServletRequest
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.http.HttpStatus.BAD_REQUEST
import org.springframework.http.HttpStatus.NOT_FOUND
import org.springframework.http.MediaType.APPLICATION_JSON_VALUE
import org.springframework.http.ResponseEntity
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ExceptionHandler
import com.koldyr.genealogy.dto.ErrorResponse

/**
Expand All @@ -29,31 +20,5 @@ import com.koldyr.genealogy.dto.ErrorResponse
content = [Content(schema = Schema(implementation = ErrorResponse::class), mediaType = APPLICATION_JSON_VALUE)]
)
class BaseController {

private val logger = LoggerFactory.getLogger(javaClass)

@ExceptionHandler(MethodArgumentNotValidException::class)
fun handleException(request: HttpServletRequest, ex: MethodArgumentNotValidException): ResponseEntity<Map<String, Any>> {
val error = ex.allErrors.first()
val message = "${error.objectName}.${error.defaultMessage}"
val model = buildModel(BAD_REQUEST, request.requestURI, message)
return ResponseEntity.badRequest().body(model)
}

@ExceptionHandler(EntityNotFoundException::class)
fun handleException(request: HttpServletRequest, ex: EntityNotFoundException): ResponseEntity<Map<String, Any>> {
val message = ex.message!!
val model = buildModel(NOT_FOUND, request.requestURI, message)
return ResponseEntity.status(NOT_FOUND).body(model)
}

private fun buildModel(status: HttpStatus, uri: String, message: String): Map<String, Any> {
return mapOf(
"timestamp" to Instant.now().toString(),
"status" to status.value(),
"error" to status.reasonPhrase,
"message" to message,
"path" to uri
)
}
protected val logger = LoggerFactory.getLogger(javaClass)
}
Loading

0 comments on commit 1805a86

Please sign in to comment.