import project

This commit is contained in:
Fabio Scotto di Santolo
2023-10-01 14:26:53 +02:00
parent 007b7f2dcc
commit 82e0977599
30 changed files with 2066 additions and 1 deletions

View File

@@ -0,0 +1,97 @@
####
# 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/cdc-demo-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/cdc-demo-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
# when running the container
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 quarkus/cdc-demo-jvm
#
# This image uses the `run-java.sh` script to run the application.
# This scripts computes the command line to execute your Java application, and
# includes memory/GC tuning.
# You can configure the behavior using the following environment properties:
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
# in JAVA_OPTS (example: "-Dsome.property=foo")
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
# used to calculate a default maximal heap memory based on a containers restriction.
# If used in a container without any memory constraints for the container then this
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
# of the container available memory as set here. The default is `50` which means 50%
# of the available memory is used as an upper boundary. You can skip this mechanism by
# setting this value to `0` in which case no `-Xmx` option is added.
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
# is used to calculate a default initial heap memory based on the maximum heap memory.
# If used in a container without any memory constraints for the container then this
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
# is used as the initial heap size. You can skip this mechanism by setting this value
# to `0` in which case no `-Xms` option is added (example: "25")
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
# This is used to calculate the maximum value of the initial heap memory. If used in
# a container without any memory constraints for the container then this option has
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
# here. The default is 4096MB which means the calculated value of `-Xms` never will
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
# when things are happening. This option, if set to true, will set
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
# true").
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
# (example: "20")
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
# (example: "40")
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
# (example: "4")
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
# previous GC times. (example: "90")
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
# contain the necessary JRE command-line options to specify the required GC, which
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
# accessed directly. (example: "foo.example.com,bar.example.com")
#
###
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 8080
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"
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]

View File

@@ -0,0 +1,93 @@
####
# 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 -Dquarkus.package.type=legacy-jar
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/cdc-demo-legacy-jar .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/cdc-demo-legacy-jar
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
# when running the container
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 quarkus/cdc-demo-legacy-jar
#
# This image uses the `run-java.sh` script to run the application.
# This scripts computes the command line to execute your Java application, and
# includes memory/GC tuning.
# You can configure the behavior using the following environment properties:
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
# in JAVA_OPTS (example: "-Dsome.property=foo")
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
# used to calculate a default maximal heap memory based on a containers restriction.
# If used in a container without any memory constraints for the container then this
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
# of the container available memory as set here. The default is `50` which means 50%
# of the available memory is used as an upper boundary. You can skip this mechanism by
# setting this value to `0` in which case no `-Xmx` option is added.
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
# is used to calculate a default initial heap memory based on the maximum heap memory.
# If used in a container without any memory constraints for the container then this
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
# is used as the initial heap size. You can skip this mechanism by setting this value
# to `0` in which case no `-Xms` option is added (example: "25")
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
# This is used to calculate the maximum value of the initial heap memory. If used in
# a container without any memory constraints for the container then this option has
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
# here. The default is 4096MB which means the calculated value of `-Xms` never will
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
# when things are happening. This option, if set to true, will set
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
# true").
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
# (example: "20")
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
# (example: "40")
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
# (example: "4")
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
# previous GC times. (example: "90")
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
# contain the necessary JRE command-line options to specify the required GC, which
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
# accessed directly. (example: "foo.example.com,bar.example.com")
#
###
FROM registry.access.redhat.com/ubi8/openjdk-17:1.16
ENV LANGUAGE='en_US:en'
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/quarkus-run.jar
EXPOSE 8080
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"
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]

View File

@@ -0,0 +1,27 @@
####
# 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 -Dnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/cdc-demo .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/cdc-demo
#
###
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 8080
USER 1001
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]

View File

@@ -0,0 +1,30 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
# It uses a micro base image, tuned for Quarkus native executables.
# It reduces the size of the resulting container image.
# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
#
# Before building the container image run:
#
# ./mvnw package -Dnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/cdc-demo .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/cdc-demo
#
###
FROM quay.io/quarkus/quarkus-micro-image:2.0
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]

View File

@@ -0,0 +1,11 @@
package org.acme;
import java.io.Serializable;
public interface CollectEvent extends Serializable {
Type getType();
enum Type {
CREATION, UPDATE, DELETE;
}
}

View File

@@ -0,0 +1,30 @@
package org.acme;
import jakarta.enterprise.context.RequestScoped;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
@RequestScoped
public class EventCollector {
private final Map<String, Collection<CollectEvent>> cache;
public EventCollector() {
cache = new HashMap<>();
}
public void register(String type, CollectEvent event) {
if (!cache.containsKey(type)) {
cache.put(type, new ArrayList<>());
}
cache.get(type).add(event);
}
public Stream<CollectEvent> stream(String type) {
return cache.get(type).stream();
}
}

View File

@@ -0,0 +1,16 @@
package org.acme;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class ExampleResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from RESTEasy Reactive";
}
}

View File

@@ -0,0 +1,32 @@
package org.acme;
import io.quarkus.runtime.Startup;
import jakarta.enterprise.context.ApplicationScoped;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.jboss.logging.Logger;
@Startup
@ApplicationScoped
public class HibernateEventListenerIntegrator implements Integrator {
private final Logger log = Logger.getLogger(HibernateEventListenerIntegrator.class);
@Override
public void integrate(Metadata metadata, BootstrapContext bootstrapContext, SessionFactoryImplementor sessionFactory) {
log.info("Integrate registry");
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
registry.appendListeners(EventType.POST_COMMIT_INSERT, UserEventListener.class);
registry.appendListeners(EventType.POST_COMMIT_UPDATE, UserEventListener.class);
registry.appendListeners(EventType.POST_COMMIT_DELETE, UserEventListener.class);
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {
}
}

View File

@@ -0,0 +1,63 @@
package org.acme;
import io.quarkus.hibernate.orm.panache.PanacheEntity;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "users")
public class User extends PanacheEntity {
@Column(name = "name", unique = true)
private String name;
@Column(name = "passwd")
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(getId(), user.getId()) && Objects.equals(getName(), user.getName()) && Objects.equals(getPassword(), user.getPassword());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getName(), getPassword());
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}

View File

@@ -0,0 +1,52 @@
package org.acme;
import java.time.LocalDateTime;
import java.util.Objects;
public class UserCreated implements CollectEvent {
private String username;
private LocalDateTime timestamp;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
@Override
public CollectEvent.Type getType() {
return Type.CREATION;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserCreated that = (UserCreated) o;
return Objects.equals(getUsername(), that.getUsername()) && Objects.equals(getTimestamp(), that.getTimestamp());
}
@Override
public int hashCode() {
return Objects.hash(getUsername(), getTimestamp());
}
@Override
public String toString() {
return "UserCreated{" +
"username='" + username + '\'' +
", timestamp=" + timestamp +
'}';
}
}

View File

@@ -0,0 +1,46 @@
package org.acme;
import java.util.Objects;
public class UserDTO {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserDTO userDTO = (UserDTO) o;
return Objects.equals(getName(), userDTO.getName()) && Objects.equals(getPassword(), userDTO.getPassword());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getPassword());
}
@Override
public String toString() {
return "UserDTO{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}

View File

@@ -0,0 +1,52 @@
package org.acme;
import java.time.LocalDateTime;
import java.util.Objects;
public class UserDeleted implements CollectEvent {
private long id;
private LocalDateTime timestamp;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
@Override
public CollectEvent.Type getType() {
return Type.DELETE;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserDeleted that = (UserDeleted) o;
return getId() == that.getId() && Objects.equals(getTimestamp(), that.getTimestamp());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getTimestamp());
}
@Override
public String toString() {
return "UserDeleted{" +
"id=" + id +
", timestamp=" + timestamp +
'}';
}
}

View File

@@ -0,0 +1,72 @@
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.hibernate.event.spi.*;
import org.hibernate.persister.entity.EntityPersister;
import org.jboss.logging.Logger;
import java.util.List;
import java.util.stream.Collectors;
@ApplicationScoped
public class UserEventListener implements PostCommitInsertEventListener, PostCommitUpdateEventListener, PostCommitDeleteEventListener {
private final Logger log = Logger.getLogger(UserEventListener.class);
private final EventCollector eventCollector;
@Inject
public UserEventListener(EventCollector eventCollector) {
this.eventCollector = eventCollector;
}
@Override
public void onPostInsert(PostInsertEvent postInsertEvent) {
log.info("onPostInsert called");
List<CollectEvent> events = eventCollector.stream(User.class.getCanonicalName())
.filter(it -> it.getType() == CollectEvent.Type.CREATION)
.collect(Collectors.toUnmodifiableList());
log.info("fire " + events.size() + " events");
}
@Override
public void onPostUpdate(PostUpdateEvent postUpdateEvent) {
log.info("onPostUpdate called");
List<CollectEvent> events = eventCollector.stream(User.class.getCanonicalName())
.filter(it -> it.getType() == CollectEvent.Type.UPDATE)
.collect(Collectors.toUnmodifiableList());
log.info("fire " + events.size() + " events");
}
@Override
public void onPostDelete(PostDeleteEvent postDeleteEvent) {
log.info("onPostDelete called");
List<CollectEvent> events = eventCollector.stream(User.class.getCanonicalName())
.filter(it -> it.getType() == CollectEvent.Type.DELETE)
.collect(Collectors.toUnmodifiableList());
log.info("fire " + events.size() + " events");
}
@Override
public boolean requiresPostCommitHandling(EntityPersister entityPersister) {
return true;
}
@Override
public void onPostDeleteCommitFailed(PostDeleteEvent postDeleteEvent) {
log.info("onPostDeleteCommitFailed called");
}
@Override
public void onPostInsertCommitFailed(PostInsertEvent postInsertEvent) {
log.info("onPostInsertCommitFailed called");
}
@Override
public void onPostUpdateCommitFailed(PostUpdateEvent postUpdateEvent) {
log.info("onPostUpdateCommitFailed called");
}
}

View File

@@ -0,0 +1,30 @@
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.event.TransactionPhase;
import jakarta.inject.Inject;
import org.jboss.logging.Logger;
@ApplicationScoped
public class UserObserver {
private final Logger log = Logger.getLogger(UserObserver.class);
private final EventCollector eventCollector;
@Inject
public UserObserver(EventCollector eventCollector) {
this.eventCollector = eventCollector;
}
public void onCreation(@Observes(during = TransactionPhase.AFTER_SUCCESS) UserCreated event) {
log.info("Arrived event for user " + event.getUsername());
eventCollector.register(User.class.getCanonicalName(), event);
}
public void onDelete(@Observes(during = TransactionPhase.AFTER_SUCCESS) UserDeleted event) {
log.info("Arrived event for deletion user " + event.getId());
eventCollector.register(User.class.getCanonicalName(), event);
}
}

View File

@@ -0,0 +1,37 @@
package org.acme;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody;
import java.util.Collection;
@Path(("/users"))
public class UserResource {
private final UserService userService;
@Inject
public UserResource(UserService userService) {
this.userService = userService;
}
@GET
public Response users() {
Collection<UserDTO> users = userService.getUsers();
return Response.ok(users).build();
}
@POST
public Response createUser(@RequestBody UserDTO user) {
userService.createUser(user);
return Response.ok().build();
}
@DELETE
@Path("/{id}")
public Response deleteUser(@PathParam("id") Long id) {
userService.deleteUser(id);
return Response.ok().build();
}
}

View File

@@ -0,0 +1,64 @@
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Event;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import org.jboss.logging.Logger;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.stream.Collectors;
@ApplicationScoped
public class UserService {
private final Logger log = Logger.getLogger(UserService.class);
private final Event<CollectEvent> collectEventSender;
@Inject
public UserService(Event<CollectEvent> collectEventSender) {
this.collectEventSender = collectEventSender;
}
public Collection<UserDTO> getUsers() {
return User.<User>findAll()
.stream()
.map(it -> {
UserDTO userDTO = new UserDTO();
userDTO.setName(it.getName());
userDTO.setPassword(it.getPassword());
return userDTO;
})
.collect(Collectors.toList());
}
@Transactional
public void createUser(UserDTO user) {
User userEntity = new User();
userEntity.setName(user.getName());
userEntity.setPassword(user.getPassword());
UserCreated userCreated = new UserCreated();
userCreated.setUsername(userEntity.getName());
userCreated.setTimestamp(LocalDateTime.now());
log.info("Creation event fired");
collectEventSender.fire(userCreated);
User.persist(userEntity);
log.info("Created user " + user.getName());
}
@Transactional
public void deleteUser(Long id) {
UserDeleted userDeleted = new UserDeleted();
userDeleted.setId(id);
userDeleted.setTimestamp(LocalDateTime.now());
log.info("Delete event fired");
collectEventSender.fire(userDeleted);
User.deleteById(id);
log.info("Deleted user with id " + id);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
%dev.quarkus.datasource.db-kind=h2
%dev.quarkus.datasource.username=sa
%dev.quarkus.datasource.jdbc.url=jdbc:h2:mem:cdctest;DB_CLOSE_DELAY=-1
%dev.quarkus.datasource.jdbc.max-size=13
%dev.quarkus.hibernate-orm.database.generation=drop-and-create
%dev.quarkus.hibernate-orm.sql-load-script = import-dev.sql

View File

@@ -0,0 +1,6 @@
-- This file allow to write SQL commands that will be emitted in test and dev.
-- The commands are commented as their support depends of the database
insert into users (id, name, passwd) values(1, 'utente1', 'password');
insert into users (id, name, passwd) values(2, 'utente2', 'password');
insert into users (id, name, passwd) values(3, 'utente3', 'password');
alter sequence users_seq restart with 4;

View File

@@ -0,0 +1,8 @@
package org.acme;
import io.quarkus.test.junit.QuarkusIntegrationTest;
@QuarkusIntegrationTest
public class ExampleResourceIT extends ExampleResourceTest {
// Execute the same tests but in packaged mode.
}

View File

@@ -0,0 +1,21 @@
package org.acme;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class ExampleResourceTest {
@Test
public void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200)
.body(is("Hello from RESTEasy Reactive"));
}
}