Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(deps): upgrade to Patternfly 5 #1303

Merged
merged 24 commits into from
Sep 16, 2024
Merged

build(deps): upgrade to Patternfly 5 #1303

merged 24 commits into from
Sep 16, 2024

Conversation

andrewazores
Copy link
Member

@andrewazores andrewazores commented Jul 15, 2024

Welcome to Cryostat! 👋

Before contributing, make sure you have:

  • Read the contributing guidelines
  • Linked a relevant issue which this PR resolves
  • Linked any other relevant issues, PR's, or documentation, if any
  • Resolved all conflicts, if any
  • Rebased your branch PR on top of the latest upstream main branch
  • Attached at least one of the following labels to the PR: [chore, ci, docs, feat, fix, test]
  • Signed all commits using a GPG signature

To recreate commits with GPG signature git fetch upstream && git rebase --force --gpg-sign upstream/main


Fixes: #1110

TODO update from PF 5.1.0 to 5.3.0

Notably broken things:

  • dashboard card creation/catalog cannot progress:
    image
  • menu item for Quick Starts must be clicked on the actual text - clicking the rest of the menu item does nothing:
    image
  • about modal has strange image rendering:
    image
  • topology view has weird black/white items:
    image
    image
  • various dropdown menus are missing drop shadows and/or include odd borders
    image
  • the target context selector dropdown has a very limited height. We are using PF 5.1.0 here, but it looks like at least 5.3.0 (re)introduced a property to control this maxMenuHeight - https://www.patternfly.org/components/menus/dropdown#dropdown :
    image
  • various features in the Settings menu do not work: 1. Advanced > Feature Levels > selecting a different level causes the panel to go blank. 2. Notifications & Messages toggles do not work and emit a console warning about cyclic value. 3. Connectivity > Auto Refresh checkbox can be checked but not unchecked, but after a page refresh it goes back to unchecked. 4. General > Theme does not work.

@andrewazores andrewazores added dependencies Pull requests that update a dependency file chore Refactor, rename, cleanup, etc. safe-to-test labels Jul 15, 2024
Copy link

Hi @andrewazores! Add at least one of the required labels to this PR

Required labels are : chore,ci,cleanup,docs,feat,fix,perf,refactor,style,test

@github-actions github-actions bot added the needs-triage Needs thorough attention from code reviewers label Jul 15, 2024
Copy link

Build Error! No Linked Issue found. Please link an issue or mention it in the body using #<issue_id>

@andrewazores andrewazores changed the title build(deps): upgrade to Patternfly 5 (#1153) build(deps): upgrade to Patternfly 5 Jul 15, 2024
@andrewazores andrewazores removed the needs-triage Needs thorough attention from code reviewers label Jul 15, 2024
@andrewazores
Copy link
Member Author

Dropdown menu heights look like a PF 5.3.0 feature:

https://github.com/patternfly/patternfly-react/releases/tag/v5.3.0

feat(Dropdown): Added support for setting height for dropdown

patternfly/patternfly-react#10149

andrewazores and others added 3 commits July 30, 2024 16:13
* chore(topology): fix broken element colors

* chore(topology): fix broken topology toolbar and controlbar

* build(deps): bump pf5 deps to latest v5

* fix(topology): display options should show

* chore(topology): topology filters should close when clicking outside

* fix: node badge should show correct color

* chore: correct css var names

* fix: truncate long key/value

* fix: quicksearch modal should show

* fix: mini search menu should show

* chore: correct css var to use v5 conventions

* fix: port fixes for topology filters

* fix: decorators should show

* eslint:apply
@tthvo
Copy link
Member

tthvo commented Aug 7, 2024

about modal has strange image rendering:

I think the .png image no longer fits. We would need some new design for an .svg, specifically to render in the bottom-right of the modal. For example, this PF6 example looks rather nice.

https://staging-v6.patternfly.org/components/about-modal/react/basic/

@andrewazores
Copy link
Member Author

Ah, okay. That PNG was actually made for the upstream https://cryostat.io website and was introduced in this PR. I can ask James if he still has the design file for that and if he's able to provide an SVG version, but considering the design of it with a lot of gradient colours and texture, I don't think it will lend itself well to being vectorized.

If we can restyle the modal with some CSS to get the existing PNG to fit again, that would be great. Otherwise we might need to get a whole new SVG asset just for this background, or else simply reuse one of the SVG icons we have.

@andrewazores
Copy link
Member Author

andrewazores commented Aug 8, 2024

Actually, given the styling of the PF5 About Modal component, the right move looks like it would be to just use the Cryostat icon SVG in both locations of the modal, except a desaturated/monochrome version and maybe partially cut off or outside of the viewport.

image

https://www.patternfly.org/components/background-image

@tthvo
Copy link
Member

tthvo commented Aug 8, 2024

Actually, given the styling of the PF5 About Modal component, the right move looks like it would be to just use the Cryostat icon SVG in both locations of the modal, except a desaturated/monochrome version and maybe partially cut off or outside of the viewport.

Sounds good to me! Though, maybe James or the team can provide one here that matches the requirements above?

@andrewazores
Copy link
Member Author

I can ask. But, I'm not convinced we really need to have this. The About Modal component says that "the modal image should be the same as the background image you use for your application," but we don't use an application background image.

https://www.patternfly.org/components/about-modal/design-guidelines

@tthvo
Copy link
Member

tthvo commented Aug 9, 2024

I can ask. But, I'm not convinced we really need to have this. The About Modal component says that "the modal image should be the same as the background image you use for your application," but we don't use an application background image.

https://www.patternfly.org/components/about-modal/design-guidelines

Oh, does this mean we can remove the background for the About modal for this upgrade?

Btw, I played around with the icon a bit and get this. Just that confirmed svg is required here with either a cryostat icon or others. I can remove it the background if we decide it that way.

Editted: Updated screenshot since last comment.

image

SVG: cryostat_icon_bg.zip

@tthvo
Copy link
Member

tthvo commented Sep 6, 2024

Upgrades for QuickStarts are currently blocked by a small issue with admonition block: patternfly/patternfly-quickstarts#323.

The issue seems to be put into 2024 Q3 so hopefully it will be fixed right when we finished upgrading and fixing tests :D

@andrewazores
Copy link
Member Author

I don't think that is necessarily a blocker anyway. We have other reasons to upgrade to PF5 that are more important, so if some minor styling is missing at first, I say we go ahead regardless and let that get fixed later.

@tthvo
Copy link
Member

tthvo commented Sep 6, 2024

I think the views are pretty much in good shape now (i.e. just need to a quick check on quickstarts)? Here are the list of available tests by directory with assignments:

Just in case anyone is also fixing the tests to void duplicating work :D

Editted: All test fixes will now be included in #1347 :D

@andrewazores
Copy link
Member Author

Thanks for all your hard work on this @tthvo , I really appreciate it.

tthvo and others added 4 commits September 9, 2024 09:45
* chore(pf5): add missing buildInfo in mocked health response

Signed-off-by: Thuan Vo <[email protected]>

* fix(mirageJS): testing target def should not create target

* chore: fix type check issues

---------

Signed-off-by: Thuan Vo <[email protected]>
@andrewazores
Copy link
Member Author

@tthvo any other planned work for this PR or can I start looking to review and merge this thing? If there are any minor updates (ex. a minor or patch version upgrade for Patternfly) etc. those can be done as follow-ups.

@tthvo
Copy link
Member

tthvo commented Sep 13, 2024

I think this is ready for review, other than the @patternfly/quickstart version bump later on :D

@tthvo
Copy link
Member

tthvo commented Sep 13, 2024

We do have one issue with credential table though where credential notification returns 0 match. I found this comment from cryostat source:

https://github.com/cryostatio/cryostat/blob/317ae48a8d9593ce36d03962f09f430bd1a1cb11/src/main/java/io/cryostat/credentials/Credentials.java#L108

For the time being, is this issue tolerable? Or some workaround desired?

@andrewazores
Copy link
Member Author

We do have one issue with credential table though where credential notification returns 0 match. I found this comment from cryostat source:

https://github.com/cryostatio/cryostat/blob/317ae48a8d9593ce36d03962f09f430bd1a1cb11/src/main/java/io/cryostat/credentials/Credentials.java#L108

For the time being, is this issue tolerable? Or some workaround desired?

https://github.com/cryostatio/cryostat/pull/584/files#diff-58bcb5d27231eedec09ab4aecc0aca9cbcbc4f2b250db1ec942c7d3344ddf7a6R156

In API v4 I think this bug is going to go away naturally anyway.

@tthvo
Copy link
Member

tthvo commented Sep 13, 2024

https://github.com/cryostatio/cryostat/pull/584/files#diff-58bcb5d27231eedec09ab4aecc0aca9cbcbc4f2b250db1ec942c7d3344ddf7a6R156

In API v4 I think this bug is going to go away naturally anyway.

Very nice! Then, this should be good then :D

@andrewazores
Copy link
Member Author

Actually, that bug is unfortunately not solved with the V4 work. I also thought it might be with the Quarkus 3.8 upgrade, but it's still present there too - and even with Quarkus 3.8 + API v4.

The bug looks something like this in the server logs:

cryostat_1  | 2024-09-13 21:08:28,820 DEBUG [org.hib.SQL] (executor-thread-4) 
cryostat_1  |     insert 
cryostat_1  |     into
cryostat_1  |         MatchExpression
cryostat_1  |         (script, id) 
cryostat_1  |     values
cryostat_1  |         (?, ?)
cryostat_1  | Hibernate: 
cryostat_1  |     insert 
cryostat_1  |     into
cryostat_1  |         MatchExpression
cryostat_1  |         (script, id) 
cryostat_1  |     values
cryostat_1  |         (?, ?)
cryostat_1  | 2024-09-13 21:08:28,823 DEBUG [org.hib.SQL] (executor-thread-4) 
cryostat_1  |     insert 
cryostat_1  |     into
cryostat_1  |         Credential
cryostat_1  |         (matchExpression, password, username, id) 
cryostat_1  |     values
cryostat_1  |         (?, pgp_sym_encrypt(?, current_setting('encrypt.key')), pgp_sym_encrypt(?, current_setting('encrypt.key')), ?)
cryostat_1  | Hibernate: 
cryostat_1  |     insert 
cryostat_1  |     into
cryostat_1  |         Credential
cryostat_1  |         (matchExpression, password, username, id) 
cryostat_1  |     values
cryostat_1  |         (?, pgp_sym_encrypt(?, current_setting('encrypt.key')), pgp_sym_encrypt(?, current_setting('encrypt.key')), ?)
cryostat_1  | 2024-09-13 21:08:28,824 DEBUG [org.hib.eve.int.AbstractFlushingEventListener] (executor-thread-4) Processing flush-time cascades
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.eve.int.AbstractFlushingEventListener] (executor-thread-4) Dirty checking collections
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.eng.int.Collections] (executor-thread-4) Collection found: [io.cryostat.discovery.DiscoveryNode.children#7], was: [<unreferenced>] (initialized)
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.eng.int.Collections] (executor-thread-4) Collection found: [io.cryostat.targets.Target.activeRecordings#1], was: [<unreferenced>] (initialized)
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.eve.int.AbstractFlushingEventListener] (executor-thread-4) Flushed: 4 insertions, 2 updates, 0 deletions to 4 objects
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.eve.int.AbstractFlushingEventListener] (executor-thread-4) Flushed: 4 (re)creations, 0 updates, 0 removals to 2 collections
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.int.uti.EntityPrinter] (executor-thread-4) Listing entities:
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.int.uti.EntityPrinter] (executor-thread-4) io.cryostat.discovery.DiscoveryNode{parent=null, children=[], name=service:jmx:rmi:///jndi/rmi://localhost:0/jmxrmi, id=7, nodeType=JVM, labels={}, target=io.cryostat.targets.Target#1}
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.int.uti.EntityPrinter] (executor-thread-4) io.cryostat.credentials.Credential{discoveryPlugin=null, matchExpression=io.cryostat.expressions.MatchExpression#1, password=pass, id=1, username=user}
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.int.uti.EntityPrinter] (executor-thread-4) io.cryostat.expressions.MatchExpression{id=1, script=target.connectUrl == "service:jmx:rmi:///jndi/rmi://localhost:0/jmxrmi"}
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.int.uti.EntityPrinter] (executor-thread-4) io.cryostat.targets.Target{connectUrl=service:jmx:rmi:///jndi/rmi://localhost:0/jmxrmi, jvmId=hY4ZlLUqaJAKFR3eR1Bstw7eHnK0Xb8NP3CLPVtUOCA=, discoveryNode=io.cryostat.discovery.DiscoveryNode#7, alias=localhost%3A0, annotations=Annotations[platform={}, cryostat={REALM=Custom Targets}], activeRecordings=[], id=1, labels={}}
cryostat_1  | 2024-09-13 21:08:28,825 DEBUG [org.hib.SQL] (executor-thread-4) 
cryostat_1  |     insert 
cryostat_1  |     into
cryostat_1  |         MatchExpression
cryostat_1  |         (script, id) 
cryostat_1  |     values
cryostat_1  |         (?, ?)
cryostat_1  | Hibernate: 
cryostat_1  |     insert 
cryostat_1  |     into
cryostat_1  |         MatchExpression
cryostat_1  |         (script, id) 
cryostat_1  |     values
cryostat_1  |         (?, ?)
db_1        | 2024-09-13 21:08:28.825 UTC [71] ERROR:  duplicate key value violates unique constraint "matchexpression_pkey"
db_1        | 2024-09-13 21:08:28.825 UTC [71] DETAIL:  Key (id)=(1) already exists.
db_1        | 2024-09-13 21:08:28.825 UTC [71] STATEMENT:  insert into MatchExpression (script,id) values ($1,$2)
cryostat_1  | 2024-09-13 21:08:28,827 DEBUG [io.cry.ws.MessagingServer] (executor-thread-2) Broadcasting: {"message":"target.connectUrl == \"service:jmx:rmi:///jndi/rmi://localhost:0/jmxrmi\"","meta":{"category":"ExpressionCreated"}}
cryostat_1  | 2024-09-13 21:08:28,828 DEBUG [org.hib.eng.jdb.spi.SqlExceptionHelper] (executor-thread-4) could not execute statement [insert into MatchExpression (script,id) values (?,?)]: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "matchexpression_pkey"
cryostat_1  |   Detail: Key (id)=(1) already exists.
cryostat_1  | 	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2725)
cryostat_1  | 	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2412)
cryostat_1  | 	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:371)
cryostat_1  | 	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:502)
cryostat_1  | 	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:419)
cryostat_1  | 	at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:194)
cryostat_1  | 	at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:155)
cryostat_1  | 	at io.agroal.pool.wrapper.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:90)
cryostat_1  | 	at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:194)
cryostat_1  | 	at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:108)
cryostat_1  | 	at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:40)
cryostat_1  | 	at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:52)
cryostat_1  | 	at org.hibernate.persister.entity.mutation.InsertCoordinator.doStaticInserts(InsertCoordinator.java:175)
cryostat_1  | 	at org.hibernate.persister.entity.mutation.InsertCoordinator.coordinateInsert(InsertCoordinator.java:113)
cryostat_1  | 	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2863)
cryostat_1  | 	at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:632)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:499)
cryostat_1  | 	at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:363)
cryostat_1  | 	at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:61)
cryostat_1  | 	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
cryostat_1  | 	at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1370)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$2(ConcreteSqmSelectQueryPlan.java:136)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:381)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:303)
cryostat_1  | 	at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:509)
cryostat_1  | 	at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:427)
cryostat_1  | 	at org.hibernate.query.Query.getResultList(Query.java:120)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.list(CommonPanacheQueryImpl.java:280)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.list(PanacheQueryImpl.java:149)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.JpaOperations.list(JpaOperations.java:24)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.JpaOperations.list(JpaOperations.java:10)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.common.runtime.AbstractJpaOperations.listAll(AbstractJpaOperations.java:305)
cryostat_1  | 	at io.cryostat.targets.Target.listAll(Target.java)
cryostat_1  | 	at io.cryostat.expressions.TargetMatcher.match(TargetMatcher.java:50)
cryostat_1  | 	at io.cryostat.expressions.TargetMatcher_ClientProxy.match(Unknown Source)
cryostat_1  | 	at io.cryostat.credentials.Credentials.safeResult(Credentials.java:158)
cryostat_1  | 	at io.cryostat.credentials.Credential$Listener.postPersist(Credential.java:101)
cryostat_1  | 	at io.cryostat.credentials.Credential_Listener_ClientProxy.postPersist(Unknown Source)
cryostat_1  | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
cryostat_1  | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
cryostat_1  | 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
cryostat_1  | 	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
cryostat_1  | 	at org.hibernate.jpa.event.internal.ListenerCallback.performCallback(ListenerCallback.java:55)
cryostat_1  | 	at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:123)
cryostat_1  | 	at org.hibernate.jpa.event.internal.CallbackRegistryImpl.postCreate(CallbackRegistryImpl.java:81)
cryostat_1  | 	at org.hibernate.event.internal.PostInsertEventListenerStandardImpl.onPostInsert(PostInsertEventListenerStandardImpl.java:31)
cryostat_1  | 	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireLazyEventOnEachListener(EventListenerGroupImpl.java:116)
cryostat_1  | 	at org.hibernate.action.internal.EntityInsertAction.postInsert(EntityInsertAction.java:191)
cryostat_1  | 	at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:117)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:632)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:499)
cryostat_1  | 	at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:363)
cryostat_1  | 	at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:61)
cryostat_1  | 	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
cryostat_1  | 	at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1370)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$2(ConcreteSqmSelectQueryPlan.java:136)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:381)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:303)
cryostat_1  | 	at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:509)
cryostat_1  | 	at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:427)
cryostat_1  | 	at org.hibernate.query.spi.AbstractSelectionQuery.getSingleResult(AbstractSelectionQuery.java:564)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.singleResult(CommonPanacheQueryImpl.java:309)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.singleResult(PanacheQueryImpl.java:169)
cryostat_1  | 	at io.cryostat.discovery.DiscoveryNode.getUniverse(DiscoveryNode.java:110)
cryostat_1  | 	at io.cryostat.discovery.DiscoveryNode.getRealm(DiscoveryNode.java:114)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery.doCreate(CustomDiscovery.java:211)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery.createForm(CustomDiscovery.java:125)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_Subclass.createForm$$superforward(Unknown Source)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_Subclass$$function$$2.apply(Unknown Source)
cryostat_1  | 	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
cryostat_1  | 	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:136)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:107)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:38)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:61)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:32)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(Unknown Source)
cryostat_1  | 	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
cryostat_1  | 	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
cryostat_1  | 	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_Subclass.createForm(Unknown Source)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_ClientProxy.createForm(Unknown Source)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery$quarkusrestinvoker$createForm_f4044472152fe54bbb4ecf74155604fed0b3a814.invoke(Unknown Source)
cryostat_1  | 	at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
cryostat_1  | 	at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
cryostat_1  | 	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
cryostat_1  | 	at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:582)
cryostat_1  | 	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
cryostat_1  | 	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
cryostat_1  | 	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
cryostat_1  | 	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
cryostat_1  | 	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
cryostat_1  | 	at java.base/java.lang.Thread.run(Thread.java:840)
cryostat_1  | 
cryostat_1  | 2024-09-13 21:08:28,828 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (executor-thread-4) SQL Error: 0, SQLState: 23505
cryostat_1  | 2024-09-13 21:08:28,828 ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (executor-thread-4) ERROR: duplicate key value violates unique constraint "matchexpression_pkey"
cryostat_1  |   Detail: Key (id)=(1) already exists.
cryostat_1  | 2024-09-13 21:08:28,831 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [Credential], timestamp: 1726261768831
cryostat_1  | 2024-09-13 21:08:28,831 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [DiscoveryNode], timestamp: 1726261768831
cryostat_1  | 2024-09-13 21:08:28,831 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [Target], timestamp: 1726261768831
cryostat_1  | 2024-09-13 21:08:28,831 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [MatchExpression], timestamp: 1726261768831
cryostat_1  | 2024-09-13 21:08:28,860 DEBUG [org.hib.eng.tra.int.TransactionImpl] (executor-thread-4) On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
cryostat_1  | 2024-09-13 21:08:28,860 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [Credential], timestamp: 1726261768860
cryostat_1  | 2024-09-13 21:08:28,860 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [DiscoveryNode], timestamp: 1726261768860
cryostat_1  | 2024-09-13 21:08:28,860 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [Target], timestamp: 1726261768860
cryostat_1  | 2024-09-13 21:08:28,860 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Pre-invalidating space [MatchExpression], timestamp: 1726261768860
cryostat_1  | 2024-09-13 21:08:28,861 FINE  [org.pos.jdb.PgConnection] (executor-thread-4)   setAutoCommit = true
cryostat_1  | 2024-09-13 21:08:28,861 DEBUG [org.hib.res.jdb.int.LogicalConnectionManagedImpl] (executor-thread-4) Initiating JDBC connection release from afterTransaction
cryostat_1  | 2024-09-13 21:08:28,862 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Invalidating space [Credential], timestamp: 1726261708862
cryostat_1  | 2024-09-13 21:08:28,862 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Invalidating space [DiscoveryNode], timestamp: 1726261708862
cryostat_1  | 2024-09-13 21:08:28,862 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Invalidating space [Target], timestamp: 1726261708862
cryostat_1  | 2024-09-13 21:08:28,862 DEBUG [org.hib.cac.int.TimestampsCacheEnabledImpl] (executor-thread-4) Invalidating space [MatchExpression], timestamp: 1726261708862
cryostat_1  | 2024-09-13 21:08:28,862 DEBUG [org.jbo.res.rea.com.cor.AbstractResteasyReactiveContext] (executor-thread-4) Restarting handler chain for exception exception: org.hibernate.exception.ConstraintViolationException: could not execute statement [ERROR: duplicate key value violates unique constraint "matchexpression_pkey"
cryostat_1  |   Detail: Key (id)=(1) already exists.] [insert into MatchExpression (script,id) values (?,?)]
cryostat_1  | 	at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:97)
cryostat_1  | 	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:58)
cryostat_1  | 	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
cryostat_1  | 	at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
cryostat_1  | 	at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:108)
cryostat_1  | 	at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:40)
cryostat_1  | 	at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:52)
cryostat_1  | 	at org.hibernate.persister.entity.mutation.InsertCoordinator.doStaticInserts(InsertCoordinator.java:175)
cryostat_1  | 	at org.hibernate.persister.entity.mutation.InsertCoordinator.coordinateInsert(InsertCoordinator.java:113)
cryostat_1  | 	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2863)
cryostat_1  | 	at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:632)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:499)
cryostat_1  | 	at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:363)
cryostat_1  | 	at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:61)
cryostat_1  | 	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
cryostat_1  | 	at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1370)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$2(ConcreteSqmSelectQueryPlan.java:136)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:381)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:303)
cryostat_1  | 	at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:509)
cryostat_1  | 	at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:427)
cryostat_1  | 	at org.hibernate.query.Query.getResultList(Query.java:120)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.list(CommonPanacheQueryImpl.java:280)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.list(PanacheQueryImpl.java:149)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.JpaOperations.list(JpaOperations.java:24)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.JpaOperations.list(JpaOperations.java:10)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.common.runtime.AbstractJpaOperations.listAll(AbstractJpaOperations.java:305)
cryostat_1  | 	at io.cryostat.targets.Target.listAll(Target.java)
cryostat_1  | 	at io.cryostat.expressions.TargetMatcher.match(TargetMatcher.java:50)
cryostat_1  | 	at io.cryostat.expressions.TargetMatcher_ClientProxy.match(Unknown Source)
cryostat_1  | 	at io.cryostat.credentials.Credentials.safeResult(Credentials.java:158)
cryostat_1  | 	at io.cryostat.credentials.Credential$Listener.postPersist(Credential.java:101)
cryostat_1  | 	at io.cryostat.credentials.Credential_Listener_ClientProxy.postPersist(Unknown Source)
cryostat_1  | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
cryostat_1  | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
cryostat_1  | 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
cryostat_1  | 	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
cryostat_1  | 	at org.hibernate.jpa.event.internal.ListenerCallback.performCallback(ListenerCallback.java:55)
cryostat_1  | 	at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:123)
cryostat_1  | 	at org.hibernate.jpa.event.internal.CallbackRegistryImpl.postCreate(CallbackRegistryImpl.java:81)
cryostat_1  | 	at org.hibernate.event.internal.PostInsertEventListenerStandardImpl.onPostInsert(PostInsertEventListenerStandardImpl.java:31)
cryostat_1  | 	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireLazyEventOnEachListener(EventListenerGroupImpl.java:116)
cryostat_1  | 	at org.hibernate.action.internal.EntityInsertAction.postInsert(EntityInsertAction.java:191)
cryostat_1  | 	at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:117)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:632)
cryostat_1  | 	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:499)
cryostat_1  | 	at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:363)
cryostat_1  | 	at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:61)
cryostat_1  | 	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
cryostat_1  | 	at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1370)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$2(ConcreteSqmSelectQueryPlan.java:136)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:381)
cryostat_1  | 	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:303)
cryostat_1  | 	at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:509)
cryostat_1  | 	at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:427)
cryostat_1  | 	at org.hibernate.query.spi.AbstractSelectionQuery.getSingleResult(AbstractSelectionQuery.java:564)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.singleResult(CommonPanacheQueryImpl.java:309)
cryostat_1  | 	at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.singleResult(PanacheQueryImpl.java:169)
cryostat_1  | 	at io.cryostat.discovery.DiscoveryNode.getUniverse(DiscoveryNode.java:110)
cryostat_1  | 	at io.cryostat.discovery.DiscoveryNode.getRealm(DiscoveryNode.java:114)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery.doCreate(CustomDiscovery.java:211)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery.createForm(CustomDiscovery.java:125)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_Subclass.createForm$$superforward(Unknown Source)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_Subclass$$function$$2.apply(Unknown Source)
cryostat_1  | 	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
cryostat_1  | 	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:136)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:107)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:38)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:61)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:32)
cryostat_1  | 	at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(Unknown Source)
cryostat_1  | 	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
cryostat_1  | 	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
cryostat_1  | 	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_Subclass.createForm(Unknown Source)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery_ClientProxy.createForm(Unknown Source)
cryostat_1  | 	at io.cryostat.discovery.CustomDiscovery$quarkusrestinvoker$createForm_f4044472152fe54bbb4ecf74155604fed0b3a814.invoke(Unknown Source)
cryostat_1  | 	at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
cryostat_1  | 	at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
cryostat_1  | 	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
cryostat_1  | 	at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:582)
cryostat_1  | 	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
cryostat_1  | 	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
cryostat_1  | 	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
cryostat_1  | 	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
cryostat_1  | 	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
cryostat_1  | 	at java.base/java.lang.Thread.run(Thread.java:840)
cryostat_1  | Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "matchexpression_pkey"
cryostat_1  |   Detail: Key (id)=(1) already exists.
cryostat_1  | 	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2725)
cryostat_1  | 	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2412)
cryostat_1  | 	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:371)
cryostat_1  | 	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:502)
cryostat_1  | 	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:419)
cryostat_1  | 	at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:194)
cryostat_1  | 	at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:155)
cryostat_1  | 	at io.agroal.pool.wrapper.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:90)
cryostat_1  | 	at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:194)
cryostat_1  | 	... 85 more

In short, something about the Credential/MatchExpression relationship, or the @PostPersist on Credentials, somehow results in two identical MatchExpression entities getting persisted, with the same ID, therefore colliding on the primary key and failing the request.

@tthvo
Copy link
Member

tthvo commented Sep 13, 2024

Actually, that bug is unfortunately not solved with the V4 work. I also thought it might be with the Quarkus 3.8 upgrade, but it's still present there too - and even with Quarkus 3.8 + API v4.

Ahh that's unfortunate. For the time being, I have a simple workaround for this issue. Basically just send a follow-up API request to get the updated credential instance: #1350

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore Refactor, rename, cleanup, etc. dependencies Pull requests that update a dependency file safe-to-test
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[Epic] Upgrade to Patternfly v5
2 participants