Skip to content

Commit 4b22510

Browse files
Task/wd 330 (#21)
* WD-330 Update versions of java & libs, fix HashUtils * WD-330 Fix message interpolator, strict email validator * WD-330 optimize imports * WD-330 CI optimization Co-authored-by: Alex Shvedov <alexeii.shvedov@gmail.com>
1 parent ae51c2f commit 4b22510

File tree

12 files changed

+148
-38
lines changed

12 files changed

+148
-38
lines changed

.github/workflows/check.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Checking build&tests
2+
on:
3+
pull_request:
4+
branches:
5+
- master
6+
- develop
7+
jobs:
8+
gradle:
9+
strategy:
10+
matrix:
11+
os: [ubuntu-latest]
12+
runs-on: ${{ matrix.os }}
13+
steps:
14+
- uses: actions/checkout@v2
15+
- uses: actions/setup-java@v1
16+
with:
17+
java-version: 11
18+
- name: Build and test
19+
run: ./gradlew build

.github/workflows/distribution.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,5 @@ jobs:
1313
- uses: actions/setup-java@v1
1414
with:
1515
java-version: 11
16-
- uses: eskatos/gradle-command-action@v1
17-
with:
18-
arguments: build
19-
- uses: eskatos/gradle-command-action@v1
20-
with:
21-
arguments: :web-utils:publish -DBINTRAY_USER=${{ secrets.BINTRAY_USER }} -DBINTRAY_KEY=${{ secrets.BINTRAY_KEY }} -PlibraryPublish
16+
- name: Build and publish to Bintray
17+
run: ./gradlew :web-utils:publish -DBINTRAY_USER=${{ secrets.BINTRAY_USER }} -DBINTRAY_KEY=${{ secrets.BINTRAY_KEY }} -PlibraryPublish

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ javax_validation=2.0.0.Final
1313
javax_el_version=2.2.6
1414
javax_el_api_version=3.0.0
1515
beanutils_version=1.9.4
16-
hibernate_validator_version=6.0.2.Final
16+
hibernate_validator_version=6.1.5.Final
1717
hibernate_validator_annotation_processor_version=6.0.2.Final
1818
# I18N
1919
gnu_gettext_version=0.18.3

sample/src/main/kotlin/com/icerockdev/sample/server.kt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ package com.icerockdev.sample
77
import com.fasterxml.jackson.databind.SerializationFeature
88
import com.icerockdev.api.AbstractResponse
99
import com.icerockdev.api.Request
10+
import com.icerockdev.api.request.QueryParser
11+
import com.icerockdev.api.request.receiveQuery
1012
import com.icerockdev.exception.ForbiddenException
1113
import com.icerockdev.exception.ServerErrorException
1214
import com.icerockdev.exception.ValidationException
13-
import com.icerockdev.api.request.QueryParser
14-
import com.icerockdev.api.request.receiveQuery
15-
import com.icerockdev.webserver.*
15+
import com.icerockdev.webserver.applyCallConfiguration
16+
import com.icerockdev.webserver.applyDefaultCORS
17+
import com.icerockdev.webserver.applyDefaultLogging
18+
import com.icerockdev.webserver.applyObjectMapper
19+
import com.icerockdev.webserver.applyStatusConfiguration
20+
import com.icerockdev.webserver.getMonitoringPipeline
1621
import com.icerockdev.webserver.log.JsonDataLogger
1722
import com.icerockdev.webserver.log.JsonSecret
1823
import com.icerockdev.webserver.log.LoggingConfiguration
@@ -22,7 +27,12 @@ import io.ktor.application.Application
2227
import io.ktor.application.ApplicationCallPipeline
2328
import io.ktor.application.call
2429
import io.ktor.application.install
25-
import io.ktor.features.*
30+
import io.ktor.features.CORS
31+
import io.ktor.features.CallId
32+
import io.ktor.features.CallLogging
33+
import io.ktor.features.ContentNegotiation
34+
import io.ktor.features.DefaultHeaders
35+
import io.ktor.features.StatusPages
2636
import io.ktor.jackson.jackson
2737
import io.ktor.response.respond
2838
import io.ktor.routing.get

web-utils/src/main/kotlin/com/icerockdev/api/Request.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ package com.icerockdev.api
66

77
import com.fasterxml.jackson.annotation.JsonIgnore
88
import com.icerockdev.exception.ValidatorException
9-
import javax.validation.*
9+
import javax.validation.ConstraintViolation
10+
import javax.validation.MessageInterpolator
11+
import javax.validation.Validation
12+
import javax.validation.Validator
13+
import javax.validation.ValidatorFactory
1014
import kotlin.reflect.KClass
1115
import kotlin.reflect.full.memberProperties
1216

web-utils/src/main/kotlin/com/icerockdev/i18n/I18N.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
package com.icerockdev.i18n
66

77
import gnu.gettext.GettextResource
8-
import java.util.*
8+
import java.util.Locale
9+
import java.util.MissingResourceException
10+
import java.util.ResourceBundle
911

1012

1113
class I18N(

web-utils/src/main/kotlin/com/icerockdev/i18n/I18NMessageInterpolator.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44

55
package com.icerockdev.i18n
66

7-
import org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator
8-
import java.util.*
7+
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator
8+
import java.util.Locale
99
import javax.validation.MessageInterpolator
1010

11-
class I18NMessageInterpolator(private val i18n: I18N) : AbstractMessageInterpolator() {
11+
class I18NMessageInterpolator(private val i18n: I18N) : ParameterMessageInterpolator() {
1212
override fun interpolate(messageTemplate: String?, context: MessageInterpolator.Context?): String {
13-
return i18n.t(interpolate(context, i18n.locale, messageTemplate))
13+
return interpolateMessage(messageTemplate, context, i18n.locale)
1414
}
1515

1616
override fun interpolate(messageTemplate: String?, context: MessageInterpolator.Context?, locale: Locale?): String {
17-
return i18n.t(interpolate(context, locale, messageTemplate), "", locale)
17+
return interpolateMessage(messageTemplate, context, locale)
1818
}
1919

20-
override fun interpolate(context: MessageInterpolator.Context?, locale: Locale?, term: String?): String {
21-
return super.interpolate(term, context, locale)
20+
private fun interpolateMessage(message: String? , context: MessageInterpolator.Context?, locale: Locale?): String {
21+
return i18n.t(super.interpolate(message, context, locale), "", locale)
2222
}
2323
}

web-utils/src/main/kotlin/com/icerockdev/validation/StrictEmail.kt

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,71 @@
44

55
package com.icerockdev.validation
66

7+
import org.hibernate.validator.internal.constraintvalidators.AbstractEmailValidator
8+
import org.hibernate.validator.internal.util.logging.LoggerFactory
9+
import java.lang.invoke.MethodHandles
10+
import java.util.regex.Pattern.compile
11+
import java.util.regex.PatternSyntaxException
712
import javax.validation.Constraint
13+
import javax.validation.ConstraintValidatorContext
814
import javax.validation.Payload
9-
import javax.validation.constraints.Email
1015
import javax.validation.constraints.Pattern
16+
import kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS
17+
import kotlin.annotation.AnnotationTarget.CONSTRUCTOR
18+
import kotlin.annotation.AnnotationTarget.FIELD
19+
import kotlin.annotation.AnnotationTarget.FUNCTION
20+
import kotlin.annotation.AnnotationTarget.TYPE_PARAMETER
21+
import kotlin.annotation.AnnotationTarget.VALUE_PARAMETER
1122
import kotlin.reflect.KClass
1223

13-
@Target(AnnotationTarget.FIELD)
14-
@Email
15-
@Pattern(regexp = ".+@.+\\..+", message = "{javax.validation.constraints.Email.message}")
16-
@Constraint(validatedBy = [])
17-
@MustBeDocumented
24+
const val DEFAULT_EMAIL_REGEXP = ".+@.+\\..+"
25+
26+
/**
27+
* Annotation to validate email
28+
*
29+
* Example, validate field
30+
* @field:StrictEmail(message = "Invalid email")
31+
*/
32+
@Constraint(validatedBy = [StrictEmailValidator::class])
33+
@Target(allowedTargets = [FUNCTION, FIELD, ANNOTATION_CLASS, CONSTRUCTOR, VALUE_PARAMETER, TYPE_PARAMETER])
34+
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
1835
annotation class StrictEmail(
1936
val message: String = "{javax.validation.constraints.Email.message}",
2037
val groups: Array<KClass<*>> = [],
21-
val payload: Array<KClass<out Payload>> = []
38+
val payload: Array<KClass<out Payload>> = [],
39+
val regexp: String = DEFAULT_EMAIL_REGEXP,
40+
val flags: Array<Pattern.Flag> = []
2241
)
42+
43+
class StrictEmailValidator : AbstractEmailValidator<StrictEmail?>() {
44+
private var pattern: java.util.regex.Pattern = compile(DEFAULT_EMAIL_REGEXP, 0)
45+
override fun initialize(constraintAnnotation: StrictEmail?) {
46+
super.initialize(constraintAnnotation)
47+
val flags: Array<Pattern.Flag> = constraintAnnotation?.flags ?: arrayOf()
48+
var intFlag = 0
49+
for (flag in flags) {
50+
intFlag = intFlag.or(flag.value)
51+
}
52+
53+
if (DEFAULT_EMAIL_REGEXP != constraintAnnotation?.regexp || constraintAnnotation.flags.isNotEmpty()) {
54+
pattern = try {
55+
compile(constraintAnnotation?.regexp ?: DEFAULT_EMAIL_REGEXP, intFlag)
56+
} catch (e: PatternSyntaxException) {
57+
throw logger.getInvalidRegularExpressionException(e)
58+
}
59+
}
60+
}
61+
62+
override fun isValid(value: CharSequence, context: ConstraintValidatorContext): Boolean {
63+
val isValid = super.isValid(value, context)
64+
if (!isValid) {
65+
return isValid
66+
}
67+
val m = pattern.matcher(value)
68+
return m.matches()
69+
}
70+
71+
companion object {
72+
private val logger = LoggerFactory.make(MethodHandles.lookup())
73+
}
74+
}

web-utils/src/main/kotlin/com/icerockdev/webserver/configuration.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import com.icerockdev.exception.UserException
1616
import io.ktor.application.Application
1717
import io.ktor.application.ApplicationCall
1818
import io.ktor.application.call
19-
import io.ktor.features.*
19+
import io.ktor.features.CORS
20+
import io.ktor.features.CallId
21+
import io.ktor.features.CallLogging
22+
import io.ktor.features.StatusPages
23+
import io.ktor.features.callIdMdc
2024
import io.ktor.http.HttpHeaders
2125
import io.ktor.http.HttpMethod
2226
import io.ktor.http.HttpStatusCode
@@ -26,7 +30,7 @@ import io.ktor.response.respond
2630
import io.ktor.util.pipeline.PipelineContext
2731
import org.slf4j.LoggerFactory
2832
import org.slf4j.event.Level
29-
import java.util.*
33+
import java.util.UUID
3034

3135
fun StatusPages.Configuration.applyStatusConfiguration() {
3236
status(HttpStatusCode.NotFound) { status ->

web-utils/src/main/kotlin/com/icerockdev/webserver/log/JsonDataLogger.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,17 @@ import com.icerockdev.api.AbstractResponse
2020
import com.icerockdev.api.Request
2121
import com.icerockdev.webserver.Constants
2222
import com.icerockdev.webserver.Environment
23-
import io.ktor.application.*
23+
import io.ktor.application.ApplicationCallPipeline
24+
import io.ktor.application.ApplicationFeature
25+
import io.ktor.application.call
26+
import io.ktor.application.feature
2427
import io.ktor.request.ApplicationReceivePipeline
2528
import io.ktor.response.ApplicationSendPipeline
26-
import io.ktor.routing.*
29+
import io.ktor.routing.Route
30+
import io.ktor.routing.RouteSelector
31+
import io.ktor.routing.RouteSelectorEvaluation
32+
import io.ktor.routing.RoutingResolveContext
33+
import io.ktor.routing.application
2734
import io.ktor.util.AttributeKey
2835
import io.ktor.util.KtorExperimentalAPI
2936
import io.ktor.util.pipeline.PipelinePhase

0 commit comments

Comments
 (0)