├── .github └── workflows │ └── gradle.yml ├── .gitignore ├── README.md ├── account ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── account │ │ │ ├── AccountApplication.kt │ │ │ ├── AccountController.kt │ │ │ ├── exception │ │ │ └── AccountException.kt │ │ │ ├── repository │ │ │ └── AccountRepository.kt │ │ │ └── service │ │ │ ├── AccountSaga.kt │ │ │ └── AccountService.kt │ └── resources │ │ └── bootstrap.yaml │ └── test │ └── kotlin │ └── com │ └── example │ └── account │ ├── AccountControllerTest.kt │ └── service │ └── AccountServiceTest.kt ├── admin ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── admin │ │ │ └── AdminApplication.kt │ └── resources │ │ └── bootstrap.yaml │ └── test │ └── kotlin │ └── com │ └── example │ └── admin │ └── AdminApplicationTests.kt ├── build.gradle.kts ├── common ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ └── com │ └── example │ └── common │ ├── BaseSwaggerConfiguration.kt │ ├── Command.kt │ └── Result.kt ├── config ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── config │ │ │ └── ConfigApplication.kt │ └── resources │ │ └── application.yaml │ └── test │ └── kotlin │ └── com │ └── example │ └── config │ └── ConfigApplicationTests.kt ├── configuration-repo ├── account-default.yaml ├── account-prod.yaml ├── admin-default.yaml ├── delivery-default.yaml ├── delivery-prod.yaml ├── gateway-default.yaml ├── gateway-prod.yaml ├── notification-default.yaml ├── notification-prod.yaml ├── order-default.yaml ├── order-prod.yaml ├── server-default.yaml ├── store-default.yaml └── store-prod.yaml ├── delivery ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── delivery │ │ │ ├── DeliveryApplication.kt │ │ │ ├── DeliveryController.kt │ │ │ ├── exception │ │ │ └── DeliveryException.kt │ │ │ ├── repository │ │ │ └── DeliveryRepository.kt │ │ │ └── service │ │ │ ├── DeliveryCommandHandler.kt │ │ │ └── DeliveryService.kt │ └── resources │ │ ├── bootstrap.yaml │ │ └── schema.sql │ └── test │ └── kotlin │ └── com │ └── example │ └── delivery │ ├── DeliveryControllerTest.kt │ └── service │ └── DeliveryServiceTest.kt ├── docker-compose.yaml ├── e2e ├── .gitignore ├── README.md ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── e2e │ │ │ └── E2eApplication.kt │ └── resources │ │ └── application.properties │ └── test │ └── kotlin │ └── com │ └── example │ └── e2e │ ├── EurekaTest.kt │ ├── OrderTest.kt │ ├── StoreTest.kt │ └── container │ ├── Container.kt │ └── RestExecutor.kt ├── gateway ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── gateway │ │ │ ├── GatewayApplication.kt │ │ │ ├── GatewayController.kt │ │ │ ├── Model.kt │ │ │ └── configuration │ │ │ ├── Client.kt │ │ │ ├── OAuthSecurityConfiguration.kt │ │ │ └── SwaggerDocumentation.kt │ └── resources │ │ └── bootstrap.yaml │ └── test │ └── kotlin │ └── com │ └── example │ └── gateway │ └── GatewayControllerTest.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── helm ├── README.md ├── account_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── admin_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── cdc_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ └── pdb.yaml │ └── values.yaml ├── config_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── delivery_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── gateway_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── notification_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── order_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── postgres_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── server_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml ├── store_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── imagestream.yaml │ │ ├── pdb.yaml │ │ ├── route.yaml │ │ └── service.yaml │ └── values.yaml └── zookeeper_chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── imagestream.yaml │ ├── pdb.yaml │ ├── route.yaml │ └── service.yaml │ └── values.yaml ├── notification ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ └── main │ ├── kotlin │ └── com │ │ └── example │ │ └── notification │ │ ├── NotificationApplication.kt │ │ └── NotifyCommandHandler.kt │ └── resources │ └── bootstrap.yaml ├── order ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── order │ │ │ ├── OrderApplication.kt │ │ │ ├── OrderController.kt │ │ │ ├── exception │ │ │ └── OrderException.kt │ │ │ ├── repository │ │ │ └── OrderRepository.kt │ │ │ ├── saga │ │ │ └── CreateOrderSaga.kt │ │ │ └── service │ │ │ └── OrderService.kt │ └── resources │ │ └── bootstrap.yaml │ └── test │ └── kotlin │ └── com │ └── example │ └── order │ ├── OrderControllerTest.kt │ └── service │ └── OrderServiceTest.kt ├── schema.png ├── server ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── server │ │ │ └── ServerApplication.kt │ └── resources │ │ └── application.yaml │ └── test │ └── kotlin │ └── com │ └── example │ └── server │ └── ServerApplicationTests.kt ├── settings.gradle.kts └── store ├── .gitignore ├── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src ├── main ├── kotlin │ └── com │ │ └── example │ │ └── store │ │ ├── StoreApplication.kt │ │ ├── StoreController.kt │ │ ├── exception │ │ └── StoreException.kt │ │ ├── repository │ │ └── StoreRepository.kt │ │ └── service │ │ ├── StoreCommandHandler.kt │ │ └── StoreService.kt └── resources │ ├── bootstrap.yaml │ └── schema.sql └── test └── kotlin └── com └── example └── store ├── StoreControllerTest.kt └── service └── StoreServiceTest.kt /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Java CI with Gradle 5 | 6 | on: [push] 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Set up JDK 11 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: 11 19 | - name: Grant execute permission for gradlew 20 | run: chmod +x gradlew 21 | - name: Test with Gradle 22 | run: ./gradlew clean build -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /.gradle/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kotlin Spring Microservices [![Kotlin](https://img.shields.io/badge/Kotlin-1.6.10-orange.svg) ](https://kotlinlang.org/) ![Java CI with Gradle](https://github.com/ElinaValieva/spring-microservices/workflows/Java%20CI%20with%20Gradle/badge.svg) 2 | > Based on methodology and patterns of [Chris Richardson](https://github.com/cer) and [Eventuate Framework](https://github.com/eventuate-tram/eventuate-tram-core) 3 | 4 | ![](https://github.com/ElinaValieva/spring-microservices/blob/master/schema.png) 5 | 6 |   7 | 8 | ### Technologies 🚩 9 | - Spring Boot, Spring Admin 10 | - Spring Cloud Discovery, Spring Cloud Config 11 | - Eventuate Tram - [CQRS, Sagas](https://eventuate.io/abouteventuatetram.html) with Kafka, Postgres 12 | 13 |   14 | 15 | ### How to start 🐳 16 | ```shell script 17 | docker-compose up 18 | ``` 19 | Browse swagger `http://localhost:8008/swagger-ui.html` 20 | 21 |   22 | 23 | ### Deploy to OpenShift 🚩 24 | ```shell script 25 | ./gradlew helm 26 | ``` 27 | -------------------------------------------------------------------------------- /account/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /account/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/account/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /account/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /account/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "account" -------------------------------------------------------------------------------- /account/src/main/kotlin/com/example/account/AccountApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.account 2 | 3 | import io.eventuate.tram.sagas.spring.orchestration.SagaOrchestratorConfiguration 4 | import io.eventuate.tram.spring.consumer.kafka.EventuateTramKafkaMessageConsumerConfiguration 5 | import io.eventuate.tram.spring.messaging.producer.jdbc.TramMessageProducerJdbcConfiguration 6 | import io.eventuate.tram.spring.optimisticlocking.OptimisticLockingDecoratorConfiguration 7 | import org.springframework.boot.autoconfigure.SpringBootApplication 8 | import org.springframework.boot.runApplication 9 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 10 | import org.springframework.cloud.context.config.annotation.RefreshScope 11 | import org.springframework.context.annotation.Import 12 | 13 | @SpringBootApplication 14 | @EnableDiscoveryClient 15 | @Import( 16 | SagaOrchestratorConfiguration::class, 17 | OptimisticLockingDecoratorConfiguration::class, 18 | EventuateTramKafkaMessageConsumerConfiguration::class, 19 | TramMessageProducerJdbcConfiguration::class 20 | ) 21 | @RefreshScope 22 | class AccountApplication 23 | 24 | fun main(args: Array) { 25 | runApplication(*args) 26 | } 27 | -------------------------------------------------------------------------------- /account/src/main/kotlin/com/example/account/AccountController.kt: -------------------------------------------------------------------------------- 1 | package com.example.account 2 | 3 | import com.example.account.repository.Account 4 | import com.example.account.service.AccountService 5 | import com.example.common.BaseSwaggerConfiguration 6 | import io.swagger.annotations.Api 7 | import io.swagger.annotations.ApiOperation 8 | import org.springframework.context.annotation.Configuration 9 | import org.springframework.http.ResponseEntity 10 | import org.springframework.web.bind.annotation.* 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2 12 | 13 | @Configuration 14 | @EnableSwagger2 15 | class SwaggerDocumentation( 16 | basePackage: String = "com.example.account", 17 | service: String = "Account" 18 | ) : BaseSwaggerConfiguration(basePackage, service) 19 | 20 | 21 | @RestController 22 | @Api(value = "API for Account service") 23 | class AccountController(var accountService: AccountService) { 24 | 25 | @PostMapping("/register") 26 | @ApiOperation(value = "Registration user") 27 | fun register(@RequestBody account: Account): ResponseEntity? { 28 | return accountService.register(account)?.let { ResponseEntity.ok(it) } 29 | } 30 | 31 | @GetMapping("/user/{id}") 32 | @ApiOperation(value = "Getting user information") 33 | fun getUserInfo(@PathVariable("id") id: String) = accountService.getUserInfo(id) 34 | } -------------------------------------------------------------------------------- /account/src/main/kotlin/com/example/account/exception/AccountException.kt: -------------------------------------------------------------------------------- 1 | package com.example.account.exception 2 | 3 | import org.springframework.http.ResponseEntity 4 | import org.springframework.web.bind.annotation.ControllerAdvice 5 | import org.springframework.web.bind.annotation.ExceptionHandler 6 | 7 | class AccountException(override val message: String) : RuntimeException(message) 8 | 9 | @ControllerAdvice 10 | class AccountExceptionHandler { 11 | 12 | @ExceptionHandler(AccountException::class) 13 | fun handleMonitoringException(ex: AccountException): ResponseEntity { 14 | return ResponseEntity.badRequest().body(ex.message) 15 | } 16 | } -------------------------------------------------------------------------------- /account/src/main/kotlin/com/example/account/repository/AccountRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.account.repository 2 | 3 | import org.springframework.data.repository.CrudRepository 4 | import javax.persistence.Column 5 | import javax.persistence.Entity 6 | import javax.persistence.Id 7 | import javax.persistence.Table 8 | 9 | @Entity 10 | @Table(name = "account", schema = "eventuate") 11 | data class Account( 12 | @Id @Column(name = "id") var id: String? = null, 13 | @Column(name = "name") var name: String? = null, 14 | @Column(name = "email") var email: String? = null, 15 | @Column(name = "picture") var picture: String? = null, 16 | @Column(name = "locale") var locale: String? = null, 17 | @Column(name = "emailVerified") var emailVerified: String? = null 18 | ) { 19 | fun confirmed() { 20 | emailVerified = true.toString() 21 | } 22 | 23 | fun rejected() { 24 | emailVerified = false.toString() 25 | } 26 | } 27 | 28 | interface AccountRepository : CrudRepository { 29 | 30 | fun findByName(username: String): Account? 31 | } -------------------------------------------------------------------------------- /account/src/main/kotlin/com/example/account/service/AccountService.kt: -------------------------------------------------------------------------------- 1 | package com.example.account.service 2 | 3 | import com.example.account.exception.AccountException 4 | import com.example.account.repository.Account 5 | import com.example.account.repository.AccountRepository 6 | import io.eventuate.tram.sagas.orchestration.SagaInstanceFactory 7 | import org.springframework.stereotype.Service 8 | import org.springframework.transaction.annotation.Transactional 9 | 10 | interface AccountService { 11 | 12 | fun register(account: Account): Account? 13 | 14 | fun getUserInfo(id: String): Account? 15 | } 16 | 17 | @Service 18 | class AccountServiceImpl( 19 | private val accountRepository: AccountRepository, 20 | private val accountSaga: AccountSaga, 21 | private val sagaInstanceFactory: SagaInstanceFactory 22 | ) : AccountService { 23 | 24 | @Transactional 25 | override fun register(account: Account): Account? { 26 | val foundedUser = account.name?.let { accountRepository.findByName(it) } 27 | 28 | if (foundedUser != null) 29 | throw AccountException("User with same username already exist") 30 | 31 | val sagaData = AccountSagaData(account = account) 32 | sagaInstanceFactory.create(accountSaga, sagaData) 33 | return sagaData.id?.let { accountRepository.findById(it).get() } 34 | } 35 | 36 | override fun getUserInfo(id: String): Account? = accountRepository.findById(id).get() 37 | } 38 | -------------------------------------------------------------------------------- /account/src/main/resources/bootstrap.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | serviceUrl: 4 | defaultZone: http://localhost:8761/eureka 5 | spring: 6 | application: 7 | name: account 8 | cloud: 9 | config: 10 | uri: http://localhost:8088 -------------------------------------------------------------------------------- /account/src/test/kotlin/com/example/account/service/AccountServiceTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.account.service 2 | 3 | import com.example.account.exception.AccountException 4 | import com.example.account.repository.Account 5 | import com.example.account.repository.AccountRepository 6 | import io.eventuate.tram.sagas.orchestration.SagaInstanceFactory 7 | import org.junit.jupiter.api.Assertions 8 | import org.junit.jupiter.api.Test 9 | import org.junit.jupiter.api.extension.ExtendWith 10 | import org.mockito.Mockito 11 | import org.springframework.beans.factory.annotation.Autowired 12 | import org.springframework.boot.test.context.TestConfiguration 13 | import org.springframework.boot.test.mock.mockito.MockBean 14 | import org.springframework.boot.test.mock.mockito.MockBeans 15 | import org.springframework.context.annotation.Bean 16 | import org.springframework.test.context.junit.jupiter.SpringExtension 17 | import java.util.* 18 | 19 | @MockBeans( 20 | MockBean(AccountSaga::class), 21 | MockBean(SagaInstanceFactory::class) 22 | ) 23 | @ExtendWith(SpringExtension::class) 24 | internal class AccountServiceTest { 25 | 26 | @TestConfiguration 27 | class AccountServiceTestConfiguration { 28 | 29 | @Bean 30 | fun accountService( 31 | accountRepository: AccountRepository, 32 | accountSaga: AccountSaga, 33 | sagaInstanceFactory: SagaInstanceFactory 34 | ): AccountService { 35 | return AccountServiceImpl(accountRepository, accountSaga, sagaInstanceFactory) 36 | } 37 | } 38 | 39 | @Autowired 40 | private lateinit var accountService: AccountService 41 | 42 | @MockBean 43 | private lateinit var accountRepository: AccountRepository 44 | 45 | private val account = Account( 46 | id = "1", 47 | name = "username", 48 | email = "email" 49 | ) 50 | 51 | @Test 52 | fun register() { 53 | Mockito.`when`(account.name?.let { accountRepository.findByName(it) }).thenReturn(null) 54 | Assertions.assertDoesNotThrow { accountService.register(account) } 55 | } 56 | 57 | @Test 58 | fun registerWithFailing() { 59 | Mockito.`when`(account.name?.let { accountRepository.findByName(it) }).thenReturn(account) 60 | Assertions.assertThrows(AccountException::class.java) { accountService.register(account) } 61 | } 62 | 63 | @Test 64 | fun getUserInfo() { 65 | Mockito.`when`(account.id?.let { accountRepository.findById(it) }).thenReturn(Optional.of(account)) 66 | Assertions.assertEquals(account, accountService.getUserInfo("1")) 67 | } 68 | } -------------------------------------------------------------------------------- /admin/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /admin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | java.sourceCompatibility = JavaVersion.VERSION_11 2 | val buildNumber by extra("0") 3 | 4 | extra["springBootAdminVersion"] = "2.2.4" 5 | extra["springCloudVersion"] = "Hoxton.SR6" 6 | 7 | 8 | dependencies { 9 | implementation("de.codecentric:spring-boot-admin-starter-server") 10 | implementation("de.codecentric:spring-boot-admin-server-ui-login:1.5.7") 11 | implementation("org.springframework.cloud:spring-cloud-config-client") 12 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client") 13 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 14 | exclude(group = "org.junit.vintage", module = "junit-vintage-engine") 15 | } 16 | } 17 | 18 | dependencyManagement { 19 | imports { 20 | mavenBom("de.codecentric:spring-boot-admin-dependencies:${property("springBootAdminVersion")}") 21 | mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}") 22 | } 23 | } 24 | 25 | jib { 26 | to { 27 | image = "elvaliev/admin" 28 | tags = setOf("$version", "$version.${extra["buildNumber"]}") 29 | auth { 30 | username = System.getenv("DOCKERHUB_USERNAME") 31 | password = System.getenv("DOCKERHUB_PASSWORD") 32 | } 33 | } 34 | container { 35 | labels = mapOf( 36 | "maintainer" to "Elina Valieva ", 37 | "org.opencontainers.image.title" to "admin", 38 | "org.opencontainers.image.description" to "Spring microservices", 39 | "org.opencontainers.image.version" to "$version", 40 | "org.opencontainers.image.authors" to "Elina Valieva >", 41 | "org.opencontainers.image.url" to "https://github.com/ElinaValieva/spring-microservices" 42 | ) 43 | jvmFlags = listOf( 44 | "-server", 45 | "-Djava.awt.headless=true", 46 | "-XX:InitialRAMFraction=2", 47 | "-XX:MinRAMFraction=2", 48 | "-XX:MaxRAMFraction=2", 49 | "-XX:+UseG1GC", 50 | "-XX:MaxGCPauseMillis=100", 51 | "-XX:+UseStringDeduplication" 52 | ) 53 | workingDirectory = "/admin" 54 | ports = listOf("8888") 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /admin/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/admin/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /admin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /admin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "admin" 2 | -------------------------------------------------------------------------------- /admin/src/main/kotlin/com/example/admin/AdminApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.admin 2 | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer 4 | import org.springframework.boot.autoconfigure.SpringBootApplication 5 | import org.springframework.boot.runApplication 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 7 | import org.springframework.cloud.context.config.annotation.RefreshScope 8 | 9 | @EnableAdminServer 10 | @EnableDiscoveryClient 11 | @SpringBootApplication 12 | @RefreshScope 13 | class AdminApplication 14 | 15 | fun main(args: Array) { 16 | runApplication(*args) 17 | } 18 | -------------------------------------------------------------------------------- /admin/src/main/resources/bootstrap.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | serviceUrl: 4 | defaultZone: http://localhost:8761/eureka 5 | spring: 6 | application: 7 | name: admin 8 | cloud: 9 | config: 10 | uri: http://localhost:8088 11 | -------------------------------------------------------------------------------- /admin/src/test/kotlin/com/example/admin/AdminApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.example.admin 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class AdminApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.apache.tools.ant.taskdefs.condition.Os 2 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 3 | 4 | val kotlinVersion: String by System.getProperties() 5 | val swaggerVersion: String by System.getProperties() 6 | 7 | plugins { 8 | id("org.springframework.boot") version "2.3.12.RELEASE" apply false 9 | id("io.spring.dependency-management") version "1.0.9.RELEASE" apply false 10 | id("com.google.cloud.tools.jib") version "2.4.0" apply false 11 | kotlin("jvm") version "1.6.10" apply false 12 | kotlin("plugin.spring") version "1.6.10" apply false 13 | } 14 | 15 | subprojects { 16 | 17 | if (this.name == "common") { 18 | apply { 19 | plugin("org.jetbrains.kotlin.jvm") 20 | plugin("org.jetbrains.kotlin.plugin.spring") 21 | } 22 | } else { 23 | apply { 24 | plugin("io.spring.dependency-management") 25 | plugin("org.springframework.boot") 26 | plugin("org.jetbrains.kotlin.jvm") 27 | plugin("org.jetbrains.kotlin.plugin.spring") 28 | plugin("com.google.cloud.tools.jib") 29 | } 30 | } 31 | 32 | group = "org.example" 33 | version = "1.0.0" 34 | val implementation by configurations 35 | 36 | dependencies { 37 | implementation("org.jetbrains.kotlin:kotlin-reflect") 38 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 39 | implementation("io.springfox:springfox-swagger2:$swaggerVersion") 40 | implementation("io.springfox:springfox-swagger-ui:$swaggerVersion") 41 | } 42 | 43 | repositories { 44 | mavenCentral() 45 | jcenter() 46 | } 47 | 48 | tasks.withType { 49 | useJUnitPlatform() 50 | } 51 | 52 | tasks.withType { 53 | kotlinOptions { 54 | freeCompilerArgs = listOf("-Xjsr305=strict") 55 | jvmTarget = "11" 56 | } 57 | } 58 | 59 | } 60 | 61 | tasks.withType { 62 | useJUnitPlatform() 63 | } 64 | 65 | tasks.create("helm") { 66 | group = "deploy" 67 | description = "Helm Chart installation" 68 | doLast { 69 | val names = mutableMapOf() 70 | fileTree("helm").visit { 71 | if (this.isDirectory && this.name !in listOf("charts", "templates")) 72 | names[this.name] = this.name 73 | .replace("[.,;:_-]?".toRegex(), "") 74 | .replace("chart", "") 75 | } 76 | names.forEach { (key, value) -> 77 | exec { 78 | if (Os.isFamily(Os.FAMILY_WINDOWS)) 79 | commandLine("cmd", "/c", "helm upgrade -i $value $key") 80 | else 81 | commandLine("sh", "-c", "helm upgrade -i $value $key") 82 | } 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /common/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | java.sourceCompatibility = JavaVersion.VERSION_11 2 | val eventuateSpring: String by System.getProperties() 3 | 4 | dependencies { 5 | implementation("io.eventuate.tram.core:eventuate-tram-spring-commands:$eventuateSpring") 6 | } -------------------------------------------------------------------------------- /common/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/common/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /common/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /common/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "common" 2 | -------------------------------------------------------------------------------- /common/src/main/kotlin/com/example/common/BaseSwaggerConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.example.common 2 | 3 | import org.springframework.context.annotation.Bean 4 | import springfox.documentation.builders.ApiInfoBuilder 5 | import springfox.documentation.builders.RequestHandlerSelectors 6 | import springfox.documentation.service.ApiInfo 7 | import springfox.documentation.service.Contact 8 | import springfox.documentation.spi.DocumentationType 9 | import springfox.documentation.spring.web.plugins.Docket 10 | 11 | open class BaseSwaggerConfiguration(private var basePackage: String, private var service: String) { 12 | 13 | @Bean 14 | open fun api(): Docket? { 15 | return Docket(DocumentationType.SWAGGER_2) 16 | .select() 17 | .apis(RequestHandlerSelectors.basePackage(basePackage)) 18 | .build() 19 | .apiInfo(metaData()) 20 | } 21 | 22 | open fun metaData(): ApiInfo? { 23 | return ApiInfoBuilder() 24 | .title("$service API Description") 25 | .description("API Description for $service") 26 | .version("1.0") 27 | .contact( 28 | Contact( 29 | "Valieva Elina", 30 | "https://github.com/ElinaValieva/spring-microservices", 31 | "veaufa@mail.ru" 32 | ) 33 | ) 34 | .build() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /common/src/main/kotlin/com/example/common/Command.kt: -------------------------------------------------------------------------------- 1 | package com.example.common 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect 4 | import com.fasterxml.jackson.annotation.JsonCreator 5 | import com.fasterxml.jackson.annotation.JsonProperty 6 | import com.fasterxml.jackson.annotation.JsonValue 7 | import io.eventuate.tram.commands.common.Command 8 | 9 | data class ReserveStoreProductCommand @JsonCreator constructor( 10 | @JsonValue var productId: String 11 | ) : Command 12 | 13 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) 14 | data class CreateDeliveryCommand @JsonCreator constructor( 15 | @param:JsonProperty("orderId") @get:JsonProperty("orderId") var orderId: String, 16 | @param:JsonProperty("city") @get:JsonProperty("city") var city: String 17 | ) : Command 18 | 19 | 20 | data class NotifyUserCommand @JsonCreator constructor( 21 | @JsonValue var username: String 22 | ) : Command -------------------------------------------------------------------------------- /common/src/main/kotlin/com/example/common/Result.kt: -------------------------------------------------------------------------------- 1 | package com.example.common 2 | 3 | class DeliveryUnavailable : Result 4 | 5 | class FailedToReserveProduct : Result 6 | 7 | class FailedToNotify: Result 8 | 9 | class ProductReserved : Result 10 | 11 | class DeliveryCreated: Result 12 | 13 | class UserNotified: Result 14 | 15 | interface Result 16 | -------------------------------------------------------------------------------- /config/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /config/build.gradle.kts: -------------------------------------------------------------------------------- 1 | java.sourceCompatibility = JavaVersion.VERSION_11 2 | val buildNumber by extra("0") 3 | 4 | extra["springCloudVersion"] = "Hoxton.SR6" 5 | extra["springBootAdminVersion"] = "2.2.4" 6 | 7 | 8 | dependencies { 9 | implementation("org.springframework.cloud:spring-cloud-config-server") 10 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client") 11 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 12 | exclude(group = "org.junit.vintage", module = "junit-vintage-engine") 13 | } 14 | } 15 | 16 | dependencyManagement { 17 | imports { 18 | mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}") 19 | } 20 | } 21 | 22 | jib { 23 | to { 24 | image = "elvaliev/config" 25 | tags = setOf("$version", "$version.${extra["buildNumber"]}") 26 | auth { 27 | username = System.getenv("DOCKERHUB_USERNAME") 28 | password = System.getenv("DOCKERHUB_PASSWORD") 29 | } 30 | } 31 | container { 32 | labels = mapOf( 33 | "maintainer" to "Elina Valieva ", 34 | "org.opencontainers.image.title" to "config", 35 | "org.opencontainers.image.description" to "Spring microservices", 36 | "org.opencontainers.image.version" to "$version", 37 | "org.opencontainers.image.authors" to "Elina Valieva >", 38 | "org.opencontainers.image.url" to "https://github.com/ElinaValieva/spring-microservices" 39 | ) 40 | jvmFlags = listOf( 41 | "-server", 42 | "-Djava.awt.headless=true", 43 | "-XX:InitialRAMFraction=2", 44 | "-XX:MinRAMFraction=2", 45 | "-XX:MaxRAMFraction=2", 46 | "-XX:+UseG1GC", 47 | "-XX:MaxGCPauseMillis=100", 48 | "-XX:+UseStringDeduplication" 49 | ) 50 | workingDirectory = "/config" 51 | ports = listOf("8088") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /config/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/config/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /config/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /config/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "config" 2 | -------------------------------------------------------------------------------- /config/src/main/kotlin/com/example/config/ConfigApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.config 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 6 | import org.springframework.cloud.config.server.EnableConfigServer 7 | 8 | @SpringBootApplication 9 | @EnableDiscoveryClient 10 | @EnableConfigServer 11 | class ConfigApplication 12 | 13 | fun main(args: Array) { 14 | runApplication(*args) 15 | } 16 | -------------------------------------------------------------------------------- /config/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | serviceUrl: 4 | defaultZone: http://localhost:8761/eureka 5 | instance: 6 | preferIpAddress: true 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" 12 | server: 13 | port: 8088 14 | spring: 15 | application: 16 | name: config 17 | cloud: 18 | config: 19 | server: 20 | git: 21 | uri: https://github.com/ElinaValieva/spring-microservices.git 22 | search-paths: configuration-repo -------------------------------------------------------------------------------- /config/src/test/kotlin/com/example/config/ConfigApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.example.config 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class ConfigApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /configuration-repo/account-default.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 0 3 | spring: 4 | boot: 5 | admin: 6 | client: 7 | url: http://localhost:8888 8 | application: 9 | name: account 10 | datasource: 11 | url: jdbc:postgresql://localhost:5432/eventuate 12 | username: postgres 13 | password: pass 14 | driver-class-name: org.postgresql.Driver 15 | jpa: 16 | database: postgresql 17 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 18 | management: 19 | endpoints: 20 | web: 21 | exposure: 22 | include: "*" 23 | eureka: 24 | client: 25 | healthcheck: 26 | enabled: true 27 | instance: 28 | preferIpAddress: true 29 | leaseRenewalIntervalInSeconds: 5 30 | leaseExpirationDurationInSeconds: 5 31 | eventuatelocal: 32 | kafka: 33 | bootstrap: 34 | servers: http://localhost:9092 35 | zookeeper: 36 | connection: 37 | string: http://localhost:2181 -------------------------------------------------------------------------------- /configuration-repo/account-prod.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | spring: 4 | boot: 5 | admin: 6 | client: 7 | url: http://admin/ 8 | application: 9 | name: account 10 | datasource: 11 | url: jdbc:postgresql://postgres/eventuate 12 | username: eventuate 13 | password: eventuate 14 | driver-class-name: org.postgresql.Driver 15 | jpa: 16 | database: postgresql 17 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 18 | management: 19 | endpoints: 20 | web: 21 | exposure: 22 | include: "*" 23 | eureka: 24 | client: 25 | healthcheck: 26 | enabled: true 27 | instance: 28 | preferIpAddress: true 29 | leaseRenewalIntervalInSeconds: 5 30 | leaseExpirationDurationInSeconds: 5 31 | eventuatelocal: 32 | kafka: 33 | bootstrap: 34 | servers: kafka:29092 35 | zookeeper: 36 | connection: 37 | string: zookeeper:2181 -------------------------------------------------------------------------------- /configuration-repo/admin-default.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8888 3 | spring: 4 | boot: 5 | admin: 6 | probed-endpoints: env, metrics, trace, jolokia, info, configprops 7 | application: 8 | name: admin 9 | eureka: 10 | client: 11 | healthcheck: 12 | enabled: true 13 | instance: 14 | preferIpAddress: true 15 | leaseRenewalIntervalInSeconds: 5 16 | leaseExpirationDurationInSeconds: 5 -------------------------------------------------------------------------------- /configuration-repo/delivery-default.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 0 8 | spring: 9 | application: 10 | name: delivery 11 | boot: 12 | admin: 13 | client: 14 | url: http://localhost:8888 15 | datasource: 16 | url: jdbc:postgresql://localhost:5432/eventuate 17 | username: postgres 18 | password: pass 19 | driver-class-name: org.postgresql.Driver 20 | initialization-mode: always 21 | continue-on-error: true 22 | jpa: 23 | database: postgresql 24 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 25 | generate-ddl: true 26 | management: 27 | endpoints: 28 | web: 29 | exposure: 30 | include: "*" 31 | eventuatelocal: 32 | kafka: 33 | bootstrap: 34 | servers: http://localhost:9092 35 | zookeeper: 36 | connection: 37 | string: http://localhost:2181 -------------------------------------------------------------------------------- /configuration-repo/delivery-prod.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 8084 8 | spring: 9 | application: 10 | name: delivery 11 | boot: 12 | admin: 13 | client: 14 | url: http://admin 15 | datasource: 16 | url: jdbc:postgresql://postgres/eventuate 17 | username: eventuate 18 | password: eventuate 19 | driver-class-name: org.postgresql.Driver 20 | initialization-mode: always 21 | continue-on-error: true 22 | jpa: 23 | database: postgresql 24 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 25 | generate-ddl: true 26 | management: 27 | endpoints: 28 | web: 29 | exposure: 30 | include: "*" 31 | eventuatelocal: 32 | kafka: 33 | bootstrap: 34 | servers: kafka:29092 35 | zookeeper: 36 | connection: 37 | string: zookeeper:2181 -------------------------------------------------------------------------------- /configuration-repo/gateway-default.yaml: -------------------------------------------------------------------------------- 1 | zuul: 2 | prefix: /api 3 | server: 4 | port: 8008 5 | spring: 6 | main: 7 | allow-bean-definition-overriding: true 8 | application: 9 | name: gateway 10 | boot: 11 | admin: 12 | client: 13 | url: ${ADMIN_URI:http://localhost:8888} 14 | management: 15 | endpoints: 16 | web: 17 | exposure: 18 | include: "*" 19 | security: 20 | oauth2: 21 | client: 22 | clientAuthenticationScheme: form 23 | userAuthorizationUri: https://accounts.google.com/o/oauth2/v2/auth 24 | accessTokenUri: https://www.googleapis.com/oauth2/v4/token 25 | scope: openid,email,profile 26 | resource: 27 | userInfoUri: https://www.googleapis.com/oauth2/v3/userinfo 28 | preferTokenInfo: true -------------------------------------------------------------------------------- /configuration-repo/gateway-prod.yaml: -------------------------------------------------------------------------------- 1 | zuul: 2 | prefix: /api 3 | server: 4 | port: 8008 5 | spring: 6 | main: 7 | allow-bean-definition-overriding: true 8 | application: 9 | name: gateway 10 | boot: 11 | admin: 12 | client: 13 | url: http://admin/ 14 | management: 15 | endpoints: 16 | web: 17 | exposure: 18 | include: "*" 19 | security: 20 | oauth2: 21 | client: 22 | clientAuthenticationScheme: form 23 | userAuthorizationUri: https://accounts.google.com/o/oauth2/v2/auth 24 | accessTokenUri: https://www.googleapis.com/oauth2/v4/token 25 | scope: openid,email,profile 26 | resource: 27 | userInfoUri: https://www.googleapis.com/oauth2/v3/userinfo 28 | preferTokenInfo: true -------------------------------------------------------------------------------- /configuration-repo/notification-default.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 0 8 | spring: 9 | application: 10 | name: notification 11 | boot: 12 | admin: 13 | client: 14 | url: http://localhost:8888 15 | datasource: 16 | url: jdbc:postgresql://localhost:5432/eventuate 17 | username: postgres 18 | password: pass 19 | driver-class-name: org.postgresql.Driver 20 | jpa: 21 | database: postgresql 22 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 23 | generate-ddl: true 24 | mail: 25 | host: smtp.gmail.com 26 | port: 587 27 | username: 28 | password: 29 | properties: 30 | mail: 31 | smptp: 32 | auth: true 33 | starttls: 34 | enable: true 35 | management: 36 | endpoints: 37 | web: 38 | exposure: 39 | include: "*" 40 | eventuatelocal: 41 | kafka: 42 | bootstrap: 43 | servers: http://localhost:9092 44 | zookeeper: 45 | connection: 46 | string: http://localhost:2181 -------------------------------------------------------------------------------- /configuration-repo/notification-prod.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 8085 8 | spring: 9 | application: 10 | name: notification 11 | boot: 12 | admin: 13 | client: 14 | url: http://admin:8888 15 | datasource: 16 | url: jdbc:postgresql://postgres/eventuate 17 | username: eventuate 18 | password: eventuate 19 | driver-class-name: org.postgresql.Driver 20 | jpa: 21 | database: postgresql 22 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 23 | generate-ddl: true 24 | mail: 25 | host: smtp.gmail.com 26 | port: 587 27 | username: 28 | password: 29 | properties: 30 | mail: 31 | smptp: 32 | auth: true 33 | starttls: 34 | enable: true 35 | management: 36 | endpoints: 37 | web: 38 | exposure: 39 | include: "*" 40 | eventuatelocal: 41 | kafka: 42 | bootstrap: 43 | servers: kafka:29092 44 | zookeeper: 45 | connection: 46 | string: zookeeper:2181 -------------------------------------------------------------------------------- /configuration-repo/order-default.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 0 8 | spring: 9 | application: 10 | name: order 11 | boot: 12 | admin: 13 | client: 14 | url: http://localhost:8888 15 | datasource: 16 | url: jdbc:postgresql://localhost:5432/eventuate 17 | username: postgres 18 | password: pass 19 | driver-class-name: org.postgresql.Driver 20 | jpa: 21 | database: postgresql 22 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 23 | generate-ddl: true 24 | management: 25 | endpoints: 26 | web: 27 | exposure: 28 | include: "*" 29 | eventuatelocal: 30 | kafka: 31 | bootstrap: 32 | servers: http://localhost:9092 33 | zookeeper: 34 | connection: 35 | string: http://localhost:2181 -------------------------------------------------------------------------------- /configuration-repo/order-prod.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 8083 8 | spring: 9 | application: 10 | name: order 11 | boot: 12 | admin: 13 | client: 14 | url: http://admin/ 15 | datasource: 16 | url: jdbc:postgresql://postgres/eventuate 17 | username: eventuate 18 | password: eventuate 19 | driver-class-name: org.postgresql.Driver 20 | jpa: 21 | database: postgresql 22 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 23 | generate-ddl: true 24 | management: 25 | endpoints: 26 | web: 27 | exposure: 28 | include: "*" 29 | eventuatelocal: 30 | kafka: 31 | bootstrap: 32 | servers: kafka:29092 33 | zookeeper: 34 | connection: 35 | string: zookeeper:2181 -------------------------------------------------------------------------------- /configuration-repo/server-default.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8761 3 | eureka: 4 | client: 5 | registerWithEureka: false 6 | fetchRegistry: false 7 | spring: 8 | boot: 9 | admin: 10 | client: 11 | url: ${ADMIN_URI:http://localhost:8888} 12 | management: 13 | endpoints: 14 | web: 15 | exposure: 16 | include: "*" -------------------------------------------------------------------------------- /configuration-repo/store-default.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 0 8 | spring: 9 | application: 10 | name: store 11 | boot: 12 | admin: 13 | client: 14 | url: http://localhost:8888 15 | datasource: 16 | url: jdbc:postgresql://localhost:5432/eventuate 17 | username: postgres 18 | password: pass 19 | driver-class-name: org.postgresql.Driver 20 | initialization-mode: always 21 | continue-on-error: true 22 | jpa: 23 | database: postgresql 24 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 25 | generate-ddl: true 26 | management: 27 | endpoints: 28 | web: 29 | exposure: 30 | include: "*" 31 | eventuatelocal: 32 | kafka: 33 | bootstrap: 34 | servers: http://localhost:9092 35 | zookeeper: 36 | connection: 37 | string: http://localhost:2181 38 | logging: 39 | level: 40 | org: 41 | springframework: 42 | orm: 43 | jpa: INFO 44 | hibernate: 45 | SQL: DEBUG 46 | io: 47 | eventuate: DEBUG -------------------------------------------------------------------------------- /configuration-repo/store-prod.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | preferIpAddress: true 4 | leaseRenewalIntervalInSeconds: 5 5 | leaseExpirationDurationInSeconds: 5 6 | server: 7 | port: 8082 8 | spring: 9 | application: 10 | name: store 11 | boot: 12 | admin: 13 | client: 14 | url: http://admin/ 15 | datasource: 16 | url: jdbc:postgresql://postgres/eventuate 17 | username: eventuate 18 | password: eventuate 19 | driver-class-name: org.postgresql.Driver 20 | initialization-mode: always 21 | continue-on-error: true 22 | jpa: 23 | database: postgresql 24 | database-platform: org.hibernate.dialect.PostgreSQL10Dialect 25 | generate-ddl: true 26 | management: 27 | endpoints: 28 | web: 29 | exposure: 30 | include: "*" 31 | eventuatelocal: 32 | kafka: 33 | bootstrap: 34 | servers: kafka:29092 35 | zookeeper: 36 | connection: 37 | string: zookeeper:2181 38 | logging: 39 | level: 40 | org: 41 | springframework: 42 | orm: 43 | jpa: INFO 44 | hibernate: 45 | SQL: DEBUG 46 | io: 47 | eventuate: DEBUG -------------------------------------------------------------------------------- /delivery/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /delivery/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/delivery/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /delivery/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /delivery/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "delivery" 2 | -------------------------------------------------------------------------------- /delivery/src/main/kotlin/com/example/delivery/DeliveryApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.delivery 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 6 | import org.springframework.cloud.context.config.annotation.RefreshScope 7 | import org.springframework.scheduling.annotation.EnableScheduling 8 | 9 | @EnableDiscoveryClient 10 | @SpringBootApplication 11 | @EnableScheduling 12 | @RefreshScope 13 | class DeliveryApplication 14 | 15 | fun main(args: Array) { 16 | runApplication(*args) 17 | } 18 | -------------------------------------------------------------------------------- /delivery/src/main/kotlin/com/example/delivery/DeliveryController.kt: -------------------------------------------------------------------------------- 1 | package com.example.delivery 2 | 3 | import com.example.common.BaseSwaggerConfiguration 4 | import com.example.delivery.service.DeliveryService 5 | import io.swagger.annotations.Api 6 | import io.swagger.annotations.ApiOperation 7 | import org.springframework.context.annotation.Configuration 8 | import org.springframework.web.bind.annotation.GetMapping 9 | import org.springframework.web.bind.annotation.PathVariable 10 | import org.springframework.web.bind.annotation.RestController 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2 12 | 13 | @Configuration 14 | @EnableSwagger2 15 | open class SwaggerDocumentation( 16 | basePackage: String = "com.example.delivery", 17 | service: String = "Delivery" 18 | ) : BaseSwaggerConfiguration(basePackage, service) 19 | 20 | 21 | @RestController 22 | @Api(value = "API for Account service") 23 | class DeliveryController(private val deliveryService: DeliveryService) { 24 | 25 | @GetMapping("/{city}") 26 | @ApiOperation(value = "Check delivery by city name") 27 | fun checkDelivery(@PathVariable("city") city: String) = deliveryService.checkDelivery(city) 28 | 29 | @GetMapping("/order/{id}") 30 | @ApiOperation(value = "Getting delivery information by id") 31 | fun getDeliveryInfo(@PathVariable("id") id: String) = deliveryService.getDeliveryInfo(id) 32 | } -------------------------------------------------------------------------------- /delivery/src/main/kotlin/com/example/delivery/exception/DeliveryException.kt: -------------------------------------------------------------------------------- 1 | package com.example.delivery.exception 2 | 3 | import org.springframework.http.ResponseEntity 4 | import org.springframework.web.bind.annotation.ControllerAdvice 5 | import org.springframework.web.bind.annotation.ExceptionHandler 6 | 7 | class DeliveryException(override val message: String) : RuntimeException(message) 8 | 9 | @ControllerAdvice 10 | class DeliveryExceptionHandler { 11 | 12 | @ExceptionHandler(DeliveryException::class) 13 | fun handleMonitoringException(ex: DeliveryException): ResponseEntity { 14 | return ResponseEntity.badRequest().body(ex.message) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /delivery/src/main/kotlin/com/example/delivery/repository/DeliveryRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.delivery.repository 2 | 3 | import org.springframework.data.repository.CrudRepository 4 | import javax.persistence.* 5 | 6 | interface CityDeliveryRepository : CrudRepository { 7 | 8 | fun findByArrival(arrival: String): List 9 | } 10 | 11 | interface DeliveryRepository : CrudRepository { 12 | 13 | fun findByOrderId(orderId: String): Delivery? 14 | } 15 | 16 | @Entity 17 | @Table(name = "delivery", schema = "eventuate") 18 | data class Delivery( 19 | @Id @GeneratedValue(strategy = GenerationType.AUTO) var id: Long? = null, 20 | @Column(name = "delivery_track") var deliveryTrack: String? = null, 21 | @OneToOne var city: City? = null, 22 | var duration: Int = 0, 23 | @Column(name = "order_id") var orderId: String? = null, 24 | var status: Status = Status.Created 25 | ) 26 | 27 | @Entity 28 | @Table(name = "city", schema = "eventuate") 29 | data class City( 30 | @Id @GeneratedValue(strategy = GenerationType.AUTO) var id: Long? = null, 31 | var destination: String? = null, 32 | var arrival: String? = null, 33 | var duration: Int = 0 34 | ) 35 | 36 | enum class Status { 37 | Created, Updated, Delivered 38 | } -------------------------------------------------------------------------------- /delivery/src/main/kotlin/com/example/delivery/service/DeliveryService.kt: -------------------------------------------------------------------------------- 1 | package com.example.delivery.service 2 | 3 | import com.example.delivery.exception.DeliveryException 4 | import com.example.delivery.repository.* 5 | import org.apache.juli.logging.LogFactory 6 | import org.springframework.scheduling.annotation.Scheduled 7 | import java.util.* 8 | 9 | interface DeliveryService { 10 | fun checkDelivery(city: String): City 11 | 12 | fun getDeliveryInfo(id: String): Delivery 13 | 14 | fun createDelivery(city: String, orderId: String) 15 | 16 | fun changeDeliveryDuration() 17 | } 18 | 19 | class DeliveryServiceImpl( 20 | private val deliveryRepository: DeliveryRepository, 21 | private val cityDeliveryRepository: CityDeliveryRepository 22 | ) : DeliveryService { 23 | 24 | private val logger = LogFactory.getLog(DeliveryService::class.java) 25 | 26 | override fun checkDelivery(city: String) = cityDeliveryRepository.findByArrival(city) 27 | .minByOrNull { it.duration } ?: throw DeliveryException("City not supported") 28 | 29 | override fun getDeliveryInfo(id: String) = 30 | deliveryRepository.findByOrderId(id) ?: throw DeliveryException("Delivery not found") 31 | 32 | override fun createDelivery(city: String, orderId: String) { 33 | logger.info("Create delivery: $orderId to $city") 34 | val deliveryCity = checkDelivery(city) 35 | deliveryRepository.save( 36 | Delivery( 37 | deliveryTrack = UUID.randomUUID().toString(), 38 | city = deliveryCity, 39 | duration = deliveryCity.duration, 40 | orderId = orderId 41 | ) 42 | ) 43 | } 44 | 45 | @Scheduled(cron = "0 0/60 * * * *") 46 | override fun changeDeliveryDuration() { 47 | deliveryRepository.findAll() 48 | .filter { it.status != Status.Delivered } 49 | .forEach { 50 | when (it.duration) { 51 | 1 -> { 52 | it.status = Status.Delivered 53 | it.duration = 0 54 | } 55 | else -> { 56 | it.status = Status.Updated 57 | it.duration-- 58 | } 59 | } 60 | deliveryRepository.save(it) 61 | } 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /delivery/src/main/resources/bootstrap.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | serviceUrl: 4 | defaultZone: http://eureka:8761/eureka 5 | spring: 6 | application: 7 | name: delivery 8 | cloud: 9 | config: 10 | uri: http://localhost:8088 -------------------------------------------------------------------------------- /delivery/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | create table city 2 | ( 3 | id bigint not null 4 | constraint city_pkey 5 | primary key, 6 | arrival varchar(255), 7 | destination varchar(255), 8 | duration integer not null 9 | ); 10 | 11 | alter table city 12 | owner to eventuate; 13 | 14 | create table delivery 15 | ( 16 | id bigint not null 17 | constraint delivery_pkey 18 | primary key, 19 | delivery_track varchar(255), 20 | duration integer not null, 21 | order_id varchar(255), 22 | city_id bigint 23 | constraint fk4e0fu5fqs6rb0xn6bw39p6uyl 24 | references city 25 | ); 26 | 27 | alter table delivery 28 | owner to eventuate; 29 | 30 | INSERT INTO eventuate.city (id, arrival, destination, duration) VALUES (1, 'Moscow', 'A', 3); 31 | INSERT INTO eventuate.city (id, arrival, destination, duration) VALUES (2, 'Saint-Petersburg', 'A', 2); 32 | INSERT INTO eventuate.city (id, arrival, destination, duration) VALUES (3, 'Voronezh', 'A', 5); 33 | INSERT INTO eventuate.city (id, arrival, destination, duration) VALUES (4, 'Moscow', 'B', 2); 34 | INSERT INTO eventuate.city (id, arrival, destination, duration) VALUES (5, 'Saint-Petersburg', 'B', 3); -------------------------------------------------------------------------------- /e2e/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /e2e/README.md: -------------------------------------------------------------------------------- 1 | # E2E Testing 2 | > Supports [test-containers](https://www.testcontainers.org/) 3 | 4 |   5 | 6 | ### How to run 🚩 7 | > Note: Docker installed and already logged in 8 | ``` 9 | ./gradlew test 10 | ``` 11 | -------------------------------------------------------------------------------- /e2e/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.3.3.RELEASE" 5 | id("io.spring.dependency-management") version "1.0.10.RELEASE" 6 | kotlin("jvm") version "1.3.72" 7 | kotlin("plugin.spring") version "1.3.72" 8 | } 9 | 10 | group = "com.example" 11 | version = "1.0.0" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | val testContainerVersion = "1.14.3" 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | implementation("org.springframework.boot:spring-boot-starter-web") 21 | implementation("org.jetbrains.kotlin:kotlin-reflect") 22 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 23 | testImplementation("org.testcontainers:testcontainers:$testContainerVersion") 24 | testImplementation("org.testcontainers:junit-jupiter:$testContainerVersion") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 26 | exclude(group = "org.junit.vintage", module = "junit-vintage-engine") 27 | } 28 | } 29 | 30 | tasks.withType { 31 | useJUnitPlatform() 32 | } 33 | 34 | tasks.withType { 35 | kotlinOptions { 36 | freeCompilerArgs = listOf("-Xjsr305=strict") 37 | jvmTarget = "11" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /e2e/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/e2e/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /e2e/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /e2e/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "e2e" 2 | -------------------------------------------------------------------------------- /e2e/src/main/kotlin/com/example/e2e/E2eApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.e2e 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class E2eApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /e2e/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /e2e/src/test/kotlin/com/example/e2e/EurekaTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.e2e 2 | 3 | import com.example.e2e.container.ConfigContainer 4 | import com.example.e2e.container.EurekaContainer 5 | import com.example.e2e.container.GatewayContainer 6 | import com.example.e2e.container.RestExecutor 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Assertions.assertTrue 9 | import org.junit.jupiter.api.Test 10 | import org.springframework.http.HttpStatus 11 | import org.testcontainers.containers.Network 12 | import org.testcontainers.junit.jupiter.Container 13 | import org.testcontainers.junit.jupiter.Testcontainers 14 | 15 | @Testcontainers 16 | class EurekaTest { 17 | 18 | private val network = Network.newNetwork() 19 | 20 | @Container 21 | val eurekaContainer = EurekaContainer(network) 22 | 23 | @Container 24 | val configContainer = ConfigContainer(network, eurekaContainer) 25 | 26 | @Container 27 | val gatewayContainer = GatewayContainer(network, eurekaContainer, configContainer) 28 | 29 | private val restExecutor = RestExecutor() 30 | 31 | @Test 32 | fun test() { 33 | assertTrue(eurekaContainer.isRunning) 34 | assertTrue(configContainer.isRunning) 35 | assertTrue(gatewayContainer.isRunning) 36 | val url = "http://${configContainer.host}:${configContainer.firstMappedPort}" 37 | mutableListOf("store", "order", "account", "gateway", "delivery", "notification", "server", "gateway", "admin").forEach { 38 | assertEquals(HttpStatus.OK, restExecutor.getResource(url, it, "default").statusCode) 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /e2e/src/test/kotlin/com/example/e2e/OrderTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.e2e 2 | 3 | import com.example.e2e.container.* 4 | import org.junit.jupiter.api.Assertions.* 5 | import org.junit.jupiter.api.Test 6 | import org.springframework.http.HttpStatus 7 | import org.testcontainers.containers.Network 8 | import org.testcontainers.junit.jupiter.Container 9 | import org.testcontainers.junit.jupiter.Testcontainers 10 | 11 | @Testcontainers 12 | class OrderTest { 13 | 14 | private val network = Network.newNetwork() 15 | 16 | @Container 17 | val eurekaContainer = EurekaContainer(network) 18 | 19 | @Container 20 | val configContainer = ConfigContainer(network, eurekaContainer) 21 | 22 | @Container 23 | val zookeeperContainer = ZookeeperContainer(network) 24 | 25 | @Container 26 | val kafkaContainer = KafkaContainer(network, zookeeperContainer) 27 | 28 | @Container 29 | val postgresContainer = PostgresContainer(network) 30 | 31 | @Container 32 | val cdcContainer = CdcContainer(network, 33 | zookeeperContainer = zookeeperContainer, 34 | kafkaContainer = kafkaContainer, 35 | postgresContainer = postgresContainer) 36 | 37 | @Container 38 | val storeContainer = StoreContainer(network, 39 | cdcContainer = cdcContainer, 40 | eurekaContainer = eurekaContainer, 41 | configContainer = configContainer) 42 | 43 | @Container 44 | val orderContainer = OrderContainer(network, 45 | cdcContainer = cdcContainer, 46 | eurekaContainer = eurekaContainer, 47 | configContainer = configContainer) 48 | 49 | @Container 50 | val deliveryContainer = DeliveryContainer(network, 51 | cdcContainer = cdcContainer, 52 | eurekaContainer = eurekaContainer, 53 | configContainer = configContainer) 54 | 55 | private val restExecutor = RestExecutor() 56 | 57 | @Test 58 | fun test() { 59 | assertTrue(storeContainer.isRunning) 60 | assertTrue(orderContainer.isRunning) 61 | assertTrue(deliveryContainer.isRunning) 62 | val url = "http://${orderContainer.host}:${orderContainer.firstMappedPort}" 63 | val order = restExecutor.createOrder(url) 64 | val orderBody = order.body!! 65 | assertEquals(HttpStatus.OK, order.statusCode) 66 | assertNotNull(orderBody) 67 | val orderById = restExecutor.getOrderById(url, orderBody.id.toString()) 68 | assertEquals(HttpStatus.OK, orderById.statusCode) 69 | assertNotNull(orderById.body) 70 | } 71 | } -------------------------------------------------------------------------------- /e2e/src/test/kotlin/com/example/e2e/StoreTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.e2e 2 | 3 | import com.example.e2e.container.* 4 | import org.junit.jupiter.api.Assertions 5 | import org.junit.jupiter.api.Test 6 | import org.springframework.http.HttpStatus 7 | import org.testcontainers.containers.Network 8 | import org.testcontainers.junit.jupiter.Container 9 | import org.testcontainers.junit.jupiter.Testcontainers 10 | 11 | @Suppress("CAST_NEVER_SUCCEEDS") 12 | @Testcontainers 13 | class StoreTest { 14 | 15 | private val network = Network.newNetwork() 16 | 17 | @Container 18 | val eurekaContainer = EurekaContainer(network) 19 | 20 | @Container 21 | val configContainer = ConfigContainer(network, eurekaContainer) 22 | 23 | @Container 24 | val zookeeperContainer = ZookeeperContainer(network) 25 | 26 | @Container 27 | val kafkaContainer = KafkaContainer(network, zookeeperContainer) 28 | 29 | @Container 30 | val postgresContainer = PostgresContainer(network) 31 | 32 | @Container 33 | val cdcContainer = CdcContainer(network, 34 | zookeeperContainer = zookeeperContainer, 35 | kafkaContainer = kafkaContainer, 36 | postgresContainer = postgresContainer) 37 | 38 | @Container 39 | val storeContainer = StoreContainer(network, 40 | cdcContainer = cdcContainer, 41 | eurekaContainer = eurekaContainer, 42 | configContainer = configContainer) 43 | 44 | private val restExecutor = RestExecutor() 45 | 46 | @Test 47 | fun test() { 48 | Assertions.assertTrue(storeContainer.isRunning) 49 | val url = "http://${storeContainer.host}:${storeContainer.firstMappedPort}" 50 | val presents = restExecutor.getPresents(url) 51 | val presentsBody = presents.body!! 52 | Assertions.assertEquals(HttpStatus.OK, presents.statusCode) 53 | Assertions.assertFalse(presentsBody.isEmpty()) 54 | val present = restExecutor.getPresentById(url, (presentsBody[0] as LinkedHashMap)["id"].toString()) 55 | Assertions.assertEquals(HttpStatus.OK, present.statusCode) 56 | Assertions.assertNotNull(present.body) 57 | } 58 | } -------------------------------------------------------------------------------- /e2e/src/test/kotlin/com/example/e2e/container/RestExecutor.kt: -------------------------------------------------------------------------------- 1 | package com.example.e2e.container 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | import org.springframework.core.ParameterizedTypeReference 6 | import org.springframework.http.HttpEntity 7 | import org.springframework.http.ResponseEntity 8 | import org.springframework.web.client.RestTemplate 9 | import org.springframework.web.client.getForEntity 10 | 11 | 12 | class RestExecutor { 13 | 14 | private val restTemplate = RestTemplate() 15 | 16 | fun getPresents(url: String): ResponseEntity> = restTemplate.getForEntity("$url/presents", object : ParameterizedTypeReference>() {}) 17 | 18 | fun getPresentById(url: String, id: String) = restTemplate.getForEntity("$url/$id", Product::class.java) 19 | 20 | fun createOrder(url: String) = restTemplate.postForEntity("$url/order", 21 | HttpEntity(OrderDetails(user = "1", city = "Moscow", product = "10")), 22 | Order::class.java) 23 | 24 | fun getOrderById(url: String, id: String) = restTemplate.getForEntity("$url/order/$id", Order::class.java) 25 | 26 | fun getResource(url: String, resource: String, profile: String) = restTemplate.getForEntity("$url/$resource/$profile", String::class.java) 27 | } 28 | 29 | data class OrderDetails( 30 | var user: String, 31 | var city: String, 32 | var product: String 33 | ) 34 | 35 | 36 | data class Product @JsonCreator constructor( 37 | @JsonProperty("id") var id: Long, 38 | @JsonProperty("description") var description: String, 39 | @JsonProperty("name") var name: String, 40 | @JsonProperty("image") var image: String, 41 | @JsonProperty("count") var count: Int 42 | ) 43 | 44 | data class Order @JsonCreator constructor( 45 | @JsonProperty("id") var id: Long, 46 | @JsonProperty("user") var user: String, 47 | @JsonProperty("product") var product: String, 48 | @JsonProperty("status") var status: String, 49 | @JsonProperty("track") var track: String, 50 | @JsonProperty("rejectionReason") var rejectionReason: String 51 | ) 52 | -------------------------------------------------------------------------------- /gateway/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /gateway/build.gradle.kts: -------------------------------------------------------------------------------- 1 | java.sourceCompatibility = JavaVersion.VERSION_11 2 | val buildNumber by extra("0") 3 | 4 | extra["springCloudVersion"] = "Hoxton.SR6" 5 | extra["springBootAdminVersion"] = "2.2.4" 6 | 7 | dependencies { 8 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-zuul") 9 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client") 10 | implementation("de.codecentric:spring-boot-admin-starter-client") 11 | implementation("org.springframework.cloud:spring-cloud-config-client") 12 | implementation("org.springframework.boot:spring-boot-starter-webflux") 13 | implementation("org.springframework.boot:spring-boot-starter-security") 14 | implementation("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure") 15 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 16 | exclude(group = "org.junit.vintage", module = "junit-vintage-engine") 17 | } 18 | } 19 | 20 | dependencyManagement { 21 | imports { 22 | mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}") 23 | mavenBom("de.codecentric:spring-boot-admin-dependencies:${property("springBootAdminVersion")}") 24 | } 25 | } 26 | 27 | jib { 28 | to { 29 | image = "elvaliev/gateway" 30 | tags = setOf("$version", "$version.${extra["buildNumber"]}") 31 | auth { 32 | username = System.getenv("DOCKERHUB_USERNAME") 33 | password = System.getenv("DOCKERHUB_PASSWORD") 34 | } 35 | } 36 | container { 37 | labels = mapOf( 38 | "maintainer" to "Elina Valieva ", 39 | "org.opencontainers.image.title" to "gateway", 40 | "org.opencontainers.image.description" to "Spring microservices", 41 | "org.opencontainers.image.version" to "$version", 42 | "org.opencontainers.image.authors" to "Elina Valieva >", 43 | "org.opencontainers.image.url" to "https://github.com/ElinaValieva/spring-microservices" 44 | ) 45 | jvmFlags = listOf( 46 | "-server", 47 | "-Djava.awt.headless=true", 48 | "-XX:InitialRAMFraction=2", 49 | "-XX:MinRAMFraction=2", 50 | "-XX:MaxRAMFraction=2", 51 | "-XX:+UseG1GC", 52 | "-XX:MaxGCPauseMillis=100", 53 | "-XX:+UseStringDeduplication" 54 | ) 55 | workingDirectory = "/gateway" 56 | } 57 | } -------------------------------------------------------------------------------- /gateway/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/gateway/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gateway/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gateway/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "gateway" 2 | -------------------------------------------------------------------------------- /gateway/src/main/kotlin/com/example/gateway/GatewayApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.gateway 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 6 | import org.springframework.cloud.context.config.annotation.RefreshScope 7 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy 8 | 9 | @SpringBootApplication 10 | @EnableZuulProxy 11 | @EnableDiscoveryClient 12 | @RefreshScope 13 | class GatewayApplication 14 | 15 | fun main(args: Array) { 16 | runApplication(*args) 17 | } 18 | -------------------------------------------------------------------------------- /gateway/src/main/kotlin/com/example/gateway/GatewayController.kt: -------------------------------------------------------------------------------- 1 | package com.example.gateway 2 | 3 | import com.example.gateway.configuration.Client 4 | import com.example.gateway.configuration.mapToUser 5 | import org.springframework.security.oauth2.provider.OAuth2Authentication 6 | import org.springframework.web.bind.annotation.GetMapping 7 | import org.springframework.web.bind.annotation.PathVariable 8 | import org.springframework.web.bind.annotation.RestController 9 | import reactor.core.publisher.Mono 10 | import java.security.Principal 11 | import java.util.* 12 | 13 | @Suppress("UNCHECKED_CAST") 14 | @RestController 15 | class GatewayController(private val client: Client) { 16 | 17 | @GetMapping("/my") 18 | fun hello(principal: Principal): String { 19 | val user = mapToUser((principal as OAuth2Authentication).userAuthentication.details as MutableMap) 20 | return "Hello ${user.name}" 21 | } 22 | 23 | @GetMapping("/info/{id}") 24 | fun getUserInfo( 25 | @PathVariable("id") orderId: Long 26 | ): Mono { 27 | return Mono 28 | .zip( 29 | client.getOrderById(orderId) 30 | .map { Optional.of(it) }, 31 | client.getDeliveryInfo(orderId) 32 | .map { Optional.of(it) } 33 | ) 34 | .flatMap { 35 | Mono.just( 36 | OrderInfo( 37 | order = it.t1.get(), 38 | delivery = it.t2.get() 39 | ) 40 | ) 41 | } 42 | .zipWhen { it.order?.product?.let { it1 -> client.getProductById(it1) } } 43 | .flatMap { 44 | Mono.just( 45 | OrderInfo( 46 | order = it.t1.order, 47 | delivery = it.t1.delivery, 48 | store = it.t2 49 | ) 50 | ) 51 | } 52 | .zipWhen { it.order?.user?.let { it1 -> client.getUserById(it1) } } 53 | .flatMap { 54 | Mono.just( 55 | convertToOrder( 56 | user = it.t2, 57 | store = it.t1.store!!, 58 | order = it.t1.order!!, 59 | delivery = it.t1.delivery!! 60 | ) 61 | ) 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /gateway/src/main/kotlin/com/example/gateway/Model.kt: -------------------------------------------------------------------------------- 1 | package com.example.gateway 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | 6 | data class User @JsonCreator constructor( 7 | @JsonProperty("id") var id: String, 8 | @JsonProperty("name") var name: String, 9 | @JsonProperty("email") var email: String, 10 | @JsonProperty("picture") var picture: String, 11 | @JsonProperty("locale") var locale: String, 12 | @JsonProperty("emailVerified") var emailVerified: Boolean 13 | ) 14 | 15 | data class Order @JsonCreator constructor( 16 | @JsonProperty("id") var id: Long, 17 | @JsonProperty("user") var user: String, 18 | @JsonProperty("product") var product: String, 19 | @JsonProperty("status") var status: String, 20 | @JsonProperty("track") var track: String, 21 | @JsonProperty("rejectionReason") var rejectionReason: String 22 | ) 23 | 24 | data class Product @JsonCreator constructor( 25 | @JsonProperty("id") var id: Long, 26 | @JsonProperty("description") var description: String, 27 | @JsonProperty("name") var name: String, 28 | @JsonProperty("image") var image: String, 29 | @JsonProperty("count") var count: Int 30 | ) 31 | 32 | data class Delivery @JsonCreator constructor( 33 | @JsonProperty("id") var id: Long, 34 | @JsonProperty("deliveryTrack") var deliveryTrack: String, 35 | @JsonProperty("duration") var duration: Int, 36 | @JsonProperty("orderId") var orderId: String, 37 | @JsonProperty("status") var status: String 38 | ) 39 | 40 | data class OrderInfo( 41 | val user: User? = null, 42 | val order: Order? = null, 43 | val delivery: Delivery? = null, 44 | val store: Product? = null 45 | ) 46 | 47 | data class OrderDetails( 48 | val userId: String, 49 | val username: String, 50 | val email: String, 51 | val productId: Long, 52 | val productInfo: String, 53 | val productLink: String, 54 | val orderId: Long, 55 | val orderTrack: String, 56 | val orderStatus: String, 57 | val deliveryId: Long, 58 | val deliveryTrack: String, 59 | val deliveryStatus: String, 60 | val deliveryDuration: Int 61 | ) 62 | 63 | fun convertToOrder(order: Order, user: User, store: Product, delivery: Delivery) = 64 | OrderDetails( 65 | userId = user.id, 66 | username = user.name, 67 | email = user.email, 68 | productId = store.id, 69 | productInfo = "${store.name} ${store.description}", 70 | productLink = store.image, 71 | orderId = order.id, 72 | orderStatus = order.status, 73 | orderTrack = order.track, 74 | deliveryId = delivery.id, 75 | deliveryDuration = delivery.duration, 76 | deliveryStatus = delivery.status, 77 | deliveryTrack = delivery.deliveryTrack 78 | ) 79 | -------------------------------------------------------------------------------- /gateway/src/main/kotlin/com/example/gateway/configuration/Client.kt: -------------------------------------------------------------------------------- 1 | package com.example.gateway.configuration 2 | 3 | import com.example.gateway.Delivery 4 | import com.example.gateway.Order 5 | import com.example.gateway.Product 6 | import com.example.gateway.User 7 | import org.springframework.beans.factory.annotation.Value 8 | import org.springframework.context.annotation.Bean 9 | import org.springframework.context.annotation.Configuration 10 | import org.springframework.stereotype.Component 11 | import org.springframework.web.reactive.function.BodyInserters 12 | import org.springframework.web.reactive.function.client.WebClient 13 | import reactor.core.publisher.Mono 14 | import java.net.InetAddress 15 | 16 | @Component 17 | class Client(private val client: WebClient) { 18 | 19 | fun register(user: User): Mono { 20 | return client.post() 21 | .uri("/account/register") 22 | .body(BodyInserters.fromValue(user)) 23 | .retrieve() 24 | .bodyToMono(Void::class.java) 25 | } 26 | 27 | fun getUserById(userId: String): Mono { 28 | return client 29 | .get() 30 | .uri("/account/user/{id}", userId) 31 | .retrieve() 32 | .bodyToMono(User::class.java) 33 | } 34 | 35 | fun getProductById(id: String): Mono { 36 | return client 37 | .get() 38 | .uri("/store/{id}", id) 39 | .retrieve() 40 | .bodyToMono(Product::class.java) 41 | } 42 | 43 | fun getOrderById(id: Long): Mono { 44 | return client 45 | .get() 46 | .uri("/order/order/{id}", id) 47 | .exchange() 48 | .flatMap { it.bodyToMono(Order::class.java) } 49 | } 50 | 51 | fun getDeliveryInfo(id: Long): Mono { 52 | return client 53 | .get() 54 | .uri("/delivery/order/{id}", id) 55 | .retrieve() 56 | .bodyToMono(Delivery::class.java) 57 | } 58 | } 59 | 60 | @Configuration 61 | class ClientConfiguration { 62 | 63 | @Value("\${server.port}") 64 | lateinit var port: String 65 | 66 | @Value("\${zuul.prefix}") 67 | lateinit var prefixApi: String 68 | 69 | @Bean 70 | fun webClient() = WebClient.builder() 71 | .baseUrl("http://${InetAddress.getLoopbackAddress().hostName}:${port}/${prefixApi}/") 72 | .build() 73 | 74 | } -------------------------------------------------------------------------------- /gateway/src/main/kotlin/com/example/gateway/configuration/OAuthSecurityConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.example.gateway.configuration 2 | 3 | import com.example.gateway.User 4 | import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso 5 | import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor 6 | import org.springframework.context.annotation.Bean 7 | import org.springframework.context.annotation.Configuration 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter 11 | 12 | @EnableWebSecurity 13 | @EnableOAuth2Sso 14 | @Configuration 15 | class OAuthSecurityConfiguration : WebSecurityConfigurerAdapter() { 16 | 17 | override fun configure(http: HttpSecurity) { 18 | http.authorizeRequests() 19 | .mvcMatchers("/").permitAll() 20 | .anyRequest().authenticated() 21 | .and() 22 | .csrf().disable() 23 | } 24 | 25 | @Bean 26 | fun extractPrincipal(client: Client): PrincipalExtractor { 27 | return PrincipalExtractor { 28 | val id = it["sub"] as String 29 | if (!client.getUserById(id).blockOptional().isPresent) 30 | client.register(mapToUser(it)) 31 | } 32 | } 33 | } 34 | 35 | fun mapToUser(map: MutableMap) = User( 36 | id = map["sub"] as String, 37 | name = map["name"] as String, 38 | email = map["email"] as String, 39 | locale = map["locale"] as String, 40 | picture = map["picture"] as String, 41 | emailVerified = map["email_verified"] as Boolean 42 | ) -------------------------------------------------------------------------------- /gateway/src/main/kotlin/com/example/gateway/configuration/SwaggerDocumentation.kt: -------------------------------------------------------------------------------- 1 | package com.example.gateway.configuration 2 | 3 | import org.springframework.beans.factory.annotation.Value 4 | import org.springframework.context.annotation.Configuration 5 | import org.springframework.context.annotation.Primary 6 | import springfox.documentation.swagger.web.SwaggerResource 7 | import springfox.documentation.swagger.web.SwaggerResourcesProvider 8 | import springfox.documentation.swagger2.annotations.EnableSwagger2 9 | 10 | @Primary 11 | @Configuration 12 | @EnableSwagger2 13 | class SwaggerDocumentation : SwaggerResourcesProvider { 14 | 15 | @Value("\${zuul.prefix}") 16 | lateinit var prefixApi: String 17 | 18 | companion object SwaggerDocumentationConstants { 19 | const val version = "2.0" 20 | const val pathPattern = "v2/api-docs" 21 | val services = listOf("account", "order", "store", "delivery") 22 | } 23 | 24 | override fun get(): MutableList { 25 | return services.map { swaggerResource(it) }.toMutableList() 26 | } 27 | 28 | private fun swaggerResource(name: String): SwaggerResource { 29 | val swaggerResource = SwaggerResource() 30 | swaggerResource.name = name 31 | swaggerResource.location = "$prefixApi/$name/$pathPattern" 32 | swaggerResource.swaggerVersion = 33 | version 34 | return swaggerResource 35 | } 36 | } -------------------------------------------------------------------------------- /gateway/src/main/resources/bootstrap.yaml: -------------------------------------------------------------------------------- 1 | security: 2 | oauth2: 3 | client: 4 | clientId: client_id 5 | clientSecret: secret 6 | spring: 7 | application: 8 | name: gateway 9 | cloud: 10 | config: 11 | uri: http://localhost:8088 12 | eureka: 13 | client: 14 | service-url: 15 | default-zone: http://localhost:8761/eureka -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | systemProp.swaggerVersion=2.9.2 3 | systemProp.eventuateSpring=0.24.0.RELEASE 4 | systemProp.eventuateCore=0.13.0.RELEASE -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /helm/README.md: -------------------------------------------------------------------------------- 1 | # OpenShift's deployment with helm 2 | > Application charts for deployment 3 | 4 | ### Prerequisites 🚩 5 | - [Helm](https://github.com/helm/helm) 6 | - Kubernetes/OC Clients 7 | 8 |   9 | 10 | ### How to start 🐳 11 | ```shell 12 | ./gradlew helm 13 | ``` -------------------------------------------------------------------------------- /helm/account_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/account_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Configserver 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/account_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/account_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8081" 37 | - name: SPRING_CLOUD_CONFIG_URI 38 | value: {{ .Values.config.url }} 39 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 40 | value: {{ .Values.eureka.url }} 41 | - name: SPRING_PROFILES_ACTIVE 42 | value: {{ .Values.application.profiles }} 43 | readinessProbe: 44 | failureThreshold: 40 45 | httpGet: 46 | path: /actuator/health 47 | port: {{ .Values.application.port }} 48 | scheme: HTTP 49 | initialDelaySeconds: 10 50 | periodSeconds: 15 51 | successThreshold: 1 52 | timeoutSeconds: 400 53 | livenessProbe: 54 | failureThreshold: 10 55 | initialDelaySeconds: 150 56 | periodSeconds: 30 57 | successThreshold: 1 58 | tcpSocket: 59 | port: {{ .Values.application.port }} 60 | timeoutSeconds: 400 61 | 62 | triggers: 63 | - imageChangeParams: 64 | automatic: yes 65 | containerNames: 66 | - {{ .Values.name }} 67 | from: 68 | kind: ImageStreamTag 69 | name: '{{ .Values.name }}:latest' 70 | type: ImageChange 71 | 72 | strategy: 73 | type: Rolling 74 | 75 | -------------------------------------------------------------------------------- /helm/account_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/account_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/account_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/account_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/account_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: account 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: account 13 | replicas: 1 14 | uri: account-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8081 18 | application: 19 | port: 8081 20 | profiles: prod 21 | pdb: 22 | enabled: false 23 | minAvailable: 1 24 | config: 25 | url: http://config/ 26 | eureka: 27 | url: http://server/eureka -------------------------------------------------------------------------------- /helm/admin_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/admin_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Configserver 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/admin_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/admin_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8888" 37 | - name: SPRING_CLOUD_CONFIG_URI 38 | value: {{ .Values.config.url }} 39 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 40 | value: {{ .Values.eureka.url }} 41 | readinessProbe: 42 | failureThreshold: 40 43 | httpGet: 44 | path: /actuator/health 45 | port: {{ .Values.application.port }} 46 | scheme: HTTP 47 | initialDelaySeconds: 10 48 | periodSeconds: 15 49 | successThreshold: 1 50 | timeoutSeconds: 400 51 | livenessProbe: 52 | failureThreshold: 10 53 | initialDelaySeconds: 150 54 | periodSeconds: 30 55 | successThreshold: 1 56 | tcpSocket: 57 | port: {{ .Values.application.port }} 58 | timeoutSeconds: 400 59 | 60 | triggers: 61 | - imageChangeParams: 62 | automatic: yes 63 | containerNames: 64 | - {{ .Values.name }} 65 | from: 66 | kind: ImageStreamTag 67 | name: '{{ .Values.name }}:latest' 68 | type: ImageChange 69 | 70 | strategy: 71 | type: Rolling 72 | 73 | -------------------------------------------------------------------------------- /helm/admin_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/admin_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/admin_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/admin_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/admin_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: admin 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: admin 13 | replicas: 1 14 | uri: admin-server-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8888 18 | application: 19 | port: 8888 20 | pdb: 21 | enabled: false 22 | minAvailable: 1 23 | config: 24 | url: http://config/ 25 | eureka: 26 | url: http://server/eureka -------------------------------------------------------------------------------- /helm/cdc_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/cdc_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices-tools 3 | description: A Helm chart for Eureka server 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/cdc_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/cdc_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | env: 25 | - name: SERVER_PORT 26 | value: '8080' 27 | - name: SPRING_DATASOURCE_URL 28 | value: 'jdbc:postgresql://postgres/eventuate' 29 | - name: SPRING_DATASOURCE_USERNAME 30 | value: eventuate 31 | - name: SPRING_DATASOURCE_PASSWORD 32 | value: eventuate 33 | - name: SPRING_DATASOURCE_TEST_ON_BORROW 34 | value: '"true"' 35 | - name: SPRING_DATASOURCE_VALIDATION_QUERY 36 | value: SELECT 1 37 | - name: SPRING_DATASOURCE_DRIVER_CLASS_NAME 38 | value: org.postgresql.Driver 39 | - name: EVENTUATELOCAL_KAFKA_BOOTSTRAP_SERVERS 40 | value: 'kafka:29092' 41 | - name: EVENTUATELOCAL_ZOOKEEPER_CONNECTION_STRING 42 | value: 'zookeeper:2181' 43 | - name: EVENTUATELOCAL_CDC_READER_NAME 44 | value: PostgresPollingReader 45 | - name: SPRING_PROFILES_ACTIVE 46 | value: EventuatePolling 47 | - name: JAVA_OPTS 48 | value: '-Xmx64m' 49 | 50 | triggers: 51 | - imageChangeParams: 52 | automatic: yes 53 | containerNames: 54 | - {{ .Values.name }} 55 | from: 56 | kind: ImageStreamTag 57 | name: '{{ .Values.name }}:latest' 58 | type: ImageChange 59 | 60 | strategy: 61 | type: Rolling 62 | 63 | -------------------------------------------------------------------------------- /helm/cdc_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Values.docker.tag }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/cdc_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/cdc_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: cdc 2 | docker: 3 | repository: eventuateio 4 | image: eventuate-cdc-service 5 | tag: 0.6.0.RC3 6 | replicas: 1 7 | servers: 8 | serviceType: ClusterIP # [ClusterIP|LoadBalancer] 9 | portName: 8080 10 | application: 11 | port: 8080 12 | pdb: 13 | enabled: false 14 | minAvailable: 1 15 | zookeeper: 16 | port: "2181" 17 | heap_ops: -Xmx64m -------------------------------------------------------------------------------- /helm/config_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/config_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Config server 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/config_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/config_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8088" 37 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 38 | value: {{ .Values.eureka.url }} 39 | readinessProbe: 40 | failureThreshold: 40 41 | httpGet: 42 | path: /actuator/health 43 | port: {{ .Values.application.port }} 44 | scheme: HTTP 45 | initialDelaySeconds: 10 46 | periodSeconds: 15 47 | successThreshold: 1 48 | timeoutSeconds: 400 49 | livenessProbe: 50 | failureThreshold: 10 51 | initialDelaySeconds: 150 52 | periodSeconds: 30 53 | successThreshold: 1 54 | tcpSocket: 55 | port: {{ .Values.application.port }} 56 | timeoutSeconds: 400 57 | 58 | triggers: 59 | - imageChangeParams: 60 | automatic: yes 61 | containerNames: 62 | - {{ .Values.name }} 63 | from: 64 | kind: ImageStreamTag 65 | name: '{{ .Values.name }}:latest' 66 | type: ImageChange 67 | 68 | strategy: 69 | type: Rolling 70 | 71 | -------------------------------------------------------------------------------- /helm/config_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/config_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/config_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/config_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/config_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: config 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: config 13 | replicas: 1 14 | uri: config-server-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8088 18 | application: 19 | port: 8088 20 | pdb: 21 | enabled: false 22 | minAvailable: 1 23 | eureka: 24 | url: http://server/eureka -------------------------------------------------------------------------------- /helm/delivery_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/delivery_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Configserver 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/delivery_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/delivery_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8084" 37 | - name: SPRING_CLOUD_CONFIG_URI 38 | value: {{ .Values.config.url }} 39 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 40 | value: {{ .Values.eureka.url }} 41 | - name: SPRING_PROFILES_ACTIVE 42 | value: {{ .Values.application.profiles }} 43 | readinessProbe: 44 | failureThreshold: 40 45 | httpGet: 46 | path: /actuator/health 47 | port: {{ .Values.application.port }} 48 | scheme: HTTP 49 | initialDelaySeconds: 10 50 | periodSeconds: 15 51 | successThreshold: 1 52 | timeoutSeconds: 400 53 | livenessProbe: 54 | failureThreshold: 10 55 | initialDelaySeconds: 150 56 | periodSeconds: 30 57 | successThreshold: 1 58 | tcpSocket: 59 | port: {{ .Values.application.port }} 60 | timeoutSeconds: 400 61 | 62 | triggers: 63 | - imageChangeParams: 64 | automatic: yes 65 | containerNames: 66 | - {{ .Values.name }} 67 | from: 68 | kind: ImageStreamTag 69 | name: '{{ .Values.name }}:latest' 70 | type: ImageChange 71 | 72 | strategy: 73 | type: Rolling 74 | 75 | -------------------------------------------------------------------------------- /helm/delivery_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/delivery_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/delivery_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/delivery_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/delivery_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: delivery 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: delivery 13 | replicas: 1 14 | uri: delivery-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8084 18 | application: 19 | port: 8084 20 | profiles: prod 21 | pdb: 22 | enabled: false 23 | minAvailable: 1 24 | config: 25 | url: http://config/ 26 | eureka: 27 | url: http://server/eureka -------------------------------------------------------------------------------- /helm/gateway_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/gateway_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Configserver 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/gateway_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/gateway_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8085" 37 | - name: SPRING_CLOUD_CONFIG_URI 38 | value: {{ .Values.config.url }} 39 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 40 | value: {{ .Values.eureka.url }} 41 | - name: SPRING_PROFILES_ACTIVE 42 | value: {{ .Values.application.profiles }} 43 | - name: ZUUL_PREFIX 44 | value: {{ .Values.eureka.api }} 45 | readinessProbe: 46 | failureThreshold: 40 47 | httpGet: 48 | path: /actuator/health 49 | port: {{ .Values.application.port }} 50 | scheme: HTTP 51 | initialDelaySeconds: 10 52 | periodSeconds: 15 53 | successThreshold: 1 54 | timeoutSeconds: 400 55 | livenessProbe: 56 | failureThreshold: 10 57 | initialDelaySeconds: 150 58 | periodSeconds: 30 59 | successThreshold: 1 60 | tcpSocket: 61 | port: {{ .Values.application.port }} 62 | timeoutSeconds: 400 63 | 64 | triggers: 65 | - imageChangeParams: 66 | automatic: yes 67 | containerNames: 68 | - {{ .Values.name }} 69 | from: 70 | kind: ImageStreamTag 71 | name: '{{ .Values.name }}:latest' 72 | type: ImageChange 73 | 74 | strategy: 75 | type: Rolling 76 | 77 | -------------------------------------------------------------------------------- /helm/gateway_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/gateway_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/gateway_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/gateway_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/gateway_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: gateway 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: gateway 13 | replicas: 1 14 | uri: gateway-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8008 18 | application: 19 | port: 8008 20 | profiles: prod 21 | pdb: 22 | enabled: false 23 | minAvailable: 1 24 | config: 25 | url: http://config/ 26 | eureka: 27 | url: http://server/eureka 28 | api: /api -------------------------------------------------------------------------------- /helm/notification_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/notification_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Configserver 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/notification_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/notification_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8085" 37 | - name: SPRING_CLOUD_CONFIG_URI 38 | value: {{ .Values.config.url }} 39 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 40 | value: {{ .Values.eureka.url }} 41 | - name: SPRING_PROFILES_ACTIVE 42 | value: {{ .Values.application.profiles }} 43 | readinessProbe: 44 | failureThreshold: 40 45 | httpGet: 46 | path: /actuator/health 47 | port: {{ .Values.application.port }} 48 | scheme: HTTP 49 | initialDelaySeconds: 10 50 | periodSeconds: 15 51 | successThreshold: 1 52 | timeoutSeconds: 400 53 | livenessProbe: 54 | failureThreshold: 10 55 | initialDelaySeconds: 150 56 | periodSeconds: 30 57 | successThreshold: 1 58 | tcpSocket: 59 | port: {{ .Values.application.port }} 60 | timeoutSeconds: 400 61 | 62 | triggers: 63 | - imageChangeParams: 64 | automatic: yes 65 | containerNames: 66 | - {{ .Values.name }} 67 | from: 68 | kind: ImageStreamTag 69 | name: '{{ .Values.name }}:latest' 70 | type: ImageChange 71 | 72 | strategy: 73 | type: Rolling 74 | 75 | -------------------------------------------------------------------------------- /helm/notification_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/notification_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/notification_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/notification_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/notification_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: notification 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: notification 13 | replicas: 1 14 | uri: notification-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8085 18 | application: 19 | port: 8085 20 | profiles: prod 21 | pdb: 22 | enabled: false 23 | minAvailable: 1 24 | config: 25 | url: http://config/ 26 | eureka: 27 | url: http://server/eureka -------------------------------------------------------------------------------- /helm/order_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/order_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Configserver 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/order_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/order_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8083" 37 | - name: SPRING_CLOUD_CONFIG_URI 38 | value: {{ .Values.config.url }} 39 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 40 | value: {{ .Values.eureka.url }} 41 | - name: SPRING_PROFILES_ACTIVE 42 | value: {{ .Values.application.profiles }} 43 | readinessProbe: 44 | failureThreshold: 40 45 | httpGet: 46 | path: /actuator/health 47 | port: {{ .Values.application.port }} 48 | scheme: HTTP 49 | initialDelaySeconds: 10 50 | periodSeconds: 15 51 | successThreshold: 1 52 | timeoutSeconds: 400 53 | livenessProbe: 54 | failureThreshold: 10 55 | initialDelaySeconds: 150 56 | periodSeconds: 30 57 | successThreshold: 1 58 | tcpSocket: 59 | port: {{ .Values.application.port }} 60 | timeoutSeconds: 400 61 | 62 | triggers: 63 | - imageChangeParams: 64 | automatic: yes 65 | containerNames: 66 | - {{ .Values.name }} 67 | from: 68 | kind: ImageStreamTag 69 | name: '{{ .Values.name }}:latest' 70 | type: ImageChange 71 | 72 | strategy: 73 | type: Rolling 74 | 75 | -------------------------------------------------------------------------------- /helm/order_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/order_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/order_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/order_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/order_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: order 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: order 13 | replicas: 1 14 | uri: order-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8083 18 | application: 19 | port: 8083 20 | profiles: prod 21 | pdb: 22 | enabled: false 23 | minAvailable: 1 24 | config: 25 | url: http://config/ 26 | eureka: 27 | url: http://server/eureka -------------------------------------------------------------------------------- /helm/postgres_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/postgres_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices-tools 3 | description: A Helm chart for Eureka server 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: latest 24 | -------------------------------------------------------------------------------- /helm/postgres_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/postgres_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | ports: 25 | - containerPort: {{ .Values.application.port }} 26 | protocol: TCP 27 | env: 28 | - name: POSTGRESQL_PASSWORD 29 | value: {{ .Values.postgres.password }} 30 | - name: POSTGRESQL_USERNAME 31 | value: {{ .Values.postgres.username }} 32 | - name: POSTGRESQL_DATABASE 33 | value: {{ .Values.postgres.db }} 34 | 35 | triggers: 36 | - imageChangeParams: 37 | automatic: yes 38 | containerNames: 39 | - {{ .Values.name }} 40 | from: 41 | kind: ImageStreamTag 42 | name: '{{ .Values.name }}:latest' 43 | type: ImageChange 44 | 45 | strategy: 46 | type: Rolling 47 | 48 | -------------------------------------------------------------------------------- /helm/postgres_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/postgres_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/postgres_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/postgres_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/postgres_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: postgres 2 | docker: 3 | repository: elvaliev 4 | image: postgres 5 | replicas: 1 6 | uri: postgres-sol-portfolio-dev03.telitcaas1.t-internal.com 7 | servers: 8 | serviceType: ClusterIP # [ClusterIP|LoadBalancer] 9 | portName: 5432 10 | application: 11 | port: 5432 12 | pdb: 13 | enabled: false 14 | minAvailable: 1 15 | postgres: 16 | db: eventuate 17 | username: eventuate 18 | password: eventuate -------------------------------------------------------------------------------- /helm/server_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/server_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Eureka server 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/server_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/server_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8761" 37 | readinessProbe: 38 | failureThreshold: 40 39 | httpGet: 40 | path: /actuator/health 41 | port: {{ .Values.application.port }} 42 | scheme: HTTP 43 | initialDelaySeconds: 10 44 | periodSeconds: 15 45 | successThreshold: 1 46 | timeoutSeconds: 400 47 | livenessProbe: 48 | failureThreshold: 10 49 | initialDelaySeconds: 150 50 | periodSeconds: 30 51 | successThreshold: 1 52 | tcpSocket: 53 | port: {{ .Values.application.port }} 54 | timeoutSeconds: 400 55 | 56 | triggers: 57 | - imageChangeParams: 58 | automatic: yes 59 | containerNames: 60 | - {{ .Values.name }} 61 | from: 62 | kind: ImageStreamTag 63 | name: '{{ .Values.name }}:latest' 64 | type: ImageChange 65 | 66 | strategy: 67 | type: Rolling 68 | 69 | -------------------------------------------------------------------------------- /helm/server_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/server_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/server_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/server_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/server_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: server 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: server 13 | replicas: 1 14 | uri: eureka-server-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8761 18 | application: 19 | port: 8761 20 | pdb: 21 | enabled: false 22 | minAvailable: 1 -------------------------------------------------------------------------------- /helm/store_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/store_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices 3 | description: A Helm chart for Configserver 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/store_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/store_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | resources: 25 | requests: 26 | cpu: {{ .Values.resources.server.requests.cpu }} 27 | memory: {{ .Values.resources.server.requests.memory }} 28 | limits: 29 | cpu: {{ .Values.resources.server.limits.cpu }} 30 | memory: {{ .Values.resources.server.limits.memory }} 31 | ports: 32 | - containerPort: {{ .Values.application.port }} 33 | name: http 34 | env: 35 | - name: SERVER_PORT 36 | value: "8082" 37 | - name: SPRING_CLOUD_CONFIG_URI 38 | value: {{ .Values.config.url }} 39 | - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE 40 | value: {{ .Values.eureka.url }} 41 | - name: SPRING_PROFILES_ACTIVE 42 | value: {{ .Values.application.profiles }} 43 | readinessProbe: 44 | failureThreshold: 40 45 | httpGet: 46 | path: /actuator/health 47 | port: {{ .Values.application.port }} 48 | scheme: HTTP 49 | initialDelaySeconds: 10 50 | periodSeconds: 15 51 | successThreshold: 1 52 | timeoutSeconds: 400 53 | livenessProbe: 54 | failureThreshold: 10 55 | initialDelaySeconds: 150 56 | periodSeconds: 30 57 | successThreshold: 1 58 | tcpSocket: 59 | port: {{ .Values.application.port }} 60 | timeoutSeconds: 400 61 | 62 | triggers: 63 | - imageChangeParams: 64 | automatic: yes 65 | containerNames: 66 | - {{ .Values.name }} 67 | from: 68 | kind: ImageStreamTag 69 | name: '{{ .Values.name }}:latest' 70 | type: ImageChange 71 | 72 | strategy: 73 | type: Rolling 74 | 75 | -------------------------------------------------------------------------------- /helm/store_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Chart.AppVersion }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/store_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/store_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/store_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: 80 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/store_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: store 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: elvaliev 12 | image: store 13 | replicas: 1 14 | uri: store-sol-portfolio-dev03.telitcaas1.t-internal.com 15 | servers: 16 | serviceType: LoadBalancer # [ClusterIP|LoadBalancer] 17 | portName: 8082 18 | application: 19 | port: 8082 20 | profiles: prod 21 | pdb: 22 | enabled: false 23 | minAvailable: 1 24 | config: 25 | url: http://config/ 26 | eureka: 27 | url: http://server/eureka -------------------------------------------------------------------------------- /helm/zookeeper_chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/zookeeper_chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-microservices-tools 3 | description: A Helm chart for Eureka server 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.0.0 24 | -------------------------------------------------------------------------------- /helm/zookeeper_chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Create a default fully qualified app name. 5 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 6 | */}} 7 | {{- define "service-catalog-management.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 9 | {{- end -}} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | */}} 15 | {{- define "service-catalog-management.fullname" -}} 16 | {{- $name := default .Chart.Name .Values.nameOverride -}} 17 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 18 | {{- end -}} 19 | 20 | 21 | {{- /* 22 | Credit: @technosophos 23 | https://github.com/technosophos/common-chart/ 24 | labels.standard prints the standard Helm labels. 25 | The standard labels are frequently used in metadata. 26 | */ -}} 27 | {{- define "labels.standard" -}} 28 | app: {{ template "service-catalog-management.name" . }} 29 | heritage: {{ .Release.Service | quote }} 30 | release: {{ .Release.Name | quote }} 31 | chart: {{ template "chartref" . }} 32 | {{- end -}} 33 | 34 | {{- /* 35 | Credit: @technosophos 36 | https://github.com/technosophos/common-chart/ 37 | chartref prints a chart name and version. 38 | It does minimal escaping for use in Kubernetes labels. 39 | Example output: 40 | zookeeper-1.2.3 41 | wordpress-3.2.1_20170219 42 | */ -}} 43 | {{- define "chartref" -}} 44 | {{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} 45 | {{- end -}} 46 | 47 | 48 | {{/* 49 | Create the name of the service account to use 50 | */}} 51 | {{- define "service-catalog-management.serviceAccountName" -}} 52 | {{- if .Values.serviceAccount.create -}} 53 | {{ default (include "service-catalog-management.fullname" .) .Values.serviceAccount.name }} 54 | {{- else -}} 55 | {{ default "default" .Values.serviceAccount.name }} 56 | {{- end -}} 57 | {{- end -}} 58 | 59 | -------------------------------------------------------------------------------- /helm/zookeeper_chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.openshift.io/v1 2 | kind: DeploymentConfig 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | scheduled: "yes" 7 | name: {{ .Values.name }} 8 | {{ include "labels.standard" . | indent 4 }} 9 | spec: 10 | replicas: 1 11 | template: 12 | metadata: 13 | annotations: 14 | prometheus.io/path: /actuator/prometheus 15 | prometheus.io/scrape: 'true' 16 | creationTimestamp: null 17 | labels: 18 | app: {{ .Values.name }} 19 | release: {{ .Release.Name }} 20 | name: {{ .Values.name }} 21 | spec: 22 | containers: 23 | - name: {{ .Values.name }} 24 | ports: 25 | - containerPort: 2181 26 | protocol: TCP 27 | - containerPort: 2888 28 | protocol: TCP 29 | - containerPort: 3888 30 | protocol: TCP 31 | env: 32 | - name: ZOOKEEPER_CLIENT_PORT 33 | value: "2181" 34 | - name: KAFKA_HEAP_OPTS 35 | value: {{ .Values.zookeeper.heap_ops }} 36 | 37 | triggers: 38 | - imageChangeParams: 39 | automatic: yes 40 | containerNames: 41 | - {{ .Values.name }} 42 | from: 43 | kind: ImageStreamTag 44 | name: '{{ .Values.name }}:latest' 45 | type: ImageChange 46 | 47 | strategy: 48 | type: Rolling 49 | 50 | -------------------------------------------------------------------------------- /helm/zookeeper_chart/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | annotations: 5 | 6 | labels: 7 | app: {{ .Values.name }} 8 | name: {{ .Values.name }} 9 | spec: 10 | lookupPolicy: 11 | local: false 12 | tags: 13 | - annotations: null 14 | from: 15 | kind: DockerImage 16 | name: {{ .Values.docker.repository }}/{{ .Values.docker.image }}:{{ .Values.docker.tag }} 17 | importPolicy: {} 18 | name: latest 19 | referencePolicy: 20 | type: Source 21 | -------------------------------------------------------------------------------- /helm/zookeeper_chart/templates/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if (.Values.pdb) -}} 2 | {{- if (eq .Values.pdb.enabled true) -}} 3 | apiVersion: policy/v1beta1 4 | kind: PodDisruptionBudget 5 | metadata: 6 | name: {{ .Values.name }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: {{ .Values.name }} 11 | minAvailable: {{ .Values.pdb.minAvailable }} 12 | {{- end }} 13 | {{- end }} -------------------------------------------------------------------------------- /helm/zookeeper_chart/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: {{ .Values.name }} 6 | name: {{ .Values.name }} 7 | spec: 8 | host: {{ .Values.uri }} 9 | port: 10 | targetPort: {{ .Values.portName }} 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: {{ .Values.name }} 17 | -------------------------------------------------------------------------------- /helm/zookeeper_chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.name }} 5 | labels: 6 | {{ include "labels.standard" . | indent 4 }} 7 | app: {{ .Values.name }} 8 | annotations: 9 | {{ toYaml .Values.servers.annotations | indent 4 }} 10 | spec: 11 | ports: 12 | - port: {{ .Values.application.port }} 13 | name: http 14 | protocol: TCP 15 | targetPort: {{ .Values.application.port }} 16 | type: {{ .Values.servers.serviceType }} 17 | selector: 18 | app: {{ .Values.name }} 19 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /helm/zookeeper_chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: zookeeper 2 | resources: 3 | server: 4 | requests: 5 | memory: 300Mi 6 | cpu: 10m 7 | limits: 8 | memory: 4000Mi 9 | cpu: 1 10 | docker: 11 | repository: confluentinc 12 | image: cp-zookeeper 13 | tag: 5.2.4 14 | replicas: 1 15 | uri: zk-sol-portfolio-dev03.telitcaas1.t-internal.com 16 | servers: 17 | serviceType: ClusterIP # [ClusterIP|LoadBalancer] 18 | portName: 2181 19 | application: 20 | port: 2181 21 | pdb: 22 | enabled: false 23 | minAvailable: 1 24 | zookeeper: 25 | port: "2181" 26 | heap_ops: -Xmx64m -------------------------------------------------------------------------------- /notification/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /notification/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/notification/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /notification/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /notification/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "notification" 2 | -------------------------------------------------------------------------------- /notification/src/main/kotlin/com/example/notification/NotificationApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.notification 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 6 | import org.springframework.cloud.context.config.annotation.RefreshScope 7 | 8 | @RefreshScope 9 | @SpringBootApplication 10 | @EnableDiscoveryClient 11 | class NotificationApplication 12 | 13 | fun main(args: Array) { 14 | runApplication(*args) 15 | } 16 | -------------------------------------------------------------------------------- /notification/src/main/resources/bootstrap.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | serviceUrl: 4 | defaultZone: http://localhost:8761/eureka 5 | spring: 6 | application: 7 | name: notification 8 | cloud: 9 | config: 10 | uri: http://localhost:8088 -------------------------------------------------------------------------------- /order/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /order/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/order/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /order/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /order/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "order" 2 | -------------------------------------------------------------------------------- /order/src/main/kotlin/com/example/order/OrderApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.order 2 | 3 | import io.eventuate.tram.sagas.spring.orchestration.SagaOrchestratorConfiguration 4 | import io.eventuate.tram.spring.consumer.kafka.EventuateTramKafkaMessageConsumerConfiguration 5 | import io.eventuate.tram.spring.messaging.producer.jdbc.TramMessageProducerJdbcConfiguration 6 | import io.eventuate.tram.spring.optimisticlocking.OptimisticLockingDecoratorConfiguration 7 | import org.springframework.boot.autoconfigure.SpringBootApplication 8 | import org.springframework.boot.runApplication 9 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 10 | import org.springframework.cloud.context.config.annotation.RefreshScope 11 | import org.springframework.context.annotation.Import 12 | 13 | @SpringBootApplication 14 | @EnableDiscoveryClient 15 | @Import( 16 | SagaOrchestratorConfiguration::class, 17 | OptimisticLockingDecoratorConfiguration::class, 18 | EventuateTramKafkaMessageConsumerConfiguration::class, 19 | TramMessageProducerJdbcConfiguration::class 20 | ) 21 | @RefreshScope 22 | class OrderApplication 23 | 24 | fun main(args: Array) { 25 | runApplication(*args) 26 | } 27 | -------------------------------------------------------------------------------- /order/src/main/kotlin/com/example/order/OrderController.kt: -------------------------------------------------------------------------------- 1 | package com.example.order 2 | 3 | import com.example.common.BaseSwaggerConfiguration 4 | import com.example.order.repository.OrderDetails 5 | import com.example.order.service.OrderService 6 | import io.swagger.annotations.Api 7 | import io.swagger.annotations.ApiOperation 8 | import org.springframework.context.annotation.Configuration 9 | import org.springframework.web.bind.annotation.* 10 | import springfox.documentation.swagger2.annotations.EnableSwagger2 11 | 12 | @Configuration 13 | @EnableSwagger2 14 | class SwaggerDocumentation( 15 | basePackage: String = "com.example.order", 16 | service: String = "Order" 17 | ) : BaseSwaggerConfiguration(basePackage, service) 18 | 19 | @RestController 20 | @RequestMapping("/order") 21 | @Api(value = "API for Account service") 22 | class OrderController(private val orderService: OrderService) { 23 | 24 | @PostMapping 25 | @ApiOperation(value = "Create order") 26 | fun order(@RequestBody order: OrderDetails) = orderService.createOrder(order) 27 | 28 | @GetMapping("/{id}") 29 | @ApiOperation(value = "Get order by id") 30 | fun getInfo(@PathVariable("id") orderId: Long) = orderService.getOrderInfo(orderId) 31 | } -------------------------------------------------------------------------------- /order/src/main/kotlin/com/example/order/exception/OrderException.kt: -------------------------------------------------------------------------------- 1 | package com.example.order.exception 2 | 3 | import org.springframework.http.ResponseEntity 4 | import org.springframework.web.bind.annotation.ControllerAdvice 5 | import org.springframework.web.bind.annotation.ExceptionHandler 6 | 7 | class OrderException(override val message: String) : RuntimeException(message) 8 | 9 | @ControllerAdvice 10 | class OrderExceptionHandler { 11 | 12 | @ExceptionHandler(OrderException::class) 13 | fun handleMonitoringException(ex: OrderException): ResponseEntity { 14 | return ResponseEntity.badRequest().body(ex.message) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /order/src/main/kotlin/com/example/order/repository/OrderRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.order.repository 2 | 3 | 4 | import com.example.order.saga.RejectedReason 5 | import org.springframework.data.repository.CrudRepository 6 | import javax.persistence.* 7 | 8 | interface OrderRepository : CrudRepository 9 | 10 | data class OrderDetails( 11 | var user: String, 12 | var city: String, 13 | var product: String 14 | ) 15 | 16 | @Entity 17 | @Table(schema = "eventuate", name = "order") 18 | data class Order( 19 | @Id @GeneratedValue(strategy = GenerationType.AUTO) var id: Long = 0, 20 | @Column(name = "user_id") var user: String? = null, 21 | var product: String? = null, 22 | var status: Status = Status.Created, 23 | var track: String? = null, 24 | @Column(name = "rejection_reason") var rejectionReason: RejectedReason? = null 25 | ) { 26 | 27 | fun reject(rejectionReason: RejectedReason) { 28 | this.rejectionReason = rejectionReason 29 | status = Status.Rejected 30 | } 31 | 32 | fun approve() { 33 | status = Status.Approved 34 | } 35 | 36 | fun reserved() { 37 | status = Status.Reserved 38 | } 39 | } 40 | 41 | enum class Status { 42 | Created, Reserved, Approved, Rejected 43 | } -------------------------------------------------------------------------------- /order/src/main/kotlin/com/example/order/service/OrderService.kt: -------------------------------------------------------------------------------- 1 | package com.example.order.service 2 | 3 | import com.example.order.repository.Order 4 | import com.example.order.repository.OrderDetails 5 | import com.example.order.repository.OrderRepository 6 | import com.example.order.saga.CreateOrderSaga 7 | import com.example.order.saga.CreateOrderSagaData 8 | import io.eventuate.tram.sagas.orchestration.SagaInstanceFactory 9 | import org.springframework.stereotype.Service 10 | import org.springframework.transaction.annotation.Transactional 11 | 12 | @Service 13 | class OrderService( 14 | private var orderRepository: OrderRepository, 15 | private val createOrderSaga: CreateOrderSaga, 16 | private val sagaInstanceFactory: SagaInstanceFactory 17 | ) { 18 | 19 | @Transactional 20 | fun createOrder(order: OrderDetails): Order? { 21 | val createOrderSagaData = CreateOrderSagaData(city = order.city, product = order.product, user = order.user) 22 | sagaInstanceFactory.create(createOrderSaga, createOrderSagaData) 23 | return createOrderSagaData.id?.let { orderRepository.findById(it).get() } 24 | } 25 | 26 | fun getOrderInfo(orderId: Long) = orderRepository.findById(orderId) 27 | } 28 | -------------------------------------------------------------------------------- /order/src/main/resources/bootstrap.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | serviceUrl: 4 | defaultZone: http://localhost:8761/eureka 5 | spring: 6 | application: 7 | name: order 8 | cloud: 9 | config: 10 | uri: http://localhost:8088 -------------------------------------------------------------------------------- /order/src/test/kotlin/com/example/order/service/OrderServiceTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.order.service 2 | 3 | import com.example.order.repository.Order 4 | import com.example.order.repository.OrderDetails 5 | import com.example.order.repository.OrderRepository 6 | import com.example.order.saga.CreateOrderSaga 7 | import io.eventuate.tram.sagas.orchestration.SagaInstanceFactory 8 | import org.junit.jupiter.api.Assertions 9 | import org.junit.jupiter.api.Test 10 | import org.junit.jupiter.api.extension.ExtendWith 11 | import org.mockito.Mockito 12 | import org.springframework.beans.factory.annotation.Autowired 13 | import org.springframework.boot.test.context.TestConfiguration 14 | import org.springframework.boot.test.mock.mockito.MockBean 15 | import org.springframework.boot.test.mock.mockito.MockBeans 16 | import org.springframework.context.annotation.Bean 17 | import org.springframework.test.context.junit.jupiter.SpringExtension 18 | import java.util.* 19 | 20 | @MockBeans( 21 | MockBean(CreateOrderSaga::class), 22 | MockBean(SagaInstanceFactory::class) 23 | ) 24 | @ExtendWith(SpringExtension::class) 25 | internal class OrderServiceTest { 26 | 27 | @TestConfiguration 28 | class OrderServiceTestConfiguration { 29 | 30 | @Bean 31 | fun orderService( 32 | orderRepository: OrderRepository, 33 | orderSaga: CreateOrderSaga, 34 | sagaInstanceFactory: SagaInstanceFactory 35 | ) = OrderService(orderRepository, orderSaga, sagaInstanceFactory) 36 | } 37 | 38 | @Autowired 39 | private lateinit var orderService: OrderService 40 | 41 | @MockBean 42 | private lateinit var orderRepository: OrderRepository 43 | 44 | @Test 45 | fun createOrder() { 46 | val orderDetails = OrderDetails(user = "1", city = "Moscow", product = "1") 47 | val order = Order(id = 1, user = orderDetails.user, product = orderDetails.product) 48 | Mockito.`when`(orderRepository.save(Order(user = orderDetails.user, product = orderDetails.product))) 49 | .thenReturn(order) 50 | Mockito.`when`(orderRepository.findById(1)).thenReturn(Optional.of(order)) 51 | Assertions.assertNull(orderService.createOrder(orderDetails)) 52 | } 53 | 54 | @Test 55 | fun getOrderInfo() { 56 | val order = Optional.of(Order()) 57 | Mockito.`when`(orderRepository.findById(1)).thenReturn(order) 58 | Assertions.assertEquals(order, orderService.getOrderInfo(1)) 59 | } 60 | } -------------------------------------------------------------------------------- /schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/schema.png -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /server/build.gradle.kts: -------------------------------------------------------------------------------- 1 | java.sourceCompatibility = JavaVersion.VERSION_11 2 | val buildNumber by extra("0") 3 | 4 | extra["springCloudVersion"] = "Hoxton.SR6" 5 | extra["springBootAdminVersion"] = "2.2.4" 6 | 7 | dependencies { 8 | implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-server") 9 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 10 | exclude(group = "org.junit.vintage", module = "junit-vintage-engine") 11 | } 12 | } 13 | 14 | dependencyManagement { 15 | imports { 16 | mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}") 17 | mavenBom("de.codecentric:spring-boot-admin-dependencies:${property("springBootAdminVersion")}") 18 | } 19 | } 20 | 21 | jib { 22 | to { 23 | image = "elvaliev/server" 24 | tags = setOf("$version", "$version.${extra["buildNumber"]}") 25 | auth { 26 | username = System.getenv("DOCKERHUB_USERNAME") 27 | password = System.getenv("DOCKERHUB_PASSWORD") 28 | } 29 | } 30 | container { 31 | labels = mapOf( 32 | "maintainer" to "Elina Valieva ", 33 | "org.opencontainers.image.title" to "server", 34 | "org.opencontainers.image.description" to "Spring microservices", 35 | "org.opencontainers.image.version" to "$version", 36 | "org.opencontainers.image.authors" to "Elina Valieva >", 37 | "org.opencontainers.image.url" to "https://github.com/ElinaValieva/spring-microservices" 38 | ) 39 | jvmFlags = listOf( 40 | "-server", 41 | "-Djava.awt.headless=true", 42 | "-XX:InitialRAMFraction=2", 43 | "-XX:MinRAMFraction=2", 44 | "-XX:MaxRAMFraction=2", 45 | "-XX:+UseG1GC", 46 | "-XX:MaxGCPauseMillis=100", 47 | "-XX:+UseStringDeduplication" 48 | ) 49 | workingDirectory = "/server" 50 | ports = listOf("8761") 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /server/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/server/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /server/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /server/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "server" 2 | -------------------------------------------------------------------------------- /server/src/main/kotlin/com/example/server/ServerApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.server 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | class ServerApplication 10 | 11 | fun main(args: Array) { 12 | runApplication(*args) 13 | } 14 | -------------------------------------------------------------------------------- /server/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8761 3 | eureka: 4 | client: 5 | registerWithEureka: false 6 | fetchRegistry: false 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" -------------------------------------------------------------------------------- /server/src/test/kotlin/com/example/server/ServerApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.example.server 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class ServerApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "spring-microservices" 2 | include("common") 3 | include("admin") 4 | include("config") 5 | include("delivery") 6 | include("gateway") 7 | include("notification") 8 | include("account") 9 | include("store") 10 | include("order") 11 | include("server") -------------------------------------------------------------------------------- /store/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /store/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElinaValieva/spring-microservices/e07351441c1074eb5c35d19bfecbe7d2a18d62ff/store/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /store/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /store/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "store" 2 | -------------------------------------------------------------------------------- /store/src/main/kotlin/com/example/store/StoreApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.store 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient 6 | import org.springframework.cloud.context.config.annotation.RefreshScope 7 | 8 | @SpringBootApplication 9 | @EnableDiscoveryClient 10 | @RefreshScope 11 | class StoreApplication 12 | 13 | fun main(args: Array) { 14 | runApplication(*args) 15 | } -------------------------------------------------------------------------------- /store/src/main/kotlin/com/example/store/StoreController.kt: -------------------------------------------------------------------------------- 1 | package com.example.store 2 | 3 | import com.example.common.BaseSwaggerConfiguration 4 | import com.example.store.service.StoreService 5 | import io.swagger.annotations.Api 6 | import io.swagger.annotations.ApiOperation 7 | import org.springframework.context.annotation.Configuration 8 | import org.springframework.web.bind.annotation.GetMapping 9 | import org.springframework.web.bind.annotation.PathVariable 10 | import org.springframework.web.bind.annotation.RestController 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2 12 | 13 | @Configuration 14 | @EnableSwagger2 15 | class SwaggerDocumentation( 16 | basePackage: String = "com.example.store", 17 | service: String = "Store" 18 | ) : BaseSwaggerConfiguration(basePackage, service) 19 | 20 | @RestController 21 | @Api(value = "API for Account service") 22 | class StoreController(private val storeService: StoreService) { 23 | 24 | @GetMapping("/presents") 25 | @ApiOperation(value = "All available products") 26 | fun getAllProducts() = storeService.getPresents() 27 | 28 | @GetMapping("/{id}") 29 | @ApiOperation(value = "Getting product by id") 30 | fun getProductById(@PathVariable("id") id: Long) = storeService.getById(id) 31 | } -------------------------------------------------------------------------------- /store/src/main/kotlin/com/example/store/exception/StoreException.kt: -------------------------------------------------------------------------------- 1 | package com.example.store.exception 2 | 3 | import org.springframework.http.ResponseEntity 4 | import org.springframework.web.bind.annotation.ControllerAdvice 5 | import org.springframework.web.bind.annotation.ExceptionHandler 6 | 7 | class StoreException(override val message: String) : RuntimeException(message) 8 | 9 | @ControllerAdvice 10 | class StoreExceptionHandler { 11 | 12 | @ExceptionHandler(StoreException::class) 13 | fun handleMonitoringException(ex: StoreException): ResponseEntity { 14 | return ResponseEntity.badRequest().body(ex.message) 15 | } 16 | } -------------------------------------------------------------------------------- /store/src/main/kotlin/com/example/store/repository/StoreRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.store.repository 2 | 3 | import org.springframework.data.repository.CrudRepository 4 | import javax.persistence.* 5 | 6 | @Entity 7 | @Table(name = "product", schema = "eventuate") 8 | data class Product( 9 | @Id @GeneratedValue(strategy = GenerationType.AUTO) var id: Long? = null, 10 | var description: String? = null, 11 | var name: String = "", 12 | var image: String? = null, 13 | var count: Int = 0 14 | ) 15 | 16 | interface StoreRepository : CrudRepository 17 | -------------------------------------------------------------------------------- /store/src/main/kotlin/com/example/store/service/StoreService.kt: -------------------------------------------------------------------------------- 1 | package com.example.store.service 2 | 3 | import com.example.store.exception.StoreException 4 | import com.example.store.repository.Product 5 | import com.example.store.repository.StoreRepository 6 | import org.apache.commons.logging.LogFactory 7 | import java.util.* 8 | 9 | interface StoreService { 10 | 11 | fun getPresents(): MutableIterable 12 | 13 | fun receive(productId: String) 14 | 15 | fun getById(id: Long): Optional 16 | } 17 | 18 | class StoreServiceImpl(private val storeRepository: StoreRepository) : StoreService { 19 | 20 | private val log = LogFactory.getLog(StoreService::class.java) 21 | 22 | override fun getPresents(): MutableIterable = storeRepository.findAll() 23 | 24 | override fun receive(productId: String) { 25 | log.info("Receive product: $productId for reserving") 26 | 27 | val foundedProduct = storeRepository.findById(productId.toLong()) 28 | 29 | if (foundedProduct.isEmpty) 30 | throw StoreException("Product not found") 31 | 32 | removeProduct(foundedProduct.get()) 33 | } 34 | 35 | private fun removeProduct(product: Product) { 36 | if (product.count == 1) 37 | storeRepository.delete(product) 38 | else { 39 | product.count -= 1 40 | storeRepository.save(product) 41 | } 42 | } 43 | 44 | override fun getById(id: Long): Optional = storeRepository.findById(id) 45 | } 46 | -------------------------------------------------------------------------------- /store/src/main/resources/bootstrap.yaml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | serviceUrl: 4 | defaultZone: http://localhost:8761/eureka 5 | spring: 6 | application: 7 | name: store 8 | cloud: 9 | config: 10 | uri: http://localhost:8088 -------------------------------------------------------------------------------- /store/src/test/kotlin/com/example/store/service/StoreServiceTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.store.service 2 | 3 | import com.example.store.repository.Product 4 | import com.example.store.repository.StoreRepository 5 | import org.bouncycastle.util.StoreException 6 | import org.junit.jupiter.api.Assertions 7 | import org.junit.jupiter.api.Test 8 | import org.junit.jupiter.api.extension.ExtendWith 9 | import org.mockito.Mockito 10 | import org.springframework.beans.factory.annotation.Autowired 11 | import org.springframework.boot.test.context.TestConfiguration 12 | import org.springframework.boot.test.mock.mockito.MockBean 13 | import org.springframework.context.annotation.Bean 14 | import org.springframework.test.context.junit.jupiter.SpringExtension 15 | import java.util.* 16 | 17 | @ExtendWith(SpringExtension::class) 18 | internal class StoreServiceTest { 19 | 20 | @TestConfiguration 21 | class AccountServiceTestConfiguration { 22 | 23 | @Bean 24 | fun storeService(storeRepository: StoreRepository) = StoreServiceImpl(storeRepository) 25 | } 26 | 27 | @Autowired 28 | private lateinit var storeService: StoreService 29 | 30 | @MockBean 31 | private lateinit var storeRepository: StoreRepository 32 | 33 | @Test 34 | fun getPresents() { 35 | Mockito.`when`(storeRepository.findAll()).thenReturn(Collections.emptyList()) 36 | Assertions.assertTrue(storeService.getPresents().toList().isEmpty()) 37 | } 38 | 39 | @Test 40 | fun receive() { 41 | Mockito.`when`(storeRepository.findById(1)).thenThrow(StoreException::class.java) 42 | Assertions.assertThrows(StoreException::class.java) { storeService.receive("1") } 43 | } 44 | 45 | @Test 46 | fun getById() { 47 | val product = Optional.of(Product(id = 1, description = "description", name = "toy", count = 10)) 48 | Mockito.`when`(storeRepository.findById(1)).thenReturn(product) 49 | Assertions.assertEquals(product, storeService.getById(1)) 50 | } 51 | } --------------------------------------------------------------------------------