import project
This commit is contained in:
11
src/main/java/org/acme/CollectEvent.java
Normal file
11
src/main/java/org/acme/CollectEvent.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package org.acme;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface CollectEvent extends Serializable {
|
||||
Type getType();
|
||||
|
||||
enum Type {
|
||||
CREATION, UPDATE, DELETE;
|
||||
}
|
||||
}
|
||||
30
src/main/java/org/acme/EventCollector.java
Normal file
30
src/main/java/org/acme/EventCollector.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
16
src/main/java/org/acme/ExampleResource.java
Normal file
16
src/main/java/org/acme/ExampleResource.java
Normal 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";
|
||||
}
|
||||
}
|
||||
32
src/main/java/org/acme/HibernateEventListenerIntegrator.java
Normal file
32
src/main/java/org/acme/HibernateEventListenerIntegrator.java
Normal 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) {
|
||||
}
|
||||
|
||||
}
|
||||
63
src/main/java/org/acme/User.java
Normal file
63
src/main/java/org/acme/User.java
Normal 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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
52
src/main/java/org/acme/UserCreated.java
Normal file
52
src/main/java/org/acme/UserCreated.java
Normal 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 +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
46
src/main/java/org/acme/UserDTO.java
Normal file
46
src/main/java/org/acme/UserDTO.java
Normal 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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
52
src/main/java/org/acme/UserDeleted.java
Normal file
52
src/main/java/org/acme/UserDeleted.java
Normal 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 +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
72
src/main/java/org/acme/UserEventListener.java
Normal file
72
src/main/java/org/acme/UserEventListener.java
Normal 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");
|
||||
}
|
||||
|
||||
}
|
||||
30
src/main/java/org/acme/UserObserver.java
Normal file
30
src/main/java/org/acme/UserObserver.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
37
src/main/java/org/acme/UserResource.java
Normal file
37
src/main/java/org/acme/UserResource.java
Normal 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();
|
||||
}
|
||||
}
|
||||
64
src/main/java/org/acme/UserService.java
Normal file
64
src/main/java/org/acme/UserService.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user