Skip to content

Instantly share code, notes, and snippets.

View jeroenr's full-sized avatar

Jeroen Rosenberg jeroenr

View GitHub Profile
fun <T> List<T>.permutations(): List<List<T>> =
when {
size < 2 -> listOf(this)
size == 2 -> listOf(listOf(first(), last()), listOf(last(), first()))
else -> flatMap { element ->
(this - element).permutations().map { listOf(element) + it }
}
}
@jeroenr
jeroenr / ExchangeRateApiClient.kt
Created February 23, 2023 15:14
Example of a port and an adapter
// in Domain Module
data class ExchangeRateDto(val rate: BigDecimal, val currency: Currency)
interface ExchangeRateApiClientPort {
fun getRate(source: Currency, target: Currency): ExchangeRateDto
}
// in Infrastructure Module
class ExchangeRateApiClientAdapter : ExchangeRateApiClientPort {
override fun getRate(source: Currency, target: Currency): ExchangeRateDto {
@jeroenr
jeroenr / DepositService.kt
Last active July 8, 2021 19:52
Example of service with many dependencies
@Service
class DepositService(
val userRepo: UserRepository,
val userAccountRepo: UserAccountRepository,
val exchangeApiClient: ExchangeApiClient,
val eventBus: EventBus
) {
@Transactional
fun deposit(userId: String, amount: BigDecimal, currency: String){
require(amount > BigDecimal.ZERO) { “Amount must be larger than 0” }
@jeroenr
jeroenr / DepositOrchestrationService.kt
Created July 8, 2021 19:22
Application Service example
open class DepositOrchestrationService(
private val depositService: DepositService,
private val userAccountRepositoryPort: UserAccountRepositoryPort,
private val userAccountEventPublisherPort: UserAccountEventPublisherPort
) {
@Transactional
open suspend fun deposit(request: DepositRequestDto): DepositResponseDto? =
userAccountRepositoryPort.findById(request.userId)?.let { userAccount ->
val oldBalance = userAccount.balance
val updated = depositService.deposit(userAccount, request.amount)
@jeroenr
jeroenr / DepositService.kt
Created July 8, 2021 19:15
Domain service example
class DepositService(private val exchangeRateApiClient: ExchangeRateApiClientPort) {
suspend fun deposit(userAccount: UserAccountDto, amount: Money): UserAccountDto {
require(amount.largerThanZero) { "Amount must be larger than 0" }
val rateToUsd = if (amount.currency != Currency.USD) {
exchangeRateApiClient.getRate(amount.currency, Currency.USD)
} else {
ExchangeRateDto(BigDecimal.ONE, Currency.USD)
}
val rateToPref = if (userAccount.balance.currency != Currency.USD) {
exchangeRateApiClient.getRate(Currency.USD, userAccount.balance.currency)
@jeroenr
jeroenr / UserAccount.kt
Last active July 8, 2021 19:12
Entity example
@Document
data class UserAccount(
@Id
val _id: ObjectId = ObjectId(),
var name: String,
var createdAt: Instant = Instant.now(),
var updatedAt: Instant = Instant.now()
) {
var auditTrail: List<String> = listOf()
fun updateName(name: String) {
@jeroenr
jeroenr / Money.kt
Created July 8, 2021 19:01
Value Object example
enum class Currency { USD, EUR }
data class Money(
val amount: BigDecimal,
val currency: Currency,
) {
val largerThanZero = amount > BigDecimal.ZERO
fun add(o: Money): Money {
if(currency != o.currency) throw IllegalArgumentException()
return Money(amount.add(o.amount), currency)
import sbt._
import sbt.Keys._
lazy val rainRadar = (project in file("."))
.enablePlugins(CloudflowAkkaStreamsApplicationPlugin)
.settings(
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http-spray-json" % "10.1.10",
"ch.qos.logback" % "logback-classic" % "1.2.3"
),
blueprint {
streamlets {
http-ingress = com.github.jeroenr.rain.radar.PrecipitationDataHttpIngress
partitioner = com.github.jeroenr.rain.radar.RainClutterPartitioner
rain-logger = com.github.jeroenr.rain.radar.RainLogger
clutter-logger = com.github.jeroenr.rain.radar.ClutterLogger
}
connections {
http-ingress.out = [partitioner.in]
package com.github.jeroenr.rain.radar
import akka.event.Logging
import cloudflow.akkastream._
import cloudflow.akkastream.scaladsl._
import cloudflow.streamlets._
import cloudflow.streamlets.avro._
import org.apache.avro.specific.SpecificRecordBase
import scala.reflect.ClassTag