Reputation: 1
I have an existing endpoint calling some function, and it works fine when doing a rest call to the endpoint. Then I want to create a scheduler that will call that function regularly. The scheduler itself works as expected, but now there is an unexpected exception in the function during a scheduled function. The rest of the endpoint still works. Since the problem seems to be a RequestScoped bean, I tried ActivateRequestContent, but nothing changes.
Below is minimally reproduicable example that better explain the problem.
EDIT: I don't want to modify the service or some external cron. I would prefer the solution to be within Scheduler.
I have a resource:
@Path("/hello")
public class GreetingResource {
@Inject
GreetingService greetingService;
@GET
public String hello() {
return greetingService.getGreetings();
}
}
A service:
@ApplicationScoped
public class GreetingService {
@Inject
RequestBean requestBean;
public String getGreetings() {
//do logic, call other services, save to DB, etc
if (requestBean.getAcceptLanguage().equals("en")) {
return "Hello from RESTEasy Reactive";
} else {
return "Hola desde RESTEasy Reactive";
}
}
}
And a RequestScoped bean.
@RequestScoped
public class RequestBean {
private String acceptLanguage;
RequestBean(HttpHeaders httpHeaders) {
acceptLanguage = httpHeaders.getHeaderString(HttpHeaders.ACCEPT_LANGUAGE);
if (acceptLanguage == null || acceptLanguage.isBlank()) {
this.acceptLanguage = "en";
}
}
public String getAcceptLanguage() {
return acceptLanguage;
}
}
The endpoints work in test and postman.
But now I need to do the exact same work regularly.
So I added the scheduler.
@ApplicationScoped
public class Scheduler {
@Inject
GreetingService greetingService;
@Scheduled(every = "10s")
@ActivateRequestContext
public void scheduledTask() {
try {
Log.info("Scheduler is starting");
greetingService.getGreetings();
Log.info("Scheduler is finished");
} catch (Exception e) {
Log.error("Error while running scheduler", e);
}
}
}
I expected no exception, but I got an exception inside the scheduledTask.
java.lang.IllegalStateException: No RESTEasy Reactive request in progress
at org.jboss.resteasy.reactive.server.injection.ContextProducers.getContext(ContextProducers.java:149)
at org.jboss.resteasy.reactive.server.injection.ContextProducers.headers(ContextProducers.java:52)
at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.doCreate(Unknown Source)
at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.create(Unknown Source)
at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.create(Unknown Source)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:79)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:75)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.c2(Unknown Source)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.computeIfAbsent(Unknown Source)
at io.quarkus.arc.impl.RequestContext.getIfActive(RequestContext.java:75)
at io.quarkus.arc.impl.ClientProxies.getSingleContextDelegate(ClientProxies.java:28)
at jakarta.ws.rs.core.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_ClientProxy.arc$delegate(Unknown Source)
at jakarta.ws.rs.core.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_ClientProxy.getHeaderString(Unknown Source)
at com.example.RequestBean.<init>(RequestBean.java:12)
at com.example.RequestBean_Bean.doCreate(Unknown Source)
at com.example.RequestBean_Bean.create(Unknown Source)
at com.example.RequestBean_Bean.create(Unknown Source)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:79)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:75)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.c0(Unknown Source)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.computeIfAbsent(Unknown Source)
at io.quarkus.arc.impl.RequestContext.getIfActive(RequestContext.java:75)
at io.quarkus.arc.impl.ClientProxies.getSingleContextDelegate(ClientProxies.java:28)
at com.example.RequestBean_ClientProxy.arc$delegate(Unknown Source)
at com.example.RequestBean_ClientProxy.getAcceptLanguage(Unknown Source)
at com.example.GreetingService.getGreetings(GreetingService.java:16)
at com.example.GreetingService_ClientProxy.getGreetings(Unknown Source)
at com.example.Scheduler.scheduledTask(Scheduler.java:21)
at com.example.Scheduler_Subclass.scheduledTask$$superforward(Unknown Source)
at com.example.Scheduler_Subclass$$function$$1.apply(Unknown Source)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
at io.quarkus.arc.impl.ActivateRequestContextInterceptor.invoke(ActivateRequestContextInterceptor.java:124)
at io.quarkus.arc.impl.ActivateRequestContextInterceptor.aroundInvoke(ActivateRequestContextInterceptor.java:33)
at io.quarkus.arc.impl.ActivateRequestContextInterceptor_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
at com.example.Scheduler_Subclass.scheduledTask(Unknown Source)
at com.example.Scheduler_ClientProxy.scheduledTask(Unknown Source)
at com.example.Scheduler_ScheduledInvoker_scheduledTask_b06a23f86c5479393959068a663c2a2a98c84093.invokeBean(Unknown Source)
at io.quarkus.scheduler.common.runtime.DefaultInvoker.invoke(DefaultInvoker.java:24)
at io.quarkus.scheduler.common.runtime.StatusEmitterInvoker.invoke(StatusEmitterInvoker.java:35)
at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask.doInvoke(SimpleScheduler.java:443)
at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask$2.call(SimpleScheduler.java:425)
at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask$2.call(SimpleScheduler.java:422)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$0(ContextImpl.java:178)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:279)
at io.vertx.core.impl.ContextImpl.lambda$internalExecuteBlocking$2(ContextImpl.java:210)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
Relevant dependency:
<quarkus.platform.version>3.8.5</quarkus.platform.version>
...
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
EDIT 2: Solutions that do work, but are not ok.
given()
.when()
.get("/hello")
.then()
.statusCode(200);
-> This looks very nice compared to 1-3 solutions, but having restassured import in main code feels wrong. Is it wrong?
Upvotes: 0
Views: 90
Reputation: 647
You can try to use Quarkus RestClient to access the /hello path. If you need to deal with authentication, you can do something like:
Class to access API
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.ws.rs.*;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
@RegisterRestClient
public interface Api {
@GET
@Path("/hello")
JsonNode hello(@HeaderParam("Authorization") String token);
}
And then your Scheduled thing
@RestClient
Api api;
@Scheduled(every = "10s")
void doTheJob(){
String token;
// do something to get the token
api.hello(token);
}
Upvotes: 1