Commit 5fdaf273 authored by seykron's avatar seykron

Initial project commit

parent 91e0663f
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
out
.gradle
.idea
test_db.mv.db
/db
*.iml
target
cli.log
/config
FROM openjdk:8-jre
MAINTAINER seykron <seykron@rlab.be>
RUN useradd \
--user-group \
--no-create-home \
--uid 1000 \
--shell /bin/false \
app
ARG JAR_FILE
# Add the service itself
ADD target/$JAR_FILE /usr/share/eye-of-cthulhu/eye-of-cthulhu.jar
# Drop privs
USER app
ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/share/eye-of-cthulhu/eye-of-cthulhu.jar"]
This diff is collapsed.
This diff is collapsed.
package be.rlab.eoc
import be.rlab.eoc.config.DomainBeans
import be.rlab.eoc.config.WebConfig
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.http.server.reactive.HttpHandler
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter
import org.springframework.web.reactive.DispatcherHandler
import org.springframework.web.server.WebHandler
import org.springframework.web.server.adapter.WebHttpHandlerBuilder
import reactor.ipc.netty.http.server.HttpServer
class Application(port: Int = 8080) {
private val httpHandler: HttpHandler
private val server: HttpServer
init {
val context = AnnotationConfigApplicationContext {
DomainBeans.beans().initialize(this)
register(WebConfig::class.java)
refresh()
}
val handler: WebHandler = DispatcherHandler(context)
server = HttpServer.create(port)
httpHandler = WebHttpHandlerBuilder
.webHandler(handler)
.build()
server.startAndAwait(ReactorHttpHandlerAdapter(httpHandler))
}
}
fun main(args: Array<String>) {
Application()
}
package be.rlab.eoc.application
import be.rlab.eoc.application.model.NotificationDTO
import be.rlab.eoc.domain.NotificationService
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/eoc")
class PushEventController(
private val notificationService: NotificationService
) {
@PostMapping("/notifications")
@ResponseStatus(HttpStatus.ACCEPTED)
fun pushNotification(
@RequestBody notification: NotificationDTO
) {
notificationService.push(notification.asNotification())
}
}
package be.rlab.eoc.application.model
import be.rlab.eoc.domain.model.Notification
data class NotificationDTO(
val userName: String,
val subject: String,
val eventType: String,
val additionalData: Map<String, String>
) {
fun asNotification(): Notification {
return Notification.new(
userName = userName,
subject = subject,
eventType = eventType,
additionalData = additionalData
)
}
}
package be.rlab.eoc.config
import be.rlab.antifaz.bot.memory.DatabaseMemory
import be.rlab.antifaz.domain.persistence.MemorySlots
import be.rlab.antifaz.domain.persistence.MemorySlotsDAO
import be.rlab.eoc.domain.NotificationService
import be.rlab.eoc.util.ObjectMapperFactory
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.deleteAll
import org.jetbrains.exposed.sql.transactions.transaction
import org.springframework.context.support.beans
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
object DomainBeans {
fun beans() = beans {
bean<DatabaseMemory>()
bean {
val db: Database = Database.connect(
url = System.getenv("db.connection_string"),
driver = System.getenv("db.driver")
)
transaction(db) {
SchemaUtils.create(MemorySlots)
}
MemorySlotsDAO(
db = db
)
}
bean {
MappingJackson2HttpMessageConverter(ObjectMapperFactory.snakeCaseMapper)
}
bean<NotificationService>()
}
}
\ No newline at end of file
package be.rlab.eoc.config
import be.rlab.eoc.util.ObjectMapperFactory
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.http.codec.ServerCodecConfigurer
import org.springframework.http.codec.json.Jackson2JsonDecoder
import org.springframework.http.codec.json.Jackson2JsonEncoder
import org.springframework.web.reactive.config.EnableWebFlux
import org.springframework.web.reactive.config.WebFluxConfigurer
@Configuration
@EnableWebFlux
@ComponentScan("be.rlab.eoc.application")
open class WebConfig : WebFluxConfigurer {
override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
configurer.defaultCodecs().jackson2JsonEncoder(Jackson2JsonEncoder(ObjectMapperFactory.snakeCaseMapper))
configurer.defaultCodecs().jackson2JsonDecoder(Jackson2JsonDecoder(ObjectMapperFactory.snakeCaseMapper))
}
}
package be.rlab.eoc.domain
import be.rlab.antifaz.bot.Memory
import be.rlab.eoc.domain.model.Notification
class NotificationService(
memory: Memory
) {
private var notifications: List<Notification> by memory.slot("notifications", listOf<Notification>())
fun push(notification: Notification) {
notifications = notifications + notification
}
}
package be.rlab.eoc.domain.model
import be.rlab.antifaz.domain.command.inbox.model.Flag
import org.joda.time.DateTime
data class Notification(
val userName: String,
val subject: String,
val timestamp: DateTime,
val eventType: String,
val additionalData: Map<String, String>,
val flags: List<Flag>
) {
companion object {
fun new(
userName: String,
subject: String,
eventType: String,
additionalData: Map<String, String>
): Notification = Notification(
userName = userName,
subject = subject,
timestamp = DateTime.now(),
eventType = eventType,
additionalData = additionalData,
flags = listOf(Flag.UNSEEN)
)
}
}
package be.rlab.eoc.util
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.PropertyNamingStrategy
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.datatype.joda.JodaModule
import com.fasterxml.jackson.module.kotlin.KotlinModule
object ObjectMapperFactory {
val snakeCaseMapper: ObjectMapper = defaultObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
val camelCaseMapper: ObjectMapper = defaultObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CAMEL_CASE)
private fun defaultObjectMapper(): ObjectMapper {
return configure(ObjectMapper())
}
private fun configure(objectMapper: ObjectMapper): ObjectMapper {
return objectMapper
.registerModule(JodaModule())
.registerModule(KotlinModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(SerializationFeature.INDENT_OUTPUT, true)
}
}
\ No newline at end of file
db {
url: "jdbc:h2:file:./db/default"
user: "sa"
password: ""
driver: "org.h2.Driver"
log-statements: false
}
q
classifiers: [{
category: "jobs",
resource-location: "/classifiers/jobs.txt"
}, {
category: "first_names",
resource-location: "/classifiers/first_names.txt"
}]
<configuration>
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="reactor" level="ERROR" />
<logger name="io.netty" level="INFO" />
<logger name="org.springframework" level="INFO" />
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment