Skip to content

Instantly share code, notes, and snippets.

@carolosf
Last active April 24, 2018 16:18
Show Gist options
  • Save carolosf/be90f8831e206cb6cceb7b122c72b47a to your computer and use it in GitHub Desktop.
Save carolosf/be90f8831e206cb6cceb7b122c72b47a to your computer and use it in GitHub Desktop.
Kotlin 1.2.31 ElasticSearch 6.2.3 Clean Architecture exercise
buildscript {
ext.kotlin_version = '1.2.31'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
group 'com.example'
version '1.0-SNAPSHOT'
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "org.elasticsearch.client:transport:6.2.3"
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.2"
compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+"
testImplementation(
'org.junit.jupiter:junit-jupiter-api:5.1.0'
)
testRuntimeOnly(
'org.junit.jupiter:junit-jupiter-engine:5.1.0'
)
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.elasticsearch.client.transport.TransportClient
import org.elasticsearch.common.settings.Settings
import org.elasticsearch.common.transport.TransportAddress
import org.elasticsearch.common.xcontent.XContentType
import org.elasticsearch.transport.client.PreBuiltTransportClient
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import java.net.InetAddress
class CreateMonsterUseCaseTest {
@Test
internal fun shouldCreateMonster() {
val repository = CreateMonsterRepository()
Assertions.assertEquals("Alice",
CreateMonsterUseCase(repository)
.handle(CreateMonsterUseCase.Request("1", "Alice")).name
)
}
@Test internal fun `Should save monster to repository`() {
val repository = CreateMonsterRepository()
CreateMonsterUseCase(repository)
.handle(CreateMonsterUseCase.Request("1","Fred"))
Assertions.assertEquals("Fred", repository.findById("1").name)
}
@Test internal fun `Should save monster to elastic search repository`() {
val settings = Settings.builder()
.put("cluster.name", "docker-cluster")
.put("client.transport.sniff", true)
.build()
val client: TransportClient = PreBuiltTransportClient(settings)
.addTransportAddress(TransportAddress(InetAddress.getByName("localhost"), 9300))
val repository = CreateMonsterElasticSearchRepository(client)
CreateMonsterUseCase(repository)
.handle(CreateMonsterUseCase.Request("1","Fred"))
Assertions.assertEquals("Fred", repository.findById("1").name)
}
class CreateMonsterElasticSearchRepository(private val client: TransportClient) : ICreateMonsterRepository {
override fun save(monster: Monster) {
val mapper = jacksonObjectMapper()
val json = mapper.writeValueAsString(monster)
client.prepareIndex("monster", "url-entry", monster.id).setSource(
json,
XContentType.JSON
).get()
}
override fun findById(id: String): Monster {
val mapper = jacksonObjectMapper()
val response = client.prepareGet("monster", "monster", id).get()
val monster : Monster = mapper.readValue<Monster>(response.sourceAsString, Monster::class.java)
return monster
}
}
interface ICreateMonsterRepository {
fun save(monster: Monster)
fun findById(id: String): Monster
}
class CreateMonsterRepository : ICreateMonsterRepository {
private val map : MutableMap<String, Monster> = mutableMapOf()
override fun save(monster: Monster) {
map[monster.id] = monster
}
override fun findById(id: String): Monster {
return map[id] ?: throw IllegalArgumentException("No monster found with id: $id")
}
}
@Test internal fun `Should create elasticsearch connection`() {
val settings = Settings.builder()
.put("cluster.name", "docker-cluster")
.put("client.transport.sniff", true)
.build()
val client: TransportClient = PreBuiltTransportClient(settings)
.addTransportAddress(TransportAddress(InetAddress.getByName("localhost"), 9300))
// mapper.registerModule(JavaTimeModule())
// mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
data class Monster(val name: String, val age: Int)
val monster = Monster("Bob", 25)
val mapper = jacksonObjectMapper()
val json = mapper.writeValueAsString(monster)
client.prepareIndex("monster", "url-entry", "1").setSource(
json,
XContentType.JSON
).get()
val response = client.prepareGet("monster", "monster", "1").get()
println(response)
}
class CreateMonsterUseCase(private val repository: ICreateMonsterRepository) {
fun handle(request: Request): Response {
repository.save(Monster(request.id, request.name))
return Response(request.name)
}
data class Response(val name: String)
data class Request(val id: String, val name: String)
}
data class Monster(val id: String, val name: String)
}
version: '3.5'
services:
#If elasticsearch fails to start need to run this on docker host: sudo sysctl -w vm.max_map_count=262144
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.2.3
container_name: elasticsearch
environment:
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- esdata1:/usr/share/elasticsearch/data
ports:
- 9200:9200
- 9300:9300
networks:
- esnet
# elasticsearch2:
# image: docker.elastic.co/elasticsearch/elasticsearch:6.2.3
# container_name: elasticsearch2
# environment:
# - cluster.name=docker-cluster
# - bootstrap.memory_lock=true
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# - "discovery.zen.ping.unicast.hosts=elasticsearch"
# ulimits:
# memlock:
# soft: -1
# hard: -1
# volumes:
# - esdata2:/usr/share/elasticsearch/data
# networks:
# - esnet
kibana:
image: docker.elastic.co/kibana/kibana:6.2.3
environment:
- "SERVER_NAME=kibana.example.org"
- "ELASTICSEARCH_URL=http://elasticsearch:9200"
- "xpack.security.enabled=false"
depends_on:
- elasticsearch
ports:
- 5601:5601
networks:
- esnet
volumes:
esdata1:
driver: local
esdata2:
driver: local
networks:
esnet:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment