Skip to content

Commit

Permalink
Merge branch 'release/0.8.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurentTreguier committed Nov 3, 2024
2 parents 6300922 + d98e08b commit 2e7d829
Show file tree
Hide file tree
Showing 35 changed files with 315 additions and 167 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ group = "app.fyreplace"
version = gitVersion()

repositories {
maven { url "https://www.javaxt.com/maven/" }
mavenCentral()
mavenLocal()
}
Expand Down Expand Up @@ -47,6 +48,7 @@ dependencies {
implementation("io.quarkus:quarkus-smallrye-openapi")
implementation("io.quarkiverse.amazonservices:quarkus-amazon-s3")
implementation("io.sentry:sentry-jul")
implementation("javaxt:javaxt-core:${javaXtVersion}")
implementation("software.amazon.awssdk:url-connection-client")
implementation("software.amazon.awssdk.crt:aws-crt")
implementation("com.twelvemonkeys.imageio:imageio-webp:${twelveMonkeysVersion}")
Expand Down
11 changes: 6 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
org.gradle.jvmargs=-Xmx1024M
quarkusPlatformVersion=3.14.4
quarkusPluginVersion=3.14.4
sentryVersion=7.14.0
twelveMonkeysVersion=3.11.0
quarkusPlatformVersion=3.16.1
quarkusPluginVersion=3.16.1
sentryVersion=7.16.0
javaXtVersion=2.1.9
twelveMonkeysVersion=3.12.0
spotlessPluginVersion=6.25.0
lombokPluginVersion=8.10
lombokPluginVersion=8.10.2
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 1 addition & 1 deletion quarkus-sentry/deployment/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ dependencies {
implementation("io.quarkus:quarkus-arc-deployment")
implementation("io.quarkus:quarkus-core-deployment")
implementation("io.quarkus:quarkus-opentelemetry-deployment")
implementation("io.quarkus:quarkus-resteasy-reactive-deployment")
implementation("io.quarkus:quarkus-rest-deployment")
implementation(project(":quarkus-sentry:runtime"))
}
2 changes: 1 addition & 1 deletion quarkus-sentry/runtime/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {
dependencies {
implementation("io.quarkus:quarkus-arc")
implementation("io.quarkus:quarkus-core")
implementation("io.quarkus:quarkus-resteasy-reactive")
implementation("io.quarkus:quarkus-rest")
implementation("io.sentry:sentry-jul")
implementation("io.opentelemetry.instrumentation:opentelemetry-jdbc")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
package app.fyreplace.api.sentry.config;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import java.util.Optional;

@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = "sentry")
public final class SentryConfig {
@ConfigMapping(prefix = "quarkus.sentry")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface SentryConfig {
/**
* Sentry Data Source Name.
*/
@ConfigItem
public Optional<String> dsn = Optional.empty();
Optional<String> dsn();

/**
* Environment the events are tagged with.
*/
@ConfigItem
public Optional<String> environment = Optional.empty();
Optional<String> environment();

/**
* Percentage of performance events sent to Sentry.
*/
@ConfigItem(defaultValue = "0.0")
public Optional<Double> tracesSampleRate = Optional.empty();
@WithDefault("0.0")
Optional<Double> tracesSampleRate();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
@Recorder
public class SentryRecorder {
public RuntimeValue<Optional<Handler>> create(final SentryConfig sentryConfig) {
if (sentryConfig.dsn.isEmpty()) {
if (sentryConfig.dsn().isEmpty()) {
return new RuntimeValue<>(Optional.empty());
}

Expand All @@ -27,9 +27,9 @@ public RuntimeValue<Optional<Handler>> create(final SentryConfig sentryConfig) {
final var options = new AtomicReference<SentryOptions>();

Sentry.init(it -> {
sentryConfig.dsn.ifPresent(it::setDsn);
sentryConfig.environment.ifPresent(it::setEnvironment);
sentryConfig.tracesSampleRate.ifPresent(it::setTracesSampleRate);
sentryConfig.dsn().ifPresent(it::setDsn);
sentryConfig.environment().ifPresent(it::setEnvironment);
sentryConfig.tracesSampleRate().ifPresent(it::setTracesSampleRate);
it.setRelease(appName + '@' + appVersion);
it.addInAppInclude("app.fyreplace.api");
it.setInstrumenter(Instrumenter.OTEL);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/app/fyreplace/api/data/CommentCreation.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package app.fyreplace.api.data;

import app.fyreplace.api.data.validators.Length;
import jakarta.validation.constraints.NotBlank;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.hibernate.validator.constraints.Length;

public record CommentCreation(
@Length(min = 1, max = Comment.TEXT_MAX_LENGTH)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/app/fyreplace/api/data/EmailActivation.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package app.fyreplace.api.data;

import app.fyreplace.api.data.validators.Length;
import jakarta.validation.constraints.NotBlank;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.hibernate.validator.constraints.Length;

public record EmailActivation(
@NotBlank
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/app/fyreplace/api/data/EmailCreation.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package app.fyreplace.api.data;

import app.fyreplace.api.data.validators.Length;
import jakarta.validation.constraints.NotBlank;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.hibernate.validator.constraints.Length;

public record EmailCreation(
@NotBlank
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/app/fyreplace/api/data/NewTokenCreation.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package app.fyreplace.api.data;

import app.fyreplace.api.data.validators.Length;
import jakarta.validation.constraints.NotBlank;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.hibernate.validator.constraints.Length;

public record NewTokenCreation(
@NotBlank @Length(max = Email.EMAIL_MAX_LENGTH) @Schema(maxLength = Email.EMAIL_MAX_LENGTH)
Expand Down
38 changes: 18 additions & 20 deletions src/main/java/app/fyreplace/api/data/StoredFile.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package app.fyreplace.api.data;

import app.fyreplace.api.services.MimeTypeService;
import app.fyreplace.api.services.ImageService;
import app.fyreplace.api.services.StorageService;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
Expand All @@ -10,13 +10,14 @@
import jakarta.annotation.Nullable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.PostPersist;
import jakarta.persistence.PreRemove;
import jakarta.persistence.PostRemove;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.UUID;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

@Entity
Expand All @@ -26,7 +27,7 @@ public class StoredFile extends EntityBase {
private StorageService storageService;

@Transient
private MimeTypeService mimeTypeService;
private ImageService imageService;

@Column(unique = true, nullable = false)
@Schema(required = true)
Expand All @@ -42,9 +43,12 @@ public StoredFile() {
initServices();
}

public StoredFile(final String directory, final String name, @Nullable final byte[] data) {
public StoredFile(final String directory, @Nullable final byte[] data) {
initServices();
this.path = Paths.get(directory, name) + "." + mimeTypeService.getExtension(data);
this.path = UriBuilder.fromPath(directory)
.path(UUID.randomUUID() + "." + imageService.getExtension(data))
.build()
.getPath();
this.data = data;
}

Expand All @@ -58,32 +62,26 @@ public String toString() {
}
}

public void store(final byte[] data) throws IOException {
if (data != null) {
storageService.store(path, data);
}
}

@SuppressWarnings("unused")
@PostPersist
final void postPersist() throws IOException {
@PrePersist
final void prePersist() throws IOException {
if (data != null) {
store(data);
storageService.store(path, data);
data = null;
}
}

@SuppressWarnings("unused")
@PreRemove
final void preDestroy() throws IOException {
@PostRemove
final void postRemove() throws IOException {
storageService.remove(path);
}

private void initServices() {
try (final var storage = Arc.container().instance(StorageService.class);
final var mimeType = Arc.container().instance(MimeTypeService.class)) {
final var mimeType = Arc.container().instance(ImageService.class)) {
storageService = storage.get();
mimeTypeService = mimeType.get();
imageService = mimeType.get();
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/app/fyreplace/api/data/TokenCreation.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package app.fyreplace.api.data;

import app.fyreplace.api.data.validators.Length;
import jakarta.validation.constraints.NotBlank;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.hibernate.validator.constraints.Length;

public record TokenCreation(
@NotBlank @Length(max = Email.EMAIL_MAX_LENGTH) @Schema(maxLength = Email.EMAIL_MAX_LENGTH) String identifier,
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/app/fyreplace/api/data/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class User extends UserDependentEntityBase implements Reportable {
"authors",
"fyreplace",
"fyreplaces",
"guest",
"guests",
"management",
"managements",
"manager",
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/app/fyreplace/api/data/UserCreation.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package app.fyreplace.api.data;

import app.fyreplace.api.data.validators.Length;
import app.fyreplace.api.data.validators.Regex;
import jakarta.validation.constraints.NotBlank;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.hibernate.validator.constraints.Length;

public record UserCreation(
@NotBlank
Expand Down
34 changes: 22 additions & 12 deletions src/main/java/app/fyreplace/api/data/dev/DataSeeder.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import app.fyreplace.api.data.Subscription;
import app.fyreplace.api.data.User;
import app.fyreplace.api.data.Vote;
import io.quarkus.elytron.security.common.BcryptUtil;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
import jakarta.enterprise.context.ApplicationScoped;
Expand Down Expand Up @@ -46,8 +47,9 @@ public void onShutdown(@Observes final ShutdownEvent event) {

@Transactional
public void insertData() {
range(0, 20).forEach(i -> createUser("user_" + i, true, i % 2 == 0));
range(0, 10).forEach(i -> createUser("user_inactive_" + i, false, false));
createUser("demo", true, false, true);
range(0, 20).forEach(i -> createUser("user_" + i, true, i % 2 == 0, false));
range(0, 10).forEach(i -> createUser("user_inactive_" + i, false, false, false));
final var user = User.findByUsername("user_0");
range(0, 20).forEach(i -> createPost(user, "Post " + i, true, false));
range(0, 20).forEach(i -> createPost(user, "Draft " + i, false, false));
Expand Down Expand Up @@ -76,16 +78,17 @@ public void deleteData() {
}

@Transactional(Transactional.TxType.REQUIRES_NEW)
public User createUser(final String username, final boolean active, final boolean hasAvatar) {
public User createUser(
final String username, final boolean active, final boolean hasAvatar, final boolean usesPassword) {
final var user = new User();
user.username = username;
user.active = active;
user.persist();

if (hasAvatar) {
try (final var stream = getClass().getResourceAsStream("/META-INF/resources/images/logo-maskable.png")) {
final var storedFile = new StoredFile(
"avatars", user.username, requireNonNull(stream).readAllBytes());
final var storedFile =
new StoredFile("avatars", requireNonNull(stream).readAllBytes());
storedFile.persist();
user.avatar = storedFile;
user.persist();
Expand All @@ -94,14 +97,21 @@ public User createUser(final String username, final boolean active, final boolea
}
}

final var email = new Email();
email.user = user;
email.email = username + "@example.org";
email.verified = active;
email.persist();
if (usesPassword) {
final var password = new Password();
password.user = user;
password.password = BcryptUtil.bcryptHash(username + "_password");
password.persist();
} else {
final var email = new Email();
email.user = user;
email.email = username + "@example.org";
email.verified = active;
email.persist();
user.mainEmail = email;
user.persist();
}

user.mainEmail = email;
user.persist();
return user;
}

Expand Down
26 changes: 26 additions & 0 deletions src/main/java/app/fyreplace/api/data/validators/Length.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package app.fyreplace.api.data.validators;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@SuppressWarnings("unused")
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
@Constraint(validatedBy = LengthValidator.class)
public @interface Length {
String message() default "does not meet length requirements";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

int min() default 0;

int max() default Integer.MAX_VALUE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package app.fyreplace.api.data.validators;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

public final class LengthValidator implements ConstraintValidator<Length, String> {
private int min;
private int max;

@Override
public void initialize(final Length constraintAnnotation) {
min = constraintAnnotation.min();
max = constraintAnnotation.max();
}

@Override
public boolean isValid(final String value, final ConstraintValidatorContext context) {
final var count = value.codePointCount(0, value.length());
return count >= min && count <= max;
}
}
Loading

0 comments on commit 2e7d829

Please sign in to comment.