Initial commit.

This commit is contained in:
Florian THIERRY
2025-09-18 16:57:59 +02:00
commit 076a224bcc
45 changed files with 1123 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
plugins {
id("java")
id("org.springframework.boot")
id("io.spring.dependency-management")
}
group = "com.zeenea.experiments.virtualthreads.virtualthreadsapp"
version = "0.0.1-SNAPSHOT"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
developmentOnly("org.springframework.boot:spring-boot-devtools")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
runtimeOnly("org.postgresql:postgresql")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
tasks.withType<Test> {
useJUnitPlatform()
}

View File

@@ -0,0 +1,10 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.configuration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@EnableJpaRepositories("com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure")
@EntityScan("com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure")
public class JpaConfiguration {}

View File

@@ -0,0 +1,21 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.model.Catalog;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.port.CatalogPort;
import org.springframework.stereotype.Service;
import java.util.Optional;
import java.util.UUID;
@Service
public class CatalogService {
private final CatalogPort catalogPort;
public CatalogService(CatalogPort catalogPort) {
this.catalogPort = catalogPort;
}
public Optional<Catalog> getById(UUID catalogId) {
return catalogPort.getById(catalogId);
}
}

View File

@@ -0,0 +1,5 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.model;
import java.util.UUID;
public record Catalog(UUID id, String name) {}

View File

@@ -0,0 +1,10 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.port;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.model.Catalog;
import java.util.Optional;
import java.util.UUID;
public interface CatalogPort {
Optional<Catalog> getById(UUID catalogId);
}

View File

@@ -0,0 +1,14 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/thread")
public class ThreadController {
@GetMapping("/name")
public String getThreadName() {
return Thread.currentThread().getName();
}
}

View File

@@ -0,0 +1,27 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.catalog;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.CatalogService;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.catalog.model.CatalogDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
import java.util.UUID;
@RestController
@RequestMapping("/api/catalogs")
public class CatalogController {
private final CatalogService catalogService;
public CatalogController(CatalogService catalogService) {
this.catalogService = catalogService;
}
@GetMapping("/{catalogId}")
public Optional<CatalogDto> getById(@PathVariable("catalogId") UUID catalogId) {
return catalogService.getById(catalogId)
.map(CatalogDto::new);
}
}

View File

@@ -0,0 +1,14 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.catalog.model;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.model.Catalog;
import java.util.UUID;
public record CatalogDto(
UUID id,
String name
) {
public CatalogDto(Catalog catalog) {
this(catalog.id(), catalog.name());
}
}

View File

@@ -0,0 +1,25 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.catalog;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.model.Catalog;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.port.CatalogPort;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.catalog.model.CatalogJpaEntity;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.catalog.repository.CatalogJpaRepository;
import org.springframework.stereotype.Component;
import java.util.Optional;
import java.util.UUID;
@Component
public class CatalogJpaAdapter implements CatalogPort {
private final CatalogJpaRepository catalogJpaRepository;
public CatalogJpaAdapter(CatalogJpaRepository catalogJpaRepository) {
this.catalogJpaRepository = catalogJpaRepository;
}
@Override
public Optional<Catalog> getById(UUID catalogId) {
return catalogJpaRepository.findById(catalogId)
.map(CatalogJpaEntity::toDomain);
}
}

View File

@@ -0,0 +1,35 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.catalog.model;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.catalog.model.Catalog;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.UUID;
@Entity
@Table(name = "catalog")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class CatalogJpaEntity {
@Id
private UUID id;
@Column(nullable = false)
private String name;
public CatalogJpaEntity(Catalog catalog) {
id = catalog.id();
name = catalog.name();
}
public Catalog toDomain() {
return new Catalog(id, name);
}
}

View File

@@ -0,0 +1,12 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.catalog.repository;
import com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.catalog.model.CatalogJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.UUID;
@Repository
public interface CatalogJpaRepository extends JpaRepository<CatalogJpaEntity, UUID> {
}

View File

@@ -0,0 +1,12 @@
package com.zeenea.experiments.virtualthreads.virtualthreadsapp.launcher;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.zeenea.experiments.virtualthreads.virtualthreadsapp")
public class VirtualThreadsApplication {
public static void main(String[] args) {
SpringApplication.run(VirtualThreadsApplication.class, args);
}
}

View File

@@ -0,0 +1,14 @@
spring:
application:
name: virtual-threads-app
datasource:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:51000/virtual_threads_test_db
username: virtual_threads_test_user
password: password
threads:
virtual:
enabled: true
server:
port: 51001

View File

@@ -0,0 +1,14 @@
\c virtual_threads_db;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE IF NOT EXISTS catalog (
id UUID NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL
);
CREATE TABLE IF NOT EXISTS item (
id UUID NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL,
shared_date TIMESTAMP WITH TIME ZONE NOT NULL
);