Skip to content

Commit 007bf9d

Browse files
authored
Merge pull request #108 from LouisCAD/oodrive
RabbitMQ, Velocity, Barber
2 parents 095910c + 3bfa1d1 commit 007bf9d

File tree

13 files changed

+309
-22
lines changed

13 files changed

+309
-22
lines changed

.github/workflows/gradle-wrapper-validation.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

.github/workflows/runOnGitHub.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ jobs:
1414
gradle:
1515
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@v1
17+
- uses: actions/checkout@v2
18+
- name: Validate Gradle Wrapper
19+
uses: gradle/wrapper-validation-action@v1.0.3
1820
- uses: actions/setup-java@v1
1921
with:
2022
java-version: 11

kotlin-codegen/src/main/kotlin/playground/utils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fun shouldThrow(message: String, block: () -> Any?) {
55
block()
66
"Expected a throwable, but nothing was thrown."
77
} catch (e: Throwable) {
8-
if (e.message == message) {
8+
if ("$e".contains(message)) {
99
println("Test: got expected exception <<$message>>")
1010
null
1111
} else {

kotlin-jvm/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ apollo {
2424
dependencies {
2525
implementation(project(":kotlin-codegen"))
2626
// Keep dependencies sorted to minimize merge conflicts on pull-requests!
27+
implementation("app.cash.barber:barber:_")
2728
implementation ("com.github.ajalt:mordant:_")
2829
implementation("com.beust:klaxon:_")
2930
implementation("com.github.ajalt.clikt:clikt:_")
3031
implementation("com.github.kittinunf.fuel:fuel:_")
3132
implementation("com.github.kittinunf.fuel:fuel-kotlinx-serialization:_")
3233
implementation("com.h2database:h2:_")
34+
implementation("com.rabbitmq:amqp-client:_")
3335
implementation("com.sksamuel.hoplite:hoplite-core:_")
3436
implementation("com.sksamuel.hoplite:hoplite-hocon:_")
3537
implementation("com.sksamuel.hoplite:hoplite-yaml:_")
@@ -42,6 +44,8 @@ dependencies {
4244
implementation("io.reactivex.rxjava3:rxjava:_")
4345
implementation("it.skrape:skrapeit-core:_")
4446
implementation("it.skrape:skrapeit-http-fetcher:_")
47+
implementation("org.apache.velocity.tools:velocity-tools-generic:_")
48+
implementation("org.apache.velocity:velocity-engine-core:_")
4549
implementation("org.jetbrains.exposed:exposed-core:_")
4650
implementation("org.jetbrains.exposed:exposed-dao:_")
4751
implementation("org.jetbrains.exposed:exposed-java-time:_")
@@ -57,6 +61,7 @@ dependencies {
5761
implementation("org.kodein.di:kodein-di:_")
5862
implementation("org.koin:koin-core:_")
5963
implementation("org.nield:kotlin-statistics:_")
64+
implementation("org.slf4j:slf4j-simple:_")
6065
// Keep dependencies sorted to minimize merge conflicts on pull-requests!
6166
implementation(JakeWharton.picnic)
6267
implementation(JakeWharton.retrofit2.converter.kotlinxSerialization)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
@file:Suppress("PackageDirectoryMismatch")
2+
3+
package playground.barber
4+
5+
import app.cash.barber.Barber
6+
import app.cash.barber.Barbershop
7+
import app.cash.barber.BarbershopBuilder
8+
import app.cash.barber.getBarber
9+
import app.cash.barber.locale.Locale.Companion.EN_US
10+
import app.cash.barber.models.Document
11+
import app.cash.barber.models.DocumentData
12+
import app.cash.barber.models.DocumentTemplate
13+
import playground.shouldBe
14+
import playground.shouldThrow
15+
import java.time.Instant
16+
import java.util.*
17+
18+
/***
19+
* cashapp/barber
20+
* A type safe Kotlin JVM library for building up localized, fillable, themed documents using Mustache templating.
21+
*
22+
* - [GitHub](https://github.com/cashapp/barber)
23+
* - [Documentation](https://cashapp.github.io/barber/)
24+
*/
25+
fun main() {
26+
println()
27+
println("# cashapp/barber")
28+
val recipientReceiptSmsDocumentTemplateEN_US = DocumentTemplate(
29+
fields = mapOf(
30+
"subject" to "{{sender}} sent you {{amount}}",
31+
"headline" to "New transfer",
32+
"short_description" to "{{sender}} sent {{amount}}",
33+
"secondary_button_url" to "{{cancelUrl}}"
34+
),
35+
source = RecipientReceipt::class,
36+
targets = setOf(TransactionalSmsDocument::class),
37+
locale = EN_US
38+
)
39+
40+
val barbershop = BarbershopBuilder()
41+
.installDocumentTemplate<RecipientReceipt>(recipientReceiptSmsDocumentTemplateEN_US)
42+
.installDocument<TransactionalSmsDocument>()
43+
.build()
44+
45+
// Get a Barber who knows how to render RecipientReceipt data into a TransactionalSmsDocument
46+
val recipientReceiptSms = barbershop.getBarber<RecipientReceipt, TransactionalSmsDocument>()
47+
val recept = RecipientReceipt(
48+
"Patrick", "14€", "http://example.com", Instant.now()
49+
)
50+
val transactionalSmsDocument: TransactionalSmsDocument = recipientReceiptSms.render(recept, EN_US)
51+
transactionalSmsDocument shouldBe TransactionalSmsDocument(
52+
"Patrick sent you 14€","New transfer", "Patrick sent 14€", null, null, null, "http://example.com"
53+
)
54+
55+
shouldThrow("DocumentData [unregistered] and corresponding DocumentTemplate(s) are not installed in Barbershop") {
56+
barbershop.getBarber<UnregisteredDocumentData, TransactionalSmsDocument>()
57+
}
58+
59+
}
60+
61+
// Define DocumentData
62+
data class RecipientReceipt(
63+
val sender: String,
64+
val amount: String,
65+
val cancelUrl: String,
66+
val deposit_expected_at: Instant
67+
) : DocumentData
68+
69+
data class TransactionalSmsDocument(
70+
val subject: String,
71+
val headline: String,
72+
val short_description: String,
73+
val primary_button: String?,
74+
val primary_button_url: String?,
75+
val secondary_button: String?,
76+
val secondary_button_url: String?
77+
) : Document
78+
79+
data class UnregisteredDocumentData(
80+
val id: Long
81+
): DocumentData

kotlin-jvm/src/main/kotlin/playground/Konf.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private fun Config.printConfig() {
6868
Credentials:
6969
- username: ${this[CredentialsSpec.username]}
7070
- password: ${this[CredentialsSpec.password]}
71-
71+
7272
Server:
7373
- domain: ${this[ServerSpec.domain]}
7474
- protocol: ${this[ServerSpec.protocol]}
@@ -90,4 +90,4 @@ enum class ServerProtocol {
9090
HTTP, HTTPS
9191
}
9292

93-
private const val configPath = "configuration"
93+
private const val configPath = "configuration"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
@file:Suppress("PackageDirectoryMismatch")
2+
3+
package playground.rabbitmq.client
4+
5+
import com.rabbitmq.client.CancelCallback
6+
import com.rabbitmq.client.Channel
7+
import com.rabbitmq.client.ConnectionFactory
8+
import com.rabbitmq.client.DeliverCallback
9+
import com.rabbitmq.client.Delivery
10+
import com.uchuhimo.konf.Config
11+
import playground.rabbitmq.producer.AmqpSpec
12+
import java.nio.charset.StandardCharsets
13+
14+
fun main() {
15+
println()
16+
println("# rabbitmq")
17+
18+
val config = Config {
19+
addSpec(AmqpSpec)
20+
}
21+
val spec = config.from.env()
22+
println(spec)
23+
val factory = ConnectionFactory()
24+
factory.newConnection(spec[AmqpSpec.url]).use { connection ->
25+
connection.createChannel().use { channel ->
26+
consumeMessage(channel, spec[AmqpSpec.queue])
27+
}
28+
}
29+
}
30+
31+
fun consumeMessage(channel: Channel, queueName: String) {
32+
val consumerTag = "SimpleConsumer"
33+
34+
channel.queueDeclare(queueName, false, false, false, null)
35+
36+
println("[$consumerTag] Waiting for messages...")
37+
val deliverCallback = DeliverCallback { consumerTag: String?, delivery: Delivery ->
38+
val message = String(delivery.body, StandardCharsets.UTF_8)
39+
println("[$consumerTag] Received message: '$message'")
40+
}
41+
val cancelCallback = CancelCallback { consumerTag: String? ->
42+
println("[$consumerTag] was canceled")
43+
}
44+
45+
channel.basicConsume(queueName, true, consumerTag, deliverCallback, cancelCallback)
46+
47+
}
48+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
@file:Suppress("PackageDirectoryMismatch")
2+
3+
package playground.rabbitmq.producer
4+
5+
import com.rabbitmq.client.ConnectionFactory
6+
import com.uchuhimo.konf.Config
7+
import com.uchuhimo.konf.ConfigSpec
8+
import java.nio.charset.StandardCharsets
9+
10+
fun main() {
11+
println()
12+
println("# rabbitmq producer")
13+
14+
val config = Config {
15+
addSpec(AmqpSpec)
16+
}
17+
val spec = config.from.env()
18+
println(spec)
19+
val factory = ConnectionFactory()
20+
factory.newConnection(spec[AmqpSpec.url]).use { connection ->
21+
connection.createChannel().use { channel ->
22+
channel.queueDeclare(spec[AmqpSpec.queue], false, false, false, null)
23+
val message = "Hello World!"
24+
channel.basicPublish(
25+
"",
26+
spec[AmqpSpec.queue],
27+
null,
28+
message.toByteArray(StandardCharsets.UTF_8)
29+
)
30+
println(" [x] Sent '$message'")
31+
}
32+
}
33+
}
34+
35+
object AmqpSpec : ConfigSpec() {
36+
val url by required<String>()
37+
val queue by required<String>()
38+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
@file:Suppress("PackageDirectoryMismatch")
2+
3+
package playground.velocity
4+
5+
import org.apache.velocity.Template
6+
import org.apache.velocity.VelocityContext
7+
import org.apache.velocity.app.VelocityEngine
8+
import playground.shouldBe
9+
import java.io.StringWriter
10+
import java.util.*
11+
12+
/**
13+
* Velocity is a Java-based template engine. It permits anyone to use a simple yet powerful template language to reference objects defined in Java code.
14+
*
15+
* [Apache Velocity Engine - User Guide](https://velocity.apache.org/engine/2.3/user-guide.html)
16+
* [Apache Velocity Engine - Developer Guide](https://velocity.apache.org/engine/2.3/developer-guide.html)
17+
*/
18+
fun main() {
19+
println()
20+
println("# Velocity")
21+
22+
val engine = velocityEngine()
23+
if (engine.resourceExists("/hello.vm")) helloWorld(engine)
24+
if (engine.resourceExists("/complex.vm")) complexExample(engine)
25+
}
26+
27+
28+
fun helloWorld(engine: VelocityEngine) {
29+
val context = VelocityContext()
30+
context.put("name", "Velocity")
31+
val template: Template = engine.getTemplate("/hello.vm")
32+
template.apply(context) shouldBe """
33+
<body>
34+
Hello Velocity World!
35+
</body>
36+
""".trimIndent()
37+
38+
}
39+
40+
41+
fun complexExample(engine: VelocityEngine) {
42+
val context = VelocityContext().apply {
43+
put("name", "Velocity")
44+
put("details", true)
45+
put("customer", VelocityCustomer("Jean-Michel", 39))
46+
put("groceries", listOf("apple", "milk"))
47+
}
48+
engine.getTemplate("/complex.vm").apply(context) shouldBe """
49+
Hello Velocity
50+
I speak French
51+
Customer Jean-Michel is 41 years old.
52+
Is he old? true enough
53+
Groceries:
54+
- apple
55+
- milk
56+
""".trimIndent()
57+
}
58+
59+
data class VelocityCustomer(val name: String, var age: Int) {
60+
fun isOld() = age >= 40
61+
}
62+
63+
64+
private fun Template.apply(context: VelocityContext) : String {
65+
val sw = StringWriter()
66+
merge(context, sw)
67+
return sw.toString().trim()
68+
}
69+
70+
private fun velocityEngine(): VelocityEngine {
71+
val properties = Properties().also {
72+
it.setProperty(
73+
"resource.loader.file.path",
74+
"/Users/jmfayard/Documents/GitHub/kotlin-libraries-playground/kotlin-jvm/src/main/resources"
75+
)
76+
}
77+
val engine = VelocityEngine(properties)
78+
engine.init();
79+
return engine
80+
}

kotlin-jvm/src/main/kotlin/playground/_main.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ fun main() {
88
* Keep the list sorted to minimize merge conflicts on pull-requests!
99
*/
1010
playground.apollo.main()
11+
playground.barber.main()
1112
playground.clikt.main(arrayOf("--language", "FR", "--greeting", "Bonjour"))
1213
playground.clikt.main(arrayOf())
1314
playground.di.kodein.main()
@@ -42,6 +43,7 @@ fun main() {
4243
playground.skrapeit.main()
4344
playground.sqldelight.main()
4445
playground.statemachine.main()
46+
playground.velocity.main()
4547
/**
4648
* Keep the list sorted to minimize merge conflicts on pull-requests!
4749
*/

0 commit comments

Comments
 (0)