CAS 7.0.0-RC9 combining cas-server-support-electrofence with cas-server-support-events-jpa

252 views
Skip to first unread message

Michał Nowakowski

unread,
Nov 28, 2023, 8:25:32 AM11/28/23
to CAS Community
I seem to have an issue with 7.0.0-RC9 when combining
cas-server-support-electrofence with cas-server-support-events-jpa.

Example build: here;

Example configuration:

cas.events.jpa.driverClass=org.postgresql.Driver
cas.events.jpa.dialect=org.hibernate.community.dialect.PostgreSQL95Dialect
cas.events.jpa.url=jdbc:postgresql://localhost/cas7
cas.events.jpa.user=CONFIGURE
cas.events.jpa.password=CONFIGURE
cas.service-registry.json.location=file:///etc/cas/config/services

At specified json location, there needs to be a JSON service,
I used the example one from https://apereo.github.io/cas/development/services/JSON-Service-Management.html

When I log in with default user and password, I get thrown back to login page. In logs, I can see WARN messages:

2023-11-28 09:44:29,314 WARN [org.apereo.cas.web.flow.resolver.impl.DefaultCasDelegatingWebflowEventResolver] - <No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 2: ticketTransactionManager,transactionManagerEvents
DefaultListableBeanFactory.java:resolveNamedBean:1310
DefaultListableBeanFactory.java:resolveBean:484
DefaultListableBeanFactory.java:getBean:339
2023-11-28 09:44:29,314 WARN [org.apereo.cas.web.flow.resolver.impl.DefaultCasDelegatingWebflowEventResolver] - <No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 2: ticketTransactionManager,transactionManagerEvents
DefaultListableBeanFactory.java:resolveNamedBean:1310
DefaultListableBeanFactory.java:resolveBean:484
DefaultListableBeanFactory.java:getBean:339

This seems to happen in the last line of BaseAuthenticationRequestRiskCalculator:getCasTicketGrantingTicketCreatedEventsFor().
When I remove electrofence from gradle file, I get the expected result, which is a "service not allowed" message.

It seemed to me like `@Transactional(readOnly = true)` annotations in JpaCasEventRepository (it's the only place I can
see this exact form of them) do not cooperate transactionManager parameter from @Transactional at the top of the class.
Hovewer, adding transactionManager to every @Transactional there doesn't fix the issue, only messages differ:

2023-11-28 11:26:44,019 WARN [org.apereo.cas.web.flow.resolver.impl.DefaultCasDelegatingWebflowEventResolver] - <org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@21eae802 is closed
AbstractLogicalConnectionImplementor.java:errorIfClosed:37
LogicalConnectionManagedImpl.java:getPhysicalConnection:142
StatementPreparerImpl.java:connection:54
2023-11-28 11:26:44,019 WARN [org.apereo.cas.web.flow.resolver.impl.DefaultCasDelegatingWebflowEventResolver] - <org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@21eae802 is closed
AbstractLogicalConnectionImplementor.java:errorIfClosed:37
LogicalConnectionManagedImpl.java:getPhysicalConnection:142
StatementPreparerImpl.java:connection:54


What am I doing wrong?

Kind regards,
Michał Nowakowski

Mohamed Amdouni

unread,
Nov 28, 2023, 9:46:09 AM11/28/23
to cas-...@apereo.org
Hello,

Would you please share the whole trace with caused by etc.

I think it’s similar to what I have encountered using two jpa module : see my question about a similar error.

I think that it’s a bug in cas because it should use a default Primary transaction manager when a spring integration default class uses @Transactional without qualifier.
 But better share your complete trace to check.

Best regards.

--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/6a4a70cc-80fd-4836-beb0-029dd70a2807n%40apereo.org.

Michał Nowakowski

unread,
Nov 29, 2023, 10:06:14 AM11/29/23
to CAS Community
Hello,

The stacktrace doesn't get printed to logs, but I got it with a debugger. Please see the attachment.

Also, I simplified my example a bit too much, there has to be at least one risk calculator enabled for error to occur. I use:

cas.authn.adaptive.risk.ip.enabled=true


Kind regards,

Michał Nowakowski
stacktrace.txt.zip

Mohamed Amdouni

unread,
Nov 30, 2023, 4:29:16 AM11/30/23
to cas-...@apereo.org
Hello,

Your case is different from mine. Don't find an explanation why it returns 2 transactionManagers especially if you annotated the methods with the Qualifier...

What if you add a @Primary TransactionManager bean, so it will be called if there are more than one TransactionManager retreived...

Best regards. 

Michał Nowakowski

unread,
Nov 30, 2023, 11:02:39 PM11/30/23
to CAS Community
Hello,

I see I misunderstood. The stacktrace I posted earlier was for unmodified code.

Attached is another stacktrace, obtained after replacing all @Transactional(readOnly = true) with
@Transactional(transactionManager = "transactionManagerEvents", readOnly = true). The transaction manager seems to be selected
correctly this time, JpaCasEventRepository:getEventsOfTypeForPrincipal() executes and returns a stream without throwing an exception,
but a new one is thrown in BaseAuthenticationRequestRiskCalculator:calculate(), when the results are to be collected in this line:

val events = getCasTicketGrantingTicketCreatedEventsFor(principal.getId()).collect(Collectors.toList());

This also seems to happen when I delete the @Transactional(readOnly = true) lines altogether.
I suspected I configured jpa wrongly, but when I drop tables cas_event and events_properties
add ddlAuto=create and run again, these tables get created. I have no idea for this one.

Kind regards,
Michał Nowakowski
stacktrace2.txt.zip

Michał Nowakowski

unread,
Dec 7, 2023, 5:50:15 AM12/7/23
to CAS Community, Michał Nowakowski
Hello,

I think I found something.

In JpaCasEventRepository, not only is disambiguation of TransactionManager necessary,
but also the queries need to be somehow rewritten to actually retrieve data before the transaction and connection are closed.
Or the TransactionManager's scope need to be extended to cover where the data are retrieved, namely to calculators and evaluator.
An ugly and overly extensive hack I tried was to rewrite CasEventRepository's methods to return Lists, not Streams of events. It worked.
I guess simply collecting the streams to list and streaming anew before returning would also work while being much less invasive.
I did not try tinkering TransactionManager's scope and I'm afraid I don't know how You would like handle this.

Kind regards,
Michał Nowakowski
Reply all
Reply to author
Forward
0 new messages