@re-shell/cli
Version:
Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja
1,595 lines (1,367 loc) โข 48.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.quarkusTemplate = void 0;
exports.quarkusTemplate = {
id: 'quarkus',
name: 'Quarkus',
displayName: 'Quarkus Native',
description: 'Cloud-native Java microservices with GraalVM native compilation support',
version: '3.6.0',
framework: 'quarkus',
language: 'java',
port: 8080,
tags: ['cloud-native', 'microservices', 'reactive', 'graalvm', 'kubernetes'],
features: [
'authentication',
'authorization',
'database',
'caching',
'logging',
'monitoring',
'testing',
'documentation',
'security',
'validation',
'rest-api',
'graphql',
'microservices',
'docker'
],
dependencies: {},
devDependencies: {},
postInstall: [
'echo "โ
Quarkus project created successfully!"',
'echo "๐ฆ Installing dependencies..."',
'./mvnw clean install',
'echo "๐ Start development server: ./mvnw quarkus:dev"',
'echo "๐ API Documentation: http://localhost:{{port}}/q/swagger-ui"',
'echo "โก Build native image: ./mvnw package -Pnative"'
],
files: {
'pom.xml': `<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>{{packageName}}</groupId>
<artifactId>{{serviceName}}</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.6.0</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.1.2</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>\${quarkus.platform.group-id}</groupId>
<artifactId>\${quarkus.platform.artifact-id}</artifactId>
<version>\${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Core -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<!-- Database -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-flyway</artifactId>
</dependency>
<!-- Security -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-security</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elytron-security-properties-file</artifactId>
</dependency>
<!-- Caching -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-cache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-redis-client</artifactId>
</dependency>
<!-- Validation -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<!-- Health & Metrics -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency>
<!-- Documentation -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
<!-- Reactive -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mutiny</artifactId>
</dependency>
<!-- Utilities -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-config-yaml</artifactId>
</dependency>
<!-- Testing -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-mockito</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-security-jwt</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>\${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>\${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>\${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>\${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>\${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>\${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>\${project.build.directory}/\${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>\${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
`,
'src/main/java/{{packagePath}}/entity/User.java': `package {{packageName}}.entity;
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import io.quarkus.security.jpa.Password;
import io.quarkus.security.jpa.Roles;
import io.quarkus.security.jpa.UserDefinition;
import io.quarkus.security.jpa.Username;
import jakarta.persistence.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
public class User extends PanacheEntityBase {
public Long id;
public String username;
public String email;
public String password;
public String firstName;
public String lastName;
public String roles = "user";
public boolean active = true;
public LocalDateTime createdAt = LocalDateTime.now();
public LocalDateTime updatedAt;
public void preUpdate() {
updatedAt = LocalDateTime.now();
}
public static User findByUsername(String username) {
return find("username", username).firstResult();
}
public static User findByEmail(String email) {
return find("email", email).firstResult();
}
public static boolean existsByUsername(String username) {
return count("username", username) > 0;
}
public static boolean existsByEmail(String email) {
return count("email", email) > 0;
}
}
`,
'src/main/java/{{packagePath}}/resource/UserResource.java': `package {{packageName}}.resource;
import {{packageName}}.dto.UserDto;
import {{packageName}}.entity.User;
import {{packageName}}.service.UserService;
import io.quarkus.panache.common.Page;
import io.quarkus.panache.common.Sort;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import java.util.List;
import java.util.stream.Collectors;
public class UserResource {
UserService userService;
public Response getUsers(
int page,
int size,
String sort) {
List<User> users = User.findAll(Sort.by(sort))
.page(Page.of(page, size))
.list();
List<UserDto> userDtos = users.stream()
.map(UserDto::from)
.collect(Collectors.toList());
return Response.ok(userDtos).build();
}
public Response getUser( Long id) {
User user = User.findById(id);
if (user == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.ok(UserDto.from(user)).build();
}
public Response createUser( UserDto userDto) {
User user = userService.createUser(userDto);
return Response.status(Response.Status.CREATED)
.entity(UserDto.from(user))
.build();
}
public Response updateUser( Long id, UserDto userDto) {
User user = userService.updateUser(id, userDto);
if (user == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.ok(UserDto.from(user)).build();
}
public Response deleteUser( Long id) {
boolean deleted = User.deleteById(id);
if (!deleted) {
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.noContent().build();
}
}
`,
'src/main/java/{{packagePath}}/resource/AuthResource.java': `package {{packageName}}.resource;
import {{packageName}}.dto.*;
import {{packageName}}.service.AuthService;
import io.quarkus.cache.CacheInvalidate;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
public class AuthResource {
AuthService authService;
public Response register( RegisterRequest request) {
AuthResponse response = authService.register(request);
return Response.status(Response.Status.CREATED).entity(response).build();
}
public Response login( LoginRequest request) {
AuthResponse response = authService.authenticate(request);
return Response.ok(response).build();
}
public Response refresh( String refreshToken) {
AuthResponse response = authService.refreshToken(refreshToken);
return Response.ok(response).build();
}
public Response logout() {
// In a real application, you would invalidate the token here
return Response.noContent().build();
}
}
`,
'src/main/java/{{packagePath}}/service/UserService.java': `package {{packageName}}.service;
import {{packageName}}.dto.UserDto;
import {{packageName}}.entity.User;
import io.quarkus.cache.CacheInvalidate;
import io.quarkus.cache.CacheResult;
import io.quarkus.elytron.security.common.BcryptUtil;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.transaction.Transactional;
public class UserService {
public User getUserById(Long id) {
return User.findById(id);
}
public User createUser(UserDto userDto) {
if (User.existsByUsername(userDto.username)) {
throw new IllegalArgumentException("Username already exists");
}
if (User.existsByEmail(userDto.email)) {
throw new IllegalArgumentException("Email already exists");
}
User user = new User();
user.username = userDto.username;
user.email = userDto.email;
user.password = BcryptUtil.bcryptHash(userDto.password);
user.firstName = userDto.firstName;
user.lastName = userDto.lastName;
user.roles = "user";
user.persist();
return user;
}
public User updateUser(Long id, UserDto userDto) {
User user = User.findById(id);
if (user == null) {
return null;
}
if (userDto.firstName != null) {
user.firstName = userDto.firstName;
}
if (userDto.lastName != null) {
user.lastName = userDto.lastName;
}
if (userDto.email != null && !userDto.email.equals(user.email)) {
if (User.existsByEmail(userDto.email)) {
throw new IllegalArgumentException("Email already exists");
}
user.email = userDto.email;
}
user.persist();
return user;
}
}
`,
'src/main/java/{{packagePath}}/service/AuthService.java': `package {{packageName}}.service;
import {{packageName}}.dto.*;
import {{packageName}}.entity.User;
import io.quarkus.elytron.security.common.BcryptUtil;
import io.smallrye.jwt.build.Jwt;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashSet;
public class AuthService {
String issuer;
Long duration;
Long refreshDuration;
UserService userService;
public AuthResponse register(RegisterRequest request) {
UserDto userDto = new UserDto();
userDto.username = request.username;
userDto.email = request.email;
userDto.password = request.password;
userDto.firstName = request.firstName;
userDto.lastName = request.lastName;
User user = userService.createUser(userDto);
String token = generateToken(user);
String refreshToken = generateRefreshToken(user);
return AuthResponse.builder()
.accessToken(token)
.refreshToken(refreshToken)
.tokenType("Bearer")
.expiresIn(duration)
.user(UserDto.from(user))
.build();
}
public AuthResponse authenticate(LoginRequest request) {
User user = User.findByUsername(request.username);
if (user == null) {
user = User.findByEmail(request.username);
}
if (user == null || !BcryptUtil.matches(request.password, user.password)) {
throw new WebApplicationException("Invalid credentials", 401);
}
if (!user.active) {
throw new WebApplicationException("Account is disabled", 403);
}
String token = generateToken(user);
String refreshToken = generateRefreshToken(user);
return AuthResponse.builder()
.accessToken(token)
.refreshToken(refreshToken)
.tokenType("Bearer")
.expiresIn(duration)
.user(UserDto.from(user))
.build();
}
public AuthResponse refreshToken(String refreshToken) {
// In a real application, you would validate the refresh token
// For this example, we'll parse it and generate a new access token
try {
var parser = Jwt.parser().verify(refreshToken);
String username = parser.getClaim("sub");
User user = User.findByUsername(username);
if (user == null || !user.active) {
throw new WebApplicationException("Invalid token", 401);
}
String newToken = generateToken(user);
return AuthResponse.builder()
.accessToken(newToken)
.refreshToken(refreshToken)
.tokenType("Bearer")
.expiresIn(duration)
.user(UserDto.from(user))
.build();
} catch (Exception e) {
throw new WebApplicationException("Invalid refresh token", 401);
}
}
private String generateToken(User user) {
return Jwt.issuer(issuer)
.upn(user.username)
.subject(user.username)
.groups(new HashSet<>(Arrays.asList(user.roles.split(","))))
.claim("email", user.email)
.claim("userId", user.id)
.expiresIn(Duration.ofSeconds(duration))
.sign();
}
private String generateRefreshToken(User user) {
return Jwt.issuer(issuer)
.upn(user.username)
.subject(user.username)
.claim("type", "refresh")
.expiresIn(Duration.ofSeconds(refreshDuration))
.sign();
}
}
`,
'src/main/java/{{packagePath}}/dto/UserDto.java': `package {{packageName}}.dto;
import {{packageName}}.entity.User;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
public class UserDto {
public Long id;
public String username;
public String email;
public String password;
public String firstName;
public String lastName;
public String roles;
public boolean active;
public LocalDateTime createdAt;
public LocalDateTime updatedAt;
public static UserDto from(User user) {
UserDto dto = new UserDto();
dto.id = user.id;
dto.username = user.username;
dto.email = user.email;
dto.firstName = user.firstName;
dto.lastName = user.lastName;
dto.roles = user.roles;
dto.active = user.active;
dto.createdAt = user.createdAt;
dto.updatedAt = user.updatedAt;
return dto;
}
}
`,
'src/main/java/{{packagePath}}/dto/LoginRequest.java': `package {{packageName}}.dto;
import jakarta.validation.constraints.NotBlank;
public class LoginRequest {
public String username;
public String password;
}
`,
'src/main/java/{{packagePath}}/dto/RegisterRequest.java': `package {{packageName}}.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class RegisterRequest {
public String username;
public String email;
public String password;
public String firstName;
public String lastName;
}
`,
'src/main/java/{{packagePath}}/dto/AuthResponse.java': `package {{packageName}}.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class AuthResponse {
public String accessToken;
public String refreshToken;
public String tokenType;
public Long expiresIn;
public UserDto user;
public static Builder builder() {
return new Builder();
}
public static class Builder {
private AuthResponse response = new AuthResponse();
public Builder accessToken(String accessToken) {
response.accessToken = accessToken;
return this;
}
public Builder refreshToken(String refreshToken) {
response.refreshToken = refreshToken;
return this;
}
public Builder tokenType(String tokenType) {
response.tokenType = tokenType;
return this;
}
public Builder expiresIn(Long expiresIn) {
response.expiresIn = expiresIn;
return this;
}
public Builder user(UserDto user) {
response.user = user;
return this;
}
public AuthResponse build() {
return response;
}
}
}
`,
'src/main/java/{{packagePath}}/health/DatabaseHealthCheck.java': `package {{packageName}}.health;
import io.agroal.api.AgroalDataSource;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Readiness;
import java.sql.Connection;
import java.sql.SQLException;
public class DatabaseHealthCheck implements HealthCheck {
AgroalDataSource dataSource;
public HealthCheckResponse call() {
HealthCheckResponse.HealthCheckResponseBuilder responseBuilder = HealthCheckResponse
.named("Database connection health check");
try (Connection connection = dataSource.getConnection()) {
boolean valid = connection.isValid(10);
if (valid) {
responseBuilder.up();
} else {
responseBuilder.down();
}
} catch (SQLException e) {
responseBuilder.down()
.withData("error", e.getMessage());
}
return responseBuilder.build();
}
}
`,
'src/main/java/{{packagePath}}/health/RedisHealthCheck.java': `package {{packageName}}.health;
import io.quarkus.redis.client.RedisClient;
import io.vertx.mutiny.redis.client.Response;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Liveness;
import java.time.Duration;
public class RedisHealthCheck implements HealthCheck {
RedisClient redisClient;
public HealthCheckResponse call() {
HealthCheckResponse.HealthCheckResponseBuilder responseBuilder = HealthCheckResponse
.named("Redis connection health check");
try {
Response response = redisClient.ping()
.onFailure()
.retry()
.atMost(3)
.await()
.atMost(Duration.ofSeconds(3));
if (response != null && response.toString().equals("PONG")) {
responseBuilder.up();
} else {
responseBuilder.down();
}
} catch (Exception e) {
responseBuilder.down()
.withData("error", e.getMessage());
}
return responseBuilder.build();
}
}
`,
'src/main/java/{{packagePath}}/exception/ErrorMapper.java': `package {{packageName}}.exception;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ErrorMapper implements ExceptionMapper<ConstraintViolationException> {
public Response toResponse(ConstraintViolationException e) {
Map<String, Object> error = new HashMap<>();
error.put("type", "validation_error");
error.put("title", "Validation Failed");
Map<String, String> violations = new HashMap<>();
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
for (ConstraintViolation<?> violation : constraintViolations) {
String path = violation.getPropertyPath().toString();
String message = violation.getMessage();
violations.put(path, message);
}
error.put("violations", violations);
return Response.status(Response.Status.BAD_REQUEST)
.entity(error)
.build();
}
}
`,
'src/main/java/{{packagePath}}/exception/WebApplicationExceptionMapper.java': `package {{packageName}}.exception;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import java.util.HashMap;
import java.util.Map;
public class WebApplicationExceptionMapper implements ExceptionMapper<WebApplicationException> {
public Response toResponse(WebApplicationException e) {
Map<String, Object> error = new HashMap<>();
error.put("type", "application_error");
error.put("status", e.getResponse().getStatus());
error.put("message", e.getMessage());
return Response.status(e.getResponse().getStatus())
.entity(error)
.build();
}
}
`,
'src/main/resources/application.yml': `quarkus:
application:
name: {{serviceName}}
version: 1.0.0
http:
port: {{port}}
cors:
~: true
origins: "http://localhost:3000,http://localhost:5173"
methods: "GET,POST,PUT,DELETE,OPTIONS"
headers: "*"
exposed-headers: "*"
datasource:
db-kind: postgresql
username: \${DB_USERNAME:postgres}
password: \${DB_PASSWORD:postgres}
jdbc:
url: jdbc:postgresql://\${DB_HOST:localhost}:\${DB_PORT:5432}/\${DB_NAME:{{serviceName}}_db}
max-size: 16
hibernate-orm:
database:
generation: none
log:
sql: false
flyway:
migrate-at-start: true
locations: db/migration
redis:
hosts: redis://\${REDIS_HOST:localhost}:\${REDIS_PORT:6379}
password: \${REDIS_PASSWORD:}
timeout: 10s
cache:
type: redis
redis:
"user-cache":
expire-after-write: 10M
"default":
expire-after-write: 5M
log:
level: INFO
category:
"{{packageName}}":
level: DEBUG
native:
container-build: true
builder-image: quay.io/quarkus/ubi-quarkus-mandrel-builder-image:23.1-java17
mp:
jwt:
verify:
publickey:
location: publicKey.pem
issuer: {{serviceName}}
jwt:
duration: 3600
refresh:
duration: 86400
"%dev":
quarkus:
log:
console:
enable: true
format: "%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n"
level: DEBUG
hibernate-orm:
log:
sql: true
"%test":
quarkus:
datasource:
db-kind: h2
jdbc:
url: jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1
hibernate-orm:
database:
generation: drop-and-create
`,
'src/main/resources/db/migration/V1__Create_users_table.sql': `CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
roles VARCHAR(255) DEFAULT 'user',
active BOOLEAN DEFAULT true,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
);
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_active ON users(active);
-- Create admin user (password: admin123)
INSERT INTO users (username, email, password, first_name, last_name, roles)
VALUES ('admin', 'admin@{{org}}.com', '$2a$10$mVWJ3N5pJ.6KJxPl8XhKaOjFqQH.Y3bg8gFRT6bCBLrJWBZwJvj9S', 'Admin', 'User', 'admin,user');
`,
'src/main/resources/privateKey.pem': `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7KlFzjF5C
fHQgusEK1FM0Z5845KN7IgNcr6u8EzjDkfOH6HwTGHfcdJqzl3KJBuJqPQAOjlo4
kB1hdRy0K2Q5g6jKBcUL6pYqJurFmFkVQqpFdBFwF/fPDGJvOumWjc6OGKpvKkNo
jLf4a0MJZ0YMOHUJMbHmVA0hZVDe6FWWnl0TWmJmfaL8JdyU/HHtPiLl5XjGPgE6
bgXwXBhcOREzwWt2FM6lzOqMbicntUDwqAl3etmFJlXzh+C9BvawCC4MFCR4UAFC
n5UtfRqxAgMBAAECggEAB0nW2ApqWzx5k6T25eKh4zCYbHDpYdXnRdYB6yH+gt2P
DJkUIA5/4wZGnVhGLl6cBKDrANzyLkqJUZMHuuBk+7L1QBGDTHD7jI7wfPl7PKUW
xKEnPgl0hIj3bqHU9QLOyT7OKJLywqsbjXbWqMkZuBwCrGp3zsDQksNCS6it7SeZ
LLtbDANKW/qx/8/NIr9gP3rJDcJgdBHCM3A3pIPqsRjW2BQpGGPWxxxj9TjFQdRW
jN0xlr2DplcXnuVJkQW7j3E2mGnHJh4DxOdnMiS2Lv9mU6Y5MMKgWT3iI1MhdPPE
VLM4phZPbcXLCWTKENU1WShXZK1vVYgsY0SMAJduwQKBgQDE/ksW7f39HqMD6nQB
5k8GeiEGgCGKJRPSJlEi+K9eOYOalqZ8YXsFHaJowru6J7FvCd7cacikrqPCJgeZ
YNCgUxskFgQ9w0v1tpShJNaFdGTBkJSmVNpbeFTNhKgEeVePJLm9VKdlivBl6qJV
p3tierQV42jimZHMqNmglk9o0QKBgQDDJVYCPSGYMsVYDXcP4u1lbA6nN5WkYJ8z
AVFcTHfBU+Vtt0KeponAlGkLH48YrxP8TWXKT8LQnsywbhCB+7R8vQ3vhkc7ILVU
L9Ye8JPrIKc2nC1oCPPaOC5Y7ehzztLiI8bO+TBLGKhO/s1s6pLT0q9V3NWEmR0n
Ff4LRoFMgQKBgQCBenP4HMFEzBH/MN6HJvmCjIcFVI3j5bZ6vK5vaOu2n5b9Kqxt
k3DQSY9x0VRxHAGX8M2IaF5gNxnrHEZ6i6to7akj8rU4PoP2PVAKcQdXEHltaT8K
TcIWJEHMdW3CBVx3wQ1Rl+uGjQngaZz6PFooKrGCo8ESUucgjVpQ8w16AQKBgHCD
niHa7fGXXNcLQ/gUXe+xbnGS4nLHgLJEGnGeIbgvP7r9xQBHMlv3N4YNNbXt8EKe
RdOtguuJmf8lK9se7f7lazmp6ND8WLJdkQNmZ3fvMVXe9nVyUKh1JJo1HDlTkfCz
oZW8sWXLBpiG0geqcponGba6l7Lx3mZpqBVfcnoBAoGABaBnDAqsKyhtoKkGfa5O
+nFO3n7cGXji0Vx8cGxL3hrGXWNFkUfMo6I0WQUUVhvsJVXMlN8F0Okm0xS6YTHa
DSvG2jG1mEWw0S6n5CYoV/zJ+lKxRmN1rv5iAmNfZ1OqJjLb4qNRNRqZb2ZrM0fx
dQwT/x8hsDdeAIVAIy9k2Fs=
-----END PRIVATE KEY-----
`,
'src/main/resources/publicKey.pem': `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+nt4Iv1p4kE1sPEQOypRc4xeQnx0ILrB
CtRTNGefOOSjeyIDXK+rvBM4w5Hzh+h8Exh33HSas5dyiQbaj0ADo5aOJAdYXUc
tClkOYOoygXFC+qWKibrxZhZFUKqRXQRcBf3zwxib7jrplo3Ojhiqb+pDaIy3+Gt
DCWdGDDh1CTGx5lQNIWVQ3uhVlp5dE1piZn2i/CXclPxx7T4i5eV4xj4BOm4F8Fw
YXDkRM8FrdhTOpcTqjG4nJ7VA8KgJd3rZiZV84fgvQb2sAguDBQkeFABQp+VLX0a
sQIDAQAB
-----END PUBLIC KEY-----
`,
'src/test/java/{{packagePath}}/UserResourceTest.java': `package {{packageName}};
import {{packageName}}.dto.UserDto;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
public class UserResourceTest {
public void testGetUsersEndpoint() {
given()
.when().get()
.then()
.statusCode(200)
.body("$.size()", is(1));
}
public void testGetUserById() {
given()
.when().get("/1")
.then()
.statusCode(200)
.body("username", is("admin"));
}
public void testCreateUser() {
UserDto userDto = new UserDto();
userDto.username = "testuser";
userDto.email = "test@example.com";
userDto.password = "password123";
userDto.firstName = "Test";
userDto.lastName = "User";
given()
.contentType(ContentType.JSON)
.body(userDto)
.when().post()
.then()
.statusCode(201)
.body("id", notNullValue())
.body("username", is("testuser"));
}
public void testUnauthorizedAccess() {
given()
.when().get()
.then()
.statusCode(401);
}
public void testForbiddenAccess() {
given()
.when().get()
.then()
.statusCode(403);
}
}
`,
'src/test/java/{{packagePath}}/AuthResourceTest.java': `package {{packageName}};
import {{packageName}}.dto.LoginRequest;
import {{packageName}}.dto.RegisterRequest;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.is;
public class AuthResourceTest {
public void testRegisterNewUser() {
RegisterRequest request = new RegisterRequest();
request.username = "newuser";
request.email = "newuser@example.com";
request.password = "password123";
request.firstName = "New";
request.lastName = "User";
given()
.contentType(ContentType.JSON)
.body(request)
.when().post("/api/auth/register")
.then()
.statusCode(201)
.body("access_token", notNullValue())
.body("refresh_token", notNullValue())
.body("token_type", is("Bearer"))
.body("user.username", is("newuser"));
}
public void testLoginWithValidCredentials() {
LoginRequest request = new LoginRequest();
request.username = "admin";
request.password = "admin123";
given()
.contentType(ContentType.JSON)
.body(request)
.when().post("/api/auth/login")
.then()
.statusCode(200)
.body("access_token", notNullValue())
.body("refresh_token", notNullValue());
}
public void testLoginWithInvalidCredentials() {
LoginRequest request = new LoginRequest();
request.username = "admin";
request.password = "wrongpassword";
given()
.contentType(ContentType.JSON)
.body(request)
.when().post("/api/auth/login")
.then()
.statusCode(401);
}
}
`,
'src/native-test/java/{{packagePath}}/NativeUserResourceIT.java': `package {{packageName}};
import io.quarkus.test.junit.QuarkusIntegrationTest;
public class NativeUserResourceIT extends UserResourceTest {
// Execute the same tests but in native mode
}
`,
'.gitignore': `# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
release.properties
# Eclipse
.project
.classpath
.settings/
bin/
# IntelliJ
.idea
*.ipr
*.iml
*.iws
# NetBeans
nb-configuration.xml
# Visual Studio Code
.vscode
.factorypath
# OSX
.DS_Store
# Vim
*.swp
*.swo
# patch
*.orig
*.rej
# Local environment
.env
# Quarkus
.quarkus/
`,
'Dockerfile': `####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./mvnw package
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/{{serviceName}}-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p {{port}}:{{port}} quarkus/{{serviceName}}-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE {{port}} 5005
#
# Then run the container using :
#
# docker run -i --rm -p {{port}}:{{port}} -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/{{serviceName}}-jvm
#
###
FROM registry.access.redhat.com/ubi8/openjdk-17:1.16
ENV LANGUAGE='en_US:en'
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=185 target/quarkus-app/*.jar /deployments/
COPY --chown=185 target/quarkus-app/app/ /deployments/app/
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE {{port}}
USER 185
ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
`,
'Dockerfile.native': `####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
#
# Before building the container image run:
#
# ./mvnw package -Pnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/{{serviceName}} .
#
# Then run the container using:
#
# docker run -i --rm -p {{port}}:{{port}} quarkus/{{serviceName}}
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE {{port}}
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
`,
'docker-compose.yml': `version: '3.8'
services:
app:
build: .
ports:
- "{{port}}:{{port}}"
environment:
- QUARKUS_PROFILE=prod
- DB_HOST=postgres
- DB_PORT=5432
- DB_NAME={{serviceName}}_db
- DB_USERNAME=postgres
- DB_PASSWORD=postgres
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- app-network
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_DB={{serviceName}}_db
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
volumes:
postgres_data:
networks:
app-network:
driver: bridge
`,
'README.md': `# {{serviceName}}
{{description}}
## ๐ Quick Start
### Prerequisites
- Java 17+
- Maven 3.8+
- PostgreSQL 15+
- Redis 7+
- GraalVM (optional, for native builds)
### Running in Development Mode
\`\`\`bash
./mvnw quarkus:dev
\`\`\`
Your application is now running at http://localhost:{{port}}
### Running with Docker
\`\`\`bash
docker-compose up
\`\`\`
## ๐งช Testing
Run all tests:
\`\`\`bash
./mvnw test
\`\`\`
Run integration tests:
\`\`\`bash
./mvnw verify
\`\`\`
## โก Building Native Image
\`\`\`bash
# Build native executable
./mvnw package -Pnative
# Build Docker image with native executable
docker build -f Dockerfile.native -t {{serviceName}}:native .
# Run native Docker container
docker run -i --rm -p {{port}}:{{port}} {{serviceName}}:native
\`\`\`
## ๐ API Documentation
- Swagger UI: http://localhost:{{port}}/q/swagger-ui
- OpenAPI Spec: http://localhost:{{port}}/q/openapi
## ๐ Security
This application uses JWT for authentication:
1. Register: \`POST /api/auth/register\`
2. Login: \`POST /api/auth/login\`
3. Use the token in \`Authorization: Bearer <token>\` header
## ๐ Monitoring
- Health: http://localhost:{{port}}/q/health
- Metrics: http://localhost:{{port}}/q/metrics
- Ready: http://localhost:{{port}}/q/health/ready
- Live: http://localhost:{{port}}/q/health/live
## ๐๏ธ Architecture
- **Framework**: Quarkus 3.6
- **Security**: JWT with SmallRye JWT
- **Database**: PostgreSQL with Hibernate ORM Panache
- **Caching**: Redis
- **Migrations**: Flyway
- **API Documentation**: SmallRye OpenAPI
- **Testing**: JUnit 5, RestAssured, Mockito
## ๐ Features
- โก Super-fast startup time
- ๐ฅ Live reload in development
- ๐ฆพ Native compilation with GraalVM
- ๐ JWT authentication
- ๐ Built-in health checks and metrics
- ๐ Reactive programming support
- ๐งช Comprehensive test coverage
- ๐ Auto-generated API documentation
`
}
};