├── .gitignore ├── README.adoc ├── docker-compose.yml ├── kotlin-api-gateway ├── .gitignore ├── Dockerfile ├── pom.xml └── src │ ├── main │ ├── kotlin │ │ └── rs │ │ │ └── dodalovic │ │ │ └── gateway │ │ │ └── KotlinApiGatewayApplication.kt │ └── resources │ │ └── application.yml │ └── test │ └── kotlin │ └── rs │ └── dodalovic │ └── gateway │ └── KotlinApiGatewayApplicationTests.kt └── kotlin-user-service ├── .gitignore ├── Dockerfile ├── pom.xml └── src ├── main ├── kotlin │ └── rs │ │ └── dodalovic │ │ └── users │ │ ├── KotlinUserServiceApplication.kt │ │ ├── UsersController.kt │ │ ├── model │ │ ├── User.kt │ │ └── UserDTO.kt │ │ └── persistence │ │ └── UserRepository.kt └── resources │ └── application.yml └── test └── kotlin └── rs └── dodalovic └── users └── KotlinUserServiceApplicationTests.kt /.gitignore: -------------------------------------------------------------------------------- 1 | **/.mvn 2 | **/.idea 3 | **/mvnw 4 | **/mvnw.cmd 5 | .vscode -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Kotlin microservices 2 | :icons: font 3 | 4 | [IMPORTANT] 5 | ==== 6 | Tested with: 7 | 8 | * Maven 3.5.0 9 | * Docker version 17.03.1-ce 10 | * docker-compose version 1.11.2 11 | ==== 12 | 13 | == Running services 14 | 15 | * Package apps: 16 | + 17 | [source,bash] 18 | .execute in `kotlin-user-service` 19 | $ mvn clean package 20 | + 21 | [source,bash] 22 | .execute in `kotlin-api-gateway` 23 | $ mvn clean package 24 | 25 | * Start services 26 | + 27 | [source,bash] 28 | .execute in project root 29 | $ docker-compose up --build -d 30 | 31 | * Sample user create request 32 | + 33 | [source,bash] 34 | .execute in shell 35 | ---- 36 | http -h POST http://localhost:8080/users/ \#<1> 37 | 'Content-Type: application/json' \ 38 | email=john@doe.com name=John lastname=Doe 39 | ---- 40 | <1> http is https://httpie.org/[httpie^] command line client 41 | + 42 | [source,http] 43 | .response 44 | HTTP/1.1 201 45 | Date: Thu, 25 May 2017 10:12:17 GMT 46 | Location: http://localhost:8080/users/5926ae01410df8000740da9a 47 | Transfer-Encoding: chunked 48 | X-Application-Context: application 49 | 50 | * Sample get user request 51 | + 52 | [source,bash] 53 | .execute in shell 54 | http :8080/users/5926ae01410df8000740da9a 55 | + 56 | [source,http] 57 | .response 58 | HTTP/1.1 200 59 | Content-Type: application/json;charset=UTF-8 60 | Date: Thu, 25 May 2017 10:12:43 GMT 61 | Transfer-Encoding: chunked 62 | X-Application-Context: application 63 | { 64 | "email": "john@doe.com", 65 | "lastname": "Doe", 66 | "name": "John" 67 | } -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | services: 3 | kotlin-user-service: 4 | build: kotlin-user-service 5 | image: kotlin-user-service 6 | depends_on: 7 | - kotlin-mongo 8 | environment: 9 | JAVA_OPTS: -Dmongo.host=kotlin-mongo -agentlib:jdwp=transport=dt_socket,server=y,address=1044,suspend=n 10 | ports: 11 | - "${KOTLIN_USER_SERVICE_DEBUG_PORT:-1045}:1044" 12 | kotlin-api-gateway: 13 | build: kotlin-api-gateway 14 | image: kotlin-api-gateway 15 | depends_on: 16 | - kotlin-user-service 17 | environment: 18 | JAVA_OPTS: -Duser.service.url=kotlin-user-service:8080 -agentlib:jdwp=transport=dt_socket,server=y,address=1044,suspend=n 19 | ports: 20 | - "8080:8080" 21 | - "${KOTLIN_API_GATEWAY_DEBUG_PORT:-1044}:1044" 22 | kotlin-mongo: 23 | image: mongo 24 | ports: 25 | - "27017:27017" -------------------------------------------------------------------------------- /kotlin-api-gateway/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /kotlin-api-gateway/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM frolvlad/alpine-oraclejdk8:8.131.11-slim 2 | VOLUME /tmp 3 | COPY target/kotlin-api-gateway-0.0.1-SNAPSHOT.jar app.jar 4 | RUN sh -c 'touch /app.jar' 5 | EXPOSE 8080 6 | ENV JAVA_OPTS="" 7 | ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ] -------------------------------------------------------------------------------- /kotlin-api-gateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | rs.dodalovic.users 7 | kotlin-api-gateway 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | kotlin-api-gateway 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.3.RELEASE 18 | 19 | 20 | 21 | 22 | true 23 | UTF-8 24 | UTF-8 25 | 1.8 26 | 1.1.2 27 | Dalston.RELEASE 28 | 29 | 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-zuul 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-web 38 | 39 | 40 | org.jetbrains.kotlin 41 | kotlin-stdlib-jre8 42 | ${kotlin.version} 43 | 44 | 45 | org.jetbrains.kotlin 46 | kotlin-reflect 47 | ${kotlin.version} 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.cloud 61 | spring-cloud-dependencies 62 | ${spring-cloud.version} 63 | pom 64 | import 65 | 66 | 67 | 68 | 69 | 70 | ${project.basedir}/src/main/kotlin 71 | ${project.basedir}/src/test/kotlin 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-maven-plugin 76 | 77 | 78 | kotlin-maven-plugin 79 | org.jetbrains.kotlin 80 | ${kotlin.version} 81 | 82 | 83 | spring 84 | 85 | 1.8 86 | 87 | 88 | 89 | compile 90 | compile 91 | 92 | compile 93 | 94 | 95 | 96 | test-compile 97 | test-compile 98 | 99 | test-compile 100 | 101 | 102 | 103 | 104 | 105 | org.jetbrains.kotlin 106 | kotlin-maven-allopen 107 | ${kotlin.version} 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /kotlin-api-gateway/src/main/kotlin/rs/dodalovic/gateway/KotlinApiGatewayApplication.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.gateway 2 | 3 | import org.springframework.boot.SpringApplication 4 | import org.springframework.boot.autoconfigure.SpringBootApplication 5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy 6 | 7 | @SpringBootApplication 8 | @EnableZuulProxy 9 | class KotlinApiGatewayApplication 10 | 11 | fun main(args: Array) { 12 | SpringApplication.run(KotlinApiGatewayApplication::class.java, *args) 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-api-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | zuul: 2 | routes: 3 | users: 4 | path: /users/** 5 | url: http://${user.service.url}/users 6 | 7 | ribbon: 8 | eureka: 9 | enabled: false -------------------------------------------------------------------------------- /kotlin-api-gateway/src/test/kotlin/rs/dodalovic/gateway/KotlinApiGatewayApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.gateway 2 | 3 | import org.junit.Test 4 | import org.junit.runner.RunWith 5 | import org.springframework.boot.test.context.SpringBootTest 6 | import org.springframework.test.context.junit4.SpringRunner 7 | 8 | @RunWith(SpringRunner::class) 9 | @SpringBootTest 10 | class KotlinApiGatewayApplicationTests { 11 | 12 | @Test 13 | fun contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kotlin-user-service/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /kotlin-user-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM frolvlad/alpine-oraclejdk8:8.131.11-slim 2 | VOLUME /tmp 3 | COPY target/kotlin-user-service-0.0.1-SNAPSHOT.jar app.jar 4 | RUN sh -c 'touch /app.jar' 5 | EXPOSE 8080 6 | ENV JAVA_OPTS="" 7 | ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ] -------------------------------------------------------------------------------- /kotlin-user-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | rs.dodalovic.users 7 | kotlin-user-service 8 | 0.0.1-SNAPSHOT 9 | jar 10 | kotlin-user-service 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 1.5.3.RELEASE 15 | 16 | 17 | 18 | 19 | true 20 | UTF-8 21 | UTF-8 22 | 1.8 23 | 1.1.2 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-mongodb 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | org.jetbrains.kotlin 37 | kotlin-stdlib-jre8 38 | ${kotlin.version} 39 | 40 | 41 | org.jetbrains.kotlin 42 | kotlin-reflect 43 | ${kotlin.version} 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-test 49 | test 50 | 51 | 52 | 53 | 54 | ${project.basedir}/src/main/kotlin 55 | ${project.basedir}/src/test/kotlin 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-maven-plugin 60 | 61 | 62 | kotlin-maven-plugin 63 | org.jetbrains.kotlin 64 | ${kotlin.version} 65 | 66 | 67 | spring 68 | 69 | 1.8 70 | 71 | 72 | 73 | compile 74 | compile 75 | 76 | compile 77 | 78 | 79 | 80 | test-compile 81 | test-compile 82 | 83 | test-compile 84 | 85 | 86 | 87 | 88 | 89 | org.jetbrains.kotlin 90 | kotlin-maven-allopen 91 | ${kotlin.version} 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /kotlin-user-service/src/main/kotlin/rs/dodalovic/users/KotlinUserServiceApplication.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.users 2 | 3 | import org.springframework.boot.SpringApplication 4 | import org.springframework.boot.autoconfigure.SpringBootApplication 5 | 6 | @SpringBootApplication 7 | class KotlinUserServiceApplication 8 | 9 | fun main(args: Array) { 10 | SpringApplication.run(KotlinUserServiceApplication::class.java, *args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-user-service/src/main/kotlin/rs/dodalovic/users/UsersController.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.users 2 | 3 | import org.springframework.http.HttpStatus 4 | import org.springframework.http.ResponseEntity 5 | import org.springframework.web.bind.annotation.* 6 | import org.springframework.web.util.UriComponentsBuilder 7 | import rs.dodalovic.users.model.UserDTO 8 | import rs.dodalovic.users.model.toUser 9 | import rs.dodalovic.users.model.toUserDTO 10 | import rs.dodalovic.users.persistence.UserRepository 11 | import java.net.URI 12 | 13 | @RestController 14 | class UsersController(val userRepo: UserRepository) { 15 | 16 | @ResponseStatus(HttpStatus.OK) 17 | @GetMapping("/users/{userId}") 18 | fun getUser(@PathVariable userId: String): UserDTO { 19 | return userRepo.findOne(userId).toUserDTO() 20 | } 21 | 22 | @PostMapping("/users") 23 | fun createUser(@RequestBody userDTO: UserDTO, builder: UriComponentsBuilder): ResponseEntity { 24 | val createdUserURI = builder.path("/{userId}").buildAndExpand(userRepo.save(userDTO.toUser()).id).toUriString() 25 | return ResponseEntity.created(URI(createdUserURI)).build() 26 | } 27 | } -------------------------------------------------------------------------------- /kotlin-user-service/src/main/kotlin/rs/dodalovic/users/model/User.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.users.model 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.mongodb.core.mapping.Document 5 | 6 | @Document(collection = "users") 7 | class User(@Id val id: String? = null, 8 | val email: String = "", 9 | val name: String = "", 10 | val lastname: String = "") 11 | 12 | fun User.toUserDTO(): UserDTO = UserDTO(this.email, this.name, this.lastname) 13 | -------------------------------------------------------------------------------- /kotlin-user-service/src/main/kotlin/rs/dodalovic/users/model/UserDTO.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.users.model 2 | 3 | data class UserDTO(val email: String = "", val name: String = "", val lastname: String = "") 4 | 5 | fun UserDTO.toUser(): User { 6 | return User(email = email, name = name, lastname = lastname) 7 | } -------------------------------------------------------------------------------- /kotlin-user-service/src/main/kotlin/rs/dodalovic/users/persistence/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.users.persistence 2 | 3 | import org.springframework.data.repository.CrudRepository 4 | import rs.dodalovic.users.model.User 5 | 6 | interface UserRepository : CrudRepository -------------------------------------------------------------------------------- /kotlin-user-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | data: 3 | mongodb: 4 | host: ${mongo.host} 5 | database: users -------------------------------------------------------------------------------- /kotlin-user-service/src/test/kotlin/rs/dodalovic/users/KotlinUserServiceApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package rs.dodalovic.users 2 | 3 | import org.junit.Test 4 | import org.junit.runner.RunWith 5 | import org.springframework.boot.test.context.SpringBootTest 6 | import org.springframework.test.context.junit4.SpringRunner 7 | 8 | @RunWith(SpringRunner::class) 9 | @SpringBootTest 10 | class KotlinUserServiceApplicationTests { 11 | 12 | @Test 13 | fun contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------