Skip to content

Commit fcc5497

Browse files
committed
Micronaut: Add base impl
1 parent da3b758 commit fcc5497

14 files changed

+322
-1
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@
55
## Quick start
66
1. Build: `./gradlew clean build`
77
2. Spin Up DB And Wiremock: `docker-compose -f docker-compose.yml up -d`
8-
3. Start one App: `./run-dropwizard.sh` or `./run-spring.sh`
8+
3. Start one of the Apps:
9+
- `./run-dropwizard.sh`
10+
- `./run-spring.sh`
11+
- `./run-micronaut.sh`
912
4. Run Gatling: `./gradlew :loadtest:gatlingRun`

micronaut-app/build.gradle

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
plugins {
2+
id "io.freefair.lombok" version "6.5.0.3"
3+
id("com.github.johnrengelman.shadow") version "7.1.2"
4+
id("io.micronaut.application") version "3.5.1"
5+
}
6+
7+
group = 'bitxon'
8+
version = '1.0-SNAPSHOT'
9+
sourceCompatibility = '17'
10+
11+
repositories {
12+
mavenCentral()
13+
}
14+
15+
dependencies {
16+
implementation project(":common-api")
17+
implementation("io.micronaut:micronaut-http-client")
18+
implementation("io.micronaut:micronaut-jackson-databind")
19+
implementation("jakarta.annotation:jakarta.annotation-api")
20+
implementation("io.micronaut:micronaut-validation")
21+
implementation("io.micronaut.beanvalidation:micronaut-hibernate-validator")
22+
implementation("io.micronaut:micronaut-management")
23+
24+
annotationProcessor("io.micronaut:micronaut-http-validation")
25+
26+
runtimeOnly("ch.qos.logback:logback-classic")
27+
28+
testImplementation("org.assertj:assertj-core")
29+
}
30+
31+
application {
32+
mainClass.set("bitxon.micronaut.MicronautApplication")
33+
}
34+
35+
graalvmNative.toolchainDetection = false
36+
micronaut {
37+
version("3.6.0")
38+
runtime("netty")
39+
testRuntime("junit5")
40+
processing {
41+
incremental(true)
42+
annotations("bitxon.micronaut.*")
43+
}
44+
}
45+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package bitxon.micronaut;
2+
3+
import io.micronaut.runtime.Micronaut;
4+
5+
public class MicronautApplication {
6+
7+
public static void main(String[] args) {
8+
Micronaut.run(MicronautApplication.class, args);
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package bitxon.micronaut.controller;
2+
3+
import static bitxon.api.constant.Constants.DIRTY_TRICK_HEADER;
4+
import static bitxon.api.constant.Constants.DirtyTrick.FAIL_TRANSFER;
5+
6+
import javax.validation.Valid;
7+
import java.util.List;
8+
import java.util.Random;
9+
10+
import bitxon.api.model.Account;
11+
import bitxon.api.model.MoneyTransfer;
12+
import io.micronaut.core.annotation.Nullable;
13+
import io.micronaut.http.HttpStatus;
14+
import io.micronaut.http.annotation.Body;
15+
import io.micronaut.http.annotation.Controller;
16+
import io.micronaut.http.annotation.Get;
17+
import io.micronaut.http.annotation.Header;
18+
import io.micronaut.http.annotation.PathVariable;
19+
import io.micronaut.http.annotation.Post;
20+
import io.micronaut.http.annotation.Status;
21+
22+
23+
@Controller("/accounts")
24+
public class AccountController {
25+
26+
@Get
27+
public List<Account> getAll() {
28+
return List.of();
29+
}
30+
31+
@Get("/{id}")
32+
public Account getById(@PathVariable("id") Long id) {
33+
return Account.builder().id(id).build();
34+
}
35+
36+
@Post
37+
public Account create(@Body @Valid Account account) {
38+
return Account.builder()
39+
.id(new Random().nextLong(0, Long.MAX_VALUE))
40+
.email(account.getEmail())
41+
.currency(account.getCurrency())
42+
.moneyAmount(account.getMoneyAmount())
43+
.build();
44+
}
45+
46+
@Post("/transfers")
47+
@Status(HttpStatus.NO_CONTENT)
48+
public void create(@Body @Valid MoneyTransfer transfer,
49+
@Header(value = DIRTY_TRICK_HEADER) @Nullable String dirtyTrick) {
50+
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
micronaut:
2+
application:
3+
name: micronaut-app
4+
server:
5+
port: 8080
6+
endpoints:
7+
all:
8+
port: 8081
9+
10+
netty:
11+
default:
12+
allocator:
13+
max-order: 3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<configuration>
2+
3+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
4+
<withJansi>true</withJansi>
5+
<!-- encoders are assigned the type
6+
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
7+
<encoder>
8+
<pattern>%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern>
9+
</encoder>
10+
</appender>
11+
12+
<root level="info">
13+
<appender-ref ref="STDOUT" />
14+
</root>
15+
16+
</configuration>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package bitxon.micronaut;
2+
3+
import io.micronaut.http.client.HttpClient;
4+
import io.micronaut.http.client.annotation.Client;
5+
import io.micronaut.runtime.EmbeddedApplication;
6+
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
7+
import jakarta.inject.Inject;
8+
9+
@MicronautTest
10+
class AbstractMicronautTest {
11+
12+
@Inject
13+
private EmbeddedApplication<?> application;
14+
@Inject
15+
@Client("/accounts")
16+
private HttpClient client;
17+
18+
protected HttpClient client() {
19+
return client;
20+
}
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package bitxon.micronaut;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.catchThrowableOfType;
5+
6+
import bitxon.api.model.Account;
7+
import io.micronaut.http.HttpRequest;
8+
import io.micronaut.http.HttpResponse;
9+
import io.micronaut.http.HttpStatus;
10+
import io.micronaut.http.client.exceptions.HttpClientResponseException;
11+
import org.junit.jupiter.api.Test;
12+
13+
14+
class CreateAccountByIdMicronautTest extends AbstractMicronautTest {
15+
16+
@Test
17+
public void create() {
18+
var account = Account.builder()
19+
20+
.currency("USD")
21+
.moneyAmount(893)
22+
.build();
23+
24+
var request = HttpRequest.POST("", account);
25+
var response = client().toBlocking().exchange(request, Account.class);
26+
27+
assertThat(response.getStatus().getCode()).isEqualTo(200);
28+
}
29+
30+
@Test
31+
void createWithMissedEmail() {
32+
var account = Account.builder()
33+
.email(null)
34+
.currency("USD")
35+
.moneyAmount(893)
36+
.build();
37+
38+
var request = HttpRequest.POST("", account);
39+
40+
var exception = catchThrowableOfType(
41+
() -> client().toBlocking().exchange(request, Account.class),
42+
HttpClientResponseException.class
43+
);
44+
45+
assertThat(exception)
46+
.extracting(HttpClientResponseException::getResponse)
47+
.extracting(HttpResponse::getStatus)
48+
.extracting(HttpStatus::getCode)
49+
.isEqualTo(400);
50+
}
51+
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package bitxon.micronaut;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import io.micronaut.http.HttpRequest;
6+
import org.junit.jupiter.api.Test;
7+
8+
9+
class FindAccountsMicronautTest extends AbstractMicronautTest {
10+
11+
@Test
12+
public void getAll() {
13+
var request = HttpRequest.GET("");
14+
var response = client().toBlocking().exchange(request);
15+
16+
assertThat(response.getStatus().getCode()).isEqualTo(200);
17+
}
18+
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package bitxon.micronaut;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import bitxon.api.model.Account;
6+
import io.micronaut.http.HttpRequest;
7+
import org.junit.jupiter.api.Test;
8+
9+
10+
class GetAccountByIdMicronautTest extends AbstractMicronautTest {
11+
12+
@Test
13+
public void getById() {
14+
var expectedId = 1L;
15+
var request = HttpRequest.GET("/" + expectedId);
16+
var response = client().toBlocking().exchange(request, Account.class);
17+
18+
assertThat(response.getStatus().getCode()).isEqualTo(200);
19+
assertThat(response.getBody())
20+
.map(Account::getId)
21+
.contains(expectedId);
22+
}
23+
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package bitxon.micronaut;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.catchThrowableOfType;
5+
6+
import bitxon.api.model.Account;
7+
import bitxon.api.model.MoneyTransfer;
8+
import io.micronaut.http.HttpRequest;
9+
import io.micronaut.http.HttpResponse;
10+
import io.micronaut.http.HttpStatus;
11+
import io.micronaut.http.client.exceptions.HttpClientResponseException;
12+
import org.junit.jupiter.api.Test;
13+
14+
15+
class MoneyTransferMicronautTest extends AbstractMicronautTest {
16+
17+
18+
@Test
19+
void transfer() {
20+
var transferAmount = 40;
21+
// Sender
22+
var senderId = 1L;
23+
var senderMoneyAmountOriginal = 340;
24+
var senderMoneyAmountResult = senderMoneyAmountOriginal - transferAmount;
25+
// Recipient
26+
var recipientId = 2L;
27+
var recipientMoneyAmountOriginal = 573;
28+
var recipientMoneyAmountResult = recipientMoneyAmountOriginal + transferAmount;
29+
30+
var requestBody = MoneyTransfer.builder()
31+
.senderId(senderId)
32+
.recipientId(recipientId)
33+
.moneyAmount(transferAmount)
34+
.build();
35+
36+
var request = HttpRequest.POST("/transfers", requestBody);
37+
var response = client().toBlocking().exchange(request);
38+
39+
assertThat(response.getStatus().getCode()).isEqualTo(204);
40+
41+
42+
}
43+
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<configuration>
2+
3+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
4+
<withJansi>true</withJansi>
5+
<!-- encoders are assigned the type
6+
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
7+
<encoder>
8+
<pattern>%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern>
9+
</encoder>
10+
</appender>
11+
12+
<root level="info">
13+
<appender-ref ref="STDOUT" />
14+
</root>
15+
16+
<logger name="io.micronaut.http.client" level="TRACE"/>
17+
18+
</configuration>

run-micronaut.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash
2+
java -jar micronaut-app/build/libs/micronaut-app-1.0-SNAPSHOT-all.jar

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ include 'common-api'
33
include 'common-wiremock'
44
include 'spring-app'
55
include 'dropwizard-app'
6+
include 'micronaut-app'
67
include 'loadtest'

0 commit comments

Comments
 (0)