Skip to content

Commit

Permalink
Merge pull request #30950 from manovotn/observerMethodImprovements
Browse files Browse the repository at this point in the history
Various changes to observer methods to align them with spec expectations
  • Loading branch information
manovotn authored Feb 8, 2023
2 parents e92c482 + 1361239 commit 8c1937f
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ Collection<Resource> generate(ObserverInfo observer) {

implementGetBeanClass(observerCreator, observer.getBeanClass());
implementNotify(observer, observerCreator, injectionPointToProviderField, reflectionRegistration, isApplicationClass);
if (Reception.IF_EXISTS == observer.getReception()) {
implementIfExistsGetReception(observerCreator);
}
if (observer.getPriority() != ObserverMethod.DEFAULT_PRIORITY) {
implementGetPriority(observerCreator, observer);
}
Expand Down Expand Up @@ -258,6 +261,12 @@ protected void initMaps(ObserverInfo observer, Map<InjectionPointInfo, String> i
}
}

protected void implementIfExistsGetReception(ClassCreator observerCreator) {
MethodCreator getReception = observerCreator.getMethodCreator("getReception", Reception.class)
.setModifiers(ACC_PUBLIC);
getReception.returnValue(getReception.load(Reception.IF_EXISTS));
}

protected void implementGetObservedType(ClassCreator observerCreator, FieldDescriptor observedTypeField) {
MethodCreator getObservedType = observerCreator.getMethodCreator("getObservedType", Type.class)
.setModifiers(ACC_PUBLIC);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@

import jakarta.enterprise.event.Reception;
import jakarta.enterprise.event.TransactionPhase;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.ObserverMethod;

import io.quarkus.arc.impl.EventContextImpl;
import io.quarkus.arc.impl.EventMetadataImpl;

/**
* Represents an observer method.
*
Expand All @@ -32,6 +36,16 @@ default TransactionPhase getTransactionPhase() {
return TransactionPhase.IN_PROGRESS;
}

@Override
default Bean<?> getDeclaringBean() {
return Arc.container().bean(getDeclaringBeanIdentifier());
}

default void notify(T event) {
notify(new EventContextImpl<>(event,
new EventMetadataImpl(getObservedQualifiers(), event.getClass())));
}

/**
*
* @return the identifier or null for synthetic observers
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.arc.impl;

import jakarta.enterprise.inject.spi.EventContext;
import jakarta.enterprise.inject.spi.EventMetadata;

// this class is public because it is used in io.quarkus.arc.InjectableObserverMethod
public final class EventContextImpl<T> implements EventContext<T> {

private final T payload;

private final EventMetadata metadata;

public EventContextImpl(T payload, EventMetadata metadata) {
this.payload = payload;
this.metadata = metadata;
}

@Override
public T getEvent() {
return payload;
}

@Override
public EventMetadata getMetadata() {
return metadata;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.spi.EventContext;
import jakarta.enterprise.inject.spi.EventMetadata;
import jakarta.enterprise.inject.spi.InjectionPoint;
import jakarta.enterprise.inject.spi.ObserverMethod;
import jakarta.enterprise.util.TypeLiteral;
import jakarta.transaction.RollbackException;
Expand Down Expand Up @@ -351,58 +350,6 @@ private boolean isNotTxObserver(ObserverMethod<?> observer) {

}

static class EventContextImpl<T> implements EventContext<T> {

private final T payload;

private final EventMetadata metadata;

public EventContextImpl(T payload, EventMetadata metadata) {
this.payload = payload;
this.metadata = metadata;
}

@Override
public T getEvent() {
return payload;
}

@Override
public EventMetadata getMetadata() {
return metadata;
}

}

static class EventMetadataImpl implements EventMetadata {

private final Set<Annotation> qualifiers;

private final Type eventType;

public EventMetadataImpl(Set<Annotation> qualifiers, Type eventType) {
this.qualifiers = qualifiers;
this.eventType = eventType;
}

@Override
public Set<Annotation> getQualifiers() {
return qualifiers;
}

@Override
public InjectionPoint getInjectionPoint() {
// Currently we do not support injection point of the injected Event instance which fired the event
return null;
}

@Override
public Type getType() {
return eventType;
}

}

static class ArcSynchronization implements Synchronization {

private List<DeferredEventNotification<?>> deferredEvents;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.quarkus.arc.impl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;

import jakarta.enterprise.inject.spi.EventMetadata;
import jakarta.enterprise.inject.spi.InjectionPoint;

// this class is public because it is used in io.quarkus.arc.InjectableObserverMethod
public final class EventMetadataImpl implements EventMetadata {

private final Set<Annotation> qualifiers;

private final Type eventType;

public EventMetadataImpl(Set<Annotation> qualifiers, Type eventType) {
this.qualifiers = qualifiers;
this.eventType = eventType;
}

@Override
public Set<Annotation> getQualifiers() {
return qualifiers;
}

@Override
public InjectionPoint getInjectionPoint() {
// Currently we do not support injection point of the injected Event instance which fired the event
return null;
}

@Override
public Type getType() {
return eventType;
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package io.quarkus.arc.test.observers;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.event.Event;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.ObserverMethod;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

Expand All @@ -31,6 +35,15 @@ public void testObserver() {
producer.produce("ping");
List<String> events = observer.getEvents();
assertEquals(2, events.size());

// verify we can resolve OM and check some of its metadata
Set<ObserverMethod<? super String>> foundOms = Arc.container().beanManager().resolveObserverMethods("someString");
assertEquals(1, foundOms.size());
ObserverMethod<? super String> om = foundOms.iterator().next();
Bean<?> declaringBean = om.getDeclaringBean();
assertNotNull(declaringBean);
assertEquals(StringObserver.class, declaringBean.getBeanClass());
assertEquals(Singleton.class, declaringBean.getScope());
}

@Singleton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import jakarta.annotation.Priority;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.event.Reception;
import jakarta.enterprise.inject.spi.ObserverMethod;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
Expand Down Expand Up @@ -50,6 +52,16 @@ public void testObserver() {
assertEquals(RequestScopedObserver.class.getName() + "foo", EVENTS.get(0));
assertEquals(DependentObserver.class.getName() + "foo", EVENTS.get(1));
container.requestContext().deactivate();

Set<ObserverMethod<? super String>> foundOm = Arc.container().beanManager().resolveObserverMethods("eventString");
assertEquals(2, foundOm.size());
for (ObserverMethod<? super String> om : foundOm) {
if (om.getDeclaringBean().getBeanClass().equals(RequestScopedObserver.class)) {
assertEquals(Reception.IF_EXISTS, om.getReception());
} else {
assertEquals(Reception.ALWAYS, om.getReception());
}
}
}

@RequestScoped
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.quarkus.arc.test.observers.notification;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.ObserverMethod;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;

public class ManualNotifyInvocationTest {

@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(StringObserver.class);

@Test
public void testManualNotifyInvocation() {
assertEquals(0, StringObserver.NOTIFIED.get());
Arc.container().beanManager().getEvent().fire("hello");
assertEquals(1, StringObserver.NOTIFIED.get());

Set<ObserverMethod<? super String>> foundOM = Arc.container().beanManager().resolveObserverMethods("foo");
assertEquals(1, foundOM.size());
foundOM.iterator().next().notify("test");
assertEquals(2, StringObserver.NOTIFIED.get());
}

@ApplicationScoped
static class StringObserver {
private static final AtomicInteger NOTIFIED = new AtomicInteger();

void observeString(@Observes String value) {
NOTIFIED.incrementAndGet();
}
}
}

0 comments on commit 8c1937f

Please sign in to comment.