471 lines
16 KiB
Markdown
471 lines
16 KiB
Markdown
# Modules
|
||
|
||
## Installation via Gradle Composite Build
|
||
|
||
1. Add this repository as a
|
||
[git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules)
|
||
to your project
|
||
|
||
1. Add these lines to your `settings.gradle.kts`:
|
||
|
||
```kotlin
|
||
includeBuild("Backend-common")
|
||
```
|
||
|
||
1. Use TLK modules as dependencies of your project
|
||
|
||
```kotlin
|
||
dependencies {
|
||
implementation("ru.touchin:common")
|
||
}
|
||
```
|
||
|
||
## Project Gradle tasks
|
||
### Detekt:
|
||
- `gradle $project:detekt` - detect not formatted, complex code.
|
||
|
||
Reports are stored in "$pwd/build/reports/kotlin-detekt-${project.name}.html".
|
||
|
||
### DiKTat:
|
||
- `gradle :diktatCheck` - detect not formatted code of "kt", "kts" files;
|
||
- `gradle :diktatFix` - if possible, fix not formatted code. Known issues: full fix may require 1+ launch in order to apply all rules; some rules potentially may break code syntax.
|
||
|
||
By setting environment variable `TASKS_FILE_REPORT_ENABLED`(true, false) you may configure raw console output or html file as report.
|
||
Reports are stored in "$pwd/build/reports/diktat-report.html".
|
||
|
||
## common
|
||
|
||
Набор утилит, структур данных, исключений без привязки к `spring`
|
||
|
||
* `ExecutionContext` - класс для хранения/получения данных из текущего потока
|
||
* `SecureRandomStringGenerator` - генератор случайной строки по словарю
|
||
* `errors.*` - базовые исключения
|
||
* `<type>.*Utils` - утилиты для различных типов данных
|
||
|
||
## common-spring
|
||
|
||
Набор утилит, структур данных для `spring`, без привязки к доп. модулям, таким как `jpa` и `web`
|
||
|
||
## common-spring-jpa
|
||
|
||
* `models.*` - базовые `Entity`
|
||
* `repositories` - утилиты и доп. интерфейсы для репозиториев
|
||
* `liquibase.LiquibaseStart` - для подключения этого компонента необходимо объявить `liquibase.LiquibaseParams`.
|
||
Указать путь к файлу с миграцией и схему, для которой эта миграция будет применяться. С помощью `LiquibaseStart`
|
||
можно применить кастомную миграцию не конфликтуя с основной.
|
||
* `EnableJpaAuditingExtra` - подключение `JpaAuditing` с поддержкой типа `ZoneDateTime`
|
||
|
||
## common-spring-web
|
||
|
||
* `request.Utils` - различные `extensions` для работы с `HttpServletRequest`
|
||
* `errors.*` - исключения и типы данных для `web`
|
||
* `webclient.*` - классы для расширения webclient, включая логирование
|
||
|
||
## common-spring-security
|
||
|
||
* `configurations.DefaultSecurityConfiguration` - дефолтная реализация WebSecurity,
|
||
определяет для каких request path надо ограничить доступ.
|
||
Использует `url.interceptors.UrlExpressionRegistryInterceptor` для принятия решения.
|
||
* `auditor.AuditorResolver` - служит для преобразования `principal` в строку, используется с `JpaAuditing`
|
||
|
||
## common-spring-security-jpa
|
||
|
||
* `auditor.SecurityAuditorAware` - резолвит имя пользователя для полей `@CreatedBy`, `@LastModifiedBy`.
|
||
Требуется явно создать бин `AuditorAware<String>` в проекте.
|
||
|
||
## common-spring-test
|
||
|
||
Утилиты для тестирования в среде `spring-test`
|
||
|
||
## common-spring-test-jpa
|
||
|
||
Утилиты для тестирования репозиториев
|
||
|
||
## codestyle-archunit
|
||
|
||
Набор правил для поддержки оформления архитектуры.
|
||
|
||
#### Список доступных правил
|
||
- `ru.touchin.codestyle.archunit.rules.ClassNamingArchRules`
|
||
- `ru.touchin.codestyle.archunit.rules.ClassPackagingArchRules`
|
||
|
||
|
||
#### Gradle plugin
|
||
Настройка и применение совместно с [ArchUnit Gradle Plugin](https://github.com/societe-generale/arch-unit-gradle-plugin).
|
||
|
||
Действие `checkRules` для проверки соответствие правилам запускается при операциях сборки, по умолчанию.
|
||
Вручную можно вызвать командой ``gradle :checkRules`` для нужного модуля.
|
||
Добавить его можно следующим образом на примере установки в рутовый gradle.build проекта:
|
||
|
||
Groovy DSL:
|
||
```groovy
|
||
buildscript {
|
||
dependencies {
|
||
classpath "com.societegenerale.commons:arch-unit-gradle-plugin:3.0.0"
|
||
}
|
||
}
|
||
subprojects {
|
||
dependencyManagement {
|
||
dependencies {
|
||
dependency "com.tngtech.archunit:archunit:1.0.1"
|
||
}
|
||
}
|
||
|
||
apply plugin: "java"
|
||
apply plugin: "com.societegenerale.commons.arch-unit-gradle-plugin"
|
||
|
||
archUnit {
|
||
mainScopePath = "/classes/kotlin/main" // or "/classes/java/main"
|
||
testScopePath = "/classes/kotlin/test" // or "/classes/java/test"
|
||
|
||
var applyType = applyOn("ru.touchin", "main")
|
||
configurableRules = [
|
||
configurableRule(
|
||
"ru.touchin.codestyle.archunit.rules.ClassNamingArchRules",
|
||
applyType,
|
||
),
|
||
configurableRule(
|
||
"ru.touchin.codestyle.archunit.rules.ClassPackagingArchRules",
|
||
applyType,
|
||
),
|
||
]
|
||
}
|
||
|
||
dependencies {
|
||
archUnitExtraLib "ru.touchin:codestyle-archunit" // or archUnitExtraLib project(":codestyle-archunit")
|
||
}
|
||
}
|
||
```
|
||
|
||
Kotlin DSL:
|
||
```kotlin
|
||
plugins {
|
||
id("com.societegenerale.commons.arch-unit-gradle-plugin") version "3.0.0"
|
||
}
|
||
subprojects {
|
||
configure<DependencyManagementExtension> {
|
||
dependencies {
|
||
dependency("com.tngtech.archunit:archunit:1.0.1")
|
||
}
|
||
}
|
||
|
||
apply(plugin = "java")
|
||
apply(plugin = "com.societegenerale.commons.arch-unit-gradle-plugin")
|
||
|
||
archUnit {
|
||
mainScopePath = "/classes/kotlin/main" // or "/classes/java/main"
|
||
testScopePath = "/classes/kotlin/test" // or "/classes/java/test"
|
||
|
||
configurableRules = listOf(
|
||
"ru.touchin.codestyle.archunit.rules.ClassNamingArchRules",
|
||
"ru.touchin.codestyle.archunit.rules.ClassPackagingArchRules"
|
||
).map { package ->
|
||
configurableRule(
|
||
package,
|
||
applyOn("ru.touchin", "main")
|
||
)
|
||
}
|
||
}
|
||
|
||
dependencies {
|
||
archUnitExtraLib("ru.touchin:codestyle-archunit") // or archUnitExtraLib(project(":codestyle-archunit"))
|
||
}
|
||
}
|
||
```
|
||
|
||
Отключить проверки на таске помимо конфигурирования `configurableRule` можно также таким образом:
|
||
```kotlin
|
||
// clear action launch for root project to avoid exception
|
||
tasks.checkRules.configure {
|
||
actions.clear()
|
||
}
|
||
```
|
||
|
||
## logger
|
||
|
||
Основные компоненты логирования:
|
||
|
||
* layout
|
||
* context
|
||
* format
|
||
|
||
## logger-spring
|
||
|
||
Встраивание системы логирования в `spring`
|
||
|
||
* autologging
|
||
* serializer
|
||
|
||
## logger-spring-web
|
||
|
||
Interceptor для логирования запросов/ответов.
|
||
|
||
## exception-handler-spring-web
|
||
|
||
Перехватывает ошибки сервера, определяет код ошибки и возвращает их в правильный `response`.
|
||
Подключается с помощью аннотации `@EnableSpringExceptionHandler`
|
||
|
||
## exception-handler-logger-spring-web
|
||
|
||
Добавляет логирование в обработку ошибок.
|
||
Подключается с помощью аннотации `@EnableSpringExceptionHandlerLogger` до подключения основного модуля.
|
||
|
||
## validation-spring
|
||
|
||
Добавляет аннотации для валидации запросов.
|
||
|
||
## version-spring-web
|
||
|
||
Добавляет возможность задавать версию апи через `properties` без необходимости явно указывать в каждом маппинге
|
||
|
||
## response-wrapper-spring-web
|
||
|
||
Добавляет обертку для успешного ответа
|
||
|
||
## common-measure
|
||
|
||
Утилиты для работы с `measure`
|
||
|
||
## common-measure-spring
|
||
|
||
Возможность задавать `measure` через `properties`
|
||
|
||
## common-geo
|
||
|
||
Интерфейс для работы с гео-данными
|
||
|
||
## common-geo-spatial4j-spring
|
||
|
||
Реализация интерфейса `GeoCalculator` с помощью библиотеки `spatial4j`
|
||
|
||
## settings-spring-jpa
|
||
|
||
Модуль для хранения настроек
|
||
|
||
## security-authorization-server-core
|
||
|
||
Модуль авторизации
|
||
|
||
## security-authorization-server-jwt-core
|
||
|
||
Добавляет поддержку jwt-токенов (создание/хранение). Для работы этого модуля требуется прописать в пропертях:
|
||
|
||
``` yaml
|
||
token.access:
|
||
issuer: ${app.issuer}
|
||
timeToLive: PT15M # 15 minutes
|
||
signatureAlgorithm: RS256
|
||
keyPair:
|
||
public: |
|
||
-----BEGIN PUBLIC KEY-----
|
||
-----END PUBLIC KEY-----
|
||
private: |
|
||
-----BEGIN PRIVATE KEY-----
|
||
-----END PRIVATE KEY-----
|
||
token.refresh:
|
||
length: 20
|
||
prefix: RT-
|
||
timeToLive: PT2H # 2 hours
|
||
```
|
||
|
||
Генерация ключей:
|
||
|
||
```bash
|
||
openssl genrsa -out private.pem 4096
|
||
openssl rsa -in private.pem -pubout -out public.pem
|
||
openssl pkcs8 -topk8 -inform PEM -in private.pem -out private_key.pem -nocrypt
|
||
|
||
cat private_key.pem
|
||
cat public.pem
|
||
```
|
||
|
||
## security-authorization-server-oauth2-metadata
|
||
|
||
OAuth2 metadata support.
|
||
|
||
## security-jwt-common
|
||
|
||
JWT related utilities.
|
||
|
||
## security-resource-server-default-configuration
|
||
|
||
Default configuration for the Spring OAuth2 resource server with JWT auth.
|
||
|
||
## security-resource-server-custom-configuration
|
||
|
||
Custom configuration for the Spring OAuth2 resource server with JWT auth. Requires the following properties:
|
||
|
||
``` yaml
|
||
token.access:
|
||
issuer: ${app.issuer}
|
||
signatureAlgorithm: RS256
|
||
keyPair:
|
||
public: |
|
||
-----BEGIN PUBLIC KEY-----
|
||
-----END PUBLIC KEY-----
|
||
```
|
||
|
||
## security-resource-server-test-configuration
|
||
|
||
Disables Spring OAuth2 resource server for testing.
|
||
|
||
## s3-storage
|
||
|
||
Amazon S3 support.
|
||
|
||
## server-info-spring-web
|
||
|
||
Allow include headers with information about the server in responses
|
||
|
||
To get started you need:
|
||
1) Add annotation to configuration
|
||
2) Add property to yml/properties file:
|
||
```
|
||
server.info:
|
||
buildVersion: ${buildVersion}
|
||
```
|
||
3) Implement ServerInfoService (optional. If you want to add other headers)
|
||
4) Add dir with impl ServerInfoService in ComponentScan annotation
|
||
|
||
## push-message-provider
|
||
|
||
Интерфейсы и компоненты для модулей по обеспечению интеграции с сервисами отправки пуш-уведомлений. Является необходимой зависимостью для использования провайдеров.
|
||
|
||
Далее рассматривается пример использования подключаемых модулей-провайдеров.
|
||
``` kotlin
|
||
@Service
|
||
class PushSendingService(
|
||
private val pushMessageProviderServiceFactory: PushMessageProviderServiceFactory
|
||
) {
|
||
|
||
fun sendPushMessage() {
|
||
val yourPushToken = "pushTokenForChecking"
|
||
val platform = PlatformType.ANDROID_GOOGLE
|
||
|
||
val pushMessageProvider: PushMessageProviderService = pushMessageProviderServiceFactory.get(platform)
|
||
|
||
val result = pushMessageProvider.check( // Проверка валидности токена для обозначения целесообразности отправки
|
||
PushTokenCheck(
|
||
pushToken = yourPushToken
|
||
)
|
||
)
|
||
|
||
if (result.status == PushTokenStatus.VALID) { // Токен валиден, PushMessageProviderService интегрирован в систему
|
||
// Отправка пуш-уведомления
|
||
pushMessageProvider.send(
|
||
PushTokenMessage(
|
||
token = yourPushToken,
|
||
pushMessageNotification = PushMessageNotification(
|
||
title = "Your PushMessage",
|
||
description = "Provided by PushMessageProviderService",
|
||
imageUrl = null
|
||
),
|
||
data = mapOf(
|
||
"customKey" to "customData"
|
||
)
|
||
)
|
||
)
|
||
}
|
||
}
|
||
|
||
}
|
||
```
|
||
|
||
## push-message-provider-fcm
|
||
|
||
Модуль по обеспечению интеграции с Firebase Cloud Messaging.
|
||
1) Подключение компонентов Spring осуществляется при помощи аннотации `@EnablePushMessageProviderFcm`.
|
||
2) Необходимо добавление конфигурации для модуля с выбранным способом хранения данных для авторизации. Пример файла конфигурации в формате yaml:
|
||
``` yaml
|
||
push-message-provider:
|
||
platformProviders:
|
||
ANDROID_GOOGLE:
|
||
- FCM
|
||
IOS:
|
||
- FCM
|
||
fcm:
|
||
appName: yourAppName
|
||
auth:
|
||
# Выбранный тип авторизации
|
||
client:
|
||
readTimeout: 10s
|
||
connectionTimeout: 1s
|
||
```
|
||
3) Настраивается способ предоставления авторизации для Firebase Cloud Messaging.
|
||
|
||
А) Токен доступа из консоли Google, добавляемый в конфигурацию настроек:
|
||
``` yaml
|
||
auth:
|
||
token:
|
||
value: testValue
|
||
expiresAt: 2023-01-01 23:59:59 +00:00
|
||
```
|
||
B) Данные в файле из консоли Firebase, добавляемые в resources с обозначением пути в конфигурации настроек:
|
||
``` yaml
|
||
auth:
|
||
credentialsFile:
|
||
path: credentials/firebase-admin.json
|
||
```
|
||
C) Данные из файла консоли Firebase, добавляемые в конфигурацию настроек:
|
||
``` yaml
|
||
auth:
|
||
credentialsData:
|
||
type: service_account
|
||
projectId: yourProjectId
|
||
privateKeyId: yourPrivateKeyId
|
||
privateKey: |
|
||
-----BEGIN PRIVATE KEY-----
|
||
-----END PRIVATE KEY-----
|
||
clientEmail: yourClientEmail
|
||
clientId: yourClientId
|
||
authUri: yourAuthUri
|
||
tokenUri: yourTokenUri
|
||
authProviderX509CertUrl: yourAuthProviderX509CertUrl
|
||
clientX509CertUrl: yourClientX509CertUrl
|
||
```
|
||
|
||
## push-message-provider-hpk
|
||
|
||
Модуль по обеспечению интеграции с Huawei Push Kit.
|
||
|
||
1) Подключение нового провайдера осуществляется при помощи аннотации `@EnablePushMessageProviderHpk`.
|
||
2) Для логирования запросов к сервису HPK нужно встроить в контейнер Spring собственный `WebClientLogger` из модуля `logger-spring-web` или же использовать стандартный посредством импорта конфигурации:
|
||
``` kotlin
|
||
@Import(
|
||
SpringLoggerConfiguration::class,
|
||
SpringLoggerWebConfiguration::class
|
||
)
|
||
class YourConfiguration
|
||
```
|
||
3) Нужно добавить конфигурацию для считывания модулем. Пример файла в формате yaml:
|
||
``` yaml
|
||
push-message-provider:
|
||
platformProviders:
|
||
ANDROID_HUAWEI:
|
||
- HPK
|
||
hpk:
|
||
web-services:
|
||
client-id: yourClientId
|
||
oauth:
|
||
client-secret: yourClientSecret
|
||
url: https://oauth-login.cloud.huawei.com/oauth2/v3/
|
||
http:
|
||
connection-timeout: 1s
|
||
read-timeout: 10s
|
||
write-timeout: 10s
|
||
ssl: # Опциональная структура
|
||
handshake-timeout: 1s
|
||
notify-read-timeout: 1s
|
||
notify-flush-timeout: 1s
|
||
hpk:
|
||
url: https://push-api.cloud.huawei.com/v1/
|
||
http:
|
||
connection-timeout: 1s
|
||
read-timeout: 10s
|
||
write-timeout: 10s
|
||
ssl: # Опциональная структура
|
||
handshake-timeout: 1s
|
||
notify-read-timeout: 1s
|
||
notify-flush-timeout: 1s
|
||
```
|