apache / camel-quarkus

Apache Camel Quarkus
https://camel.apache.org
Apache License 2.0
257 stars 192 forks source link

Panache Entity not working inside routebuilder #6792

Closed Serkan80 closed 1 week ago

Serkan80 commented 1 week ago

Bug description

I want to retrieve data via MyEntity which extends Quarkus' PanacheEntity, however this doesn't work and I get the following exception:

"exception": "jakarta.enterprise.context.ContextNotActiveException", "message": "Cannot use the EntityManager/Session because neither a transaction nor a CDI request context is active. Consider adding @Transactional to your method to automatically activate a transaction, or @ActivateRequestContext if you have valid reasons not to use transactions."

Also adding @Transactional and @ActivateRequestContext on the EndpointRouteBuilder class doesn't work.

This is my code:

@ApplicationScoped
public class GatewayRoute extends EndpointRouteBuilder {

    @Override
    public void configure() {
        onException(Throwable.class)
                .handled(true)
                .process(CamelUtils::setErrorMessage)
                .end();

        //@formatter:off
        from(platformHttp("/gateway").matchOnUriPrefix(true))
                .id("gatewayRoute")
                .log(DEBUG, "incoming: ${headers}")
                .process(CamelUtils::validateUser)
                .process(CamelUtils::checkSubscription) ===> this throws the exception, see below
                .choice()
                    .when(header(CONTENT_TYPE).contains(MULTIPART_FORM_DATA.getMimeType()))
                        .process(this::multiPartProcessor)
                .end()
                .process(this::forwardUrlProcessor)
                .removeHeader(HTTP_PATH)
                .removeHeader(HTTP_URI)
                .log(DEBUG, "forwarding url: ${exchangeProperty.forwardUrl}")
                .toD("${exchangeProperty.forwardUrl}?bridgeEndpoint=true&skipRequestHeaders=true&followRedirects=true&connectionClose=true&copyHeaders=true");
        //@formatter:on
    }   
}

// CamelUtils:

   public static void checkSubscription(Exchange exchange) {
        var incomingRequest = exchange.getIn().getHeader(HTTP_URI, String.class);
        var subscriptionKey = exchange.getIn().getHeader(SUBSCRIPTION_KEY, String.class);
        var subscription = SubscriptionEntity.findByKey(subscriptionKey);  ====> Panache call
        var proxyExists = subscription.apis.stream().anyMatch(api -> incomingRequest.contains(api.mappingPrefix));

        if (!proxyExists)
            throw new UnauthorizedException("Subscriber has no authorization for %s".formatted(incomingRequest));

        exchange.getIn().setHeader("subscription", subscription);
    }

Is there a way to overcome this problem ?

jamesnetherton commented 1 week ago

Is there a way to overcome this problem ?

Write a Processor class as a CDI bean and annotate the process method with ActivateRequestContext. E.g:

@Singleton
public class SubscriptionChecker implements Processor {
    @ActivateRequestContext
    @Override
    public void process(Exchange exchange) throws Exception {
        // Your Panache calls here
    }
}

Then in the RouteBuilder class:

@Inject
SubscriptionChecker subscriptionChecker;

public void configure() {
    // Route config here...
    .process(subscriptionChecker)
}

It should work in a simlar way using named beans. The important part is that whatever you use for .bean() or .process() has to be a CDI bean.

Serkan80 commented 1 week ago

@jamesnetherton, thx your tip worked.

Maybe this should be documented somewhere, otherwise it is quite confusing to assume that all injections just work on RouteBuilders when they are annotated with @ApplicationScoped and @ActivateRequestContext.

jamesnetherton commented 1 week ago

Maybe this should be documented somewhere

I will try to add something.

jamesnetherton commented 1 week ago

Added some notes to the CDI docs here:

https://github.com/apache/camel-quarkus/blob/main/docs/modules/ROOT/pages/user-guide/cdi.adoc#cdi-contexts--contextnotactiveexception