diff --git a/.github/workflows/ci-code-analysis.yml b/.github/workflows/ci-code-analysis.yml
index d6b8ac38a..8036fc62a 100644
--- a/.github/workflows/ci-code-analysis.yml
+++ b/.github/workflows/ci-code-analysis.yml
@@ -37,7 +37,7 @@ jobs:
step: restore
- uses: actions/setup-java@v4
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
- name: Run spotbugs
run: mvn -B -U compile spotbugs:check
diff --git a/.github/workflows/pr-ci.yaml b/.github/workflows/pr-ci.yaml
index 822d497c8..61554e0d7 100644
--- a/.github/workflows/pr-ci.yaml
+++ b/.github/workflows/pr-ci.yaml
@@ -110,7 +110,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-java@v4
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
cache: 'maven'
- run: git submodule init && git submodule update
@@ -192,7 +192,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-java@v4
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
cache: 'maven'
- run: git submodule init && git submodule update
diff --git a/.github/workflows/push-ci.yaml b/.github/workflows/push-ci.yaml
index e0b832f38..0d6ae8c58 100644
--- a/.github/workflows/push-ci.yaml
+++ b/.github/workflows/push-ci.yaml
@@ -63,7 +63,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-java@v4
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
cache: 'maven'
- run: git submodule init && git submodule update
diff --git a/README.md b/README.md
index ecfaef71e..05d9d9819 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,7 @@ We welcome and appreciate any contributions from our community. Please visit our
Build requirements:
- git
-- JDK 17+
+- JDK 21+
- Maven v3+
- [Quarkus CLI](https://quarkus.io/guides/cli-tooling) v3.4.1+ (Recommended)
- [Podman](https://podman.io/docs/installation) 4.7+
diff --git a/compose/auth_proxy.yml b/compose/auth_proxy.yml
index 2e182cda1..a6913e17b 100644
--- a/compose/auth_proxy.yml
+++ b/compose/auth_proxy.yml
@@ -12,12 +12,6 @@ services:
QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_PREFIX: "true"
QUARKUS_HTTP_ACCESS_LOG_PATTERN: long
QUARKUS_HTTP_ACCESS_LOG_ENABLED: "true"
- healthcheck:
- test: curl --fail http://cryostat:8181/health/liveness || exit 1
- interval: 10s
- retries: 3
- start_period: 30s
- timeout: 5s
auth:
# the proxy does not actually depend on cryostat being up, but we use this
# to ensure that when the smoketest tries to open the auth login page in a
@@ -31,7 +25,7 @@ services:
limits:
cpus: "0.1"
memory: 32m
- image: ${OAUTH2_PROXY_IMAGE:-quay.io/oauth2-proxy/oauth2-proxy:latest}
+ image: ${OAUTH2_PROXY_IMAGE:-quay.io/oauth2-proxy/oauth2-proxy:latest-alpine}
command:
- --alpha-config=/tmp/auth_proxy_alpha_config.yml
volumes:
@@ -49,10 +43,10 @@ services:
CRYOSTAT_PROXY_PORT: ${CRYOSTAT_PROXY_PORT}
restart: unless-stopped
healthcheck:
- test: wget -q --spider ${CRYOSTAT_PROXY_PROTOCOL}://localhost:${CRYOSTAT_PROXY_PORT}/ping || exit 1
+ test: wget --no-check-certificate -q --spider ${CRYOSTAT_PROXY_PROTOCOL}://localhost:${CRYOSTAT_PROXY_PORT}/ping || exit 1
interval: 10s
retries: 3
- start_period: 30s
+ start_period: 10s
timeout: 5s
volumes:
diff --git a/compose/cryostat-grafana.yml b/compose/cryostat-grafana.yml
index 3c030bc38..37d376180 100644
--- a/compose/cryostat-grafana.yml
+++ b/compose/cryostat-grafana.yml
@@ -26,5 +26,5 @@ services:
test: curl --fail http://localhost:3000/ || exit 1
retries: 3
interval: 30s
- start_period: 30s
+ start_period: 10s
timeout: 1s
diff --git a/compose/cryostat.yml b/compose/cryostat.yml
index 63f15ebdb..13c3bbc1f 100644
--- a/compose/cryostat.yml
+++ b/compose/cryostat.yml
@@ -25,8 +25,8 @@ services:
CRYOSTAT_DISCOVERY_DOCKER_ENABLED: ${CRYOSTAT_DISCOVERY_DOCKER_ENABLED:-true}
JAVA_OPTS_APPEND: >-
-XX:+FlightRecorder
- -XX:StartFlightRecording=name=onstart,settings=default,disk=true,maxage=5m
- -XX:StartFlightRecording=name=startup,settings=profile,disk=true,duration=30s
+ -XX:StartFlightRecording=filename=/tmp,name=onstart,settings=default,disk=true,maxage=5m
+ -XX:StartFlightRecording=filename=/tmp,name=startup,settings=profile,disk=true,duration=30s
-Dcom.sun.management.jmxremote.autodiscovery=true
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9091
@@ -36,12 +36,14 @@ services:
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
restart: unless-stopped
- healthcheck:
- test: curl --fail http://cryostat:${CRYOSTAT_HTTP_PORT}/health/liveness || exit 1
- interval: 10s
- retries: 3
- start_period: 30s
- timeout: 5s
+ # FIXME reenable this check. Somehow after upgrading to Quarkus 3.8, this check fails with 'connection refused',
+ # but the container comes up successfully without it and shelling into the container later to run curl succeeds
+ # healthcheck:
+ # test: curl --fail http://cryostat:${CRYOSTAT_HTTP_PORT}/health/liveness || exit 1
+ # interval: 10s
+ # retries: 3
+ # start_period: 30s
+ # timeout: 5s
volumes:
jmxtls_cfg:
diff --git a/compose/cryostat_docker.yml b/compose/cryostat_docker.yml
index 2060bfd63..05f925807 100644
--- a/compose/cryostat_docker.yml
+++ b/compose/cryostat_docker.yml
@@ -35,7 +35,7 @@ services:
CRYOSTAT_DISCOVERY_JDP_ENABLED: "true"
JAVA_OPTS_APPEND: >-
-XX:+FlightRecorder
- -XX:StartFlightRecording=name=onstart,settings=default,disk=true,maxage=5m
+ -XX:StartFlightRecording=filename=/tmp,name=onstart,settings=default,disk=true,maxage=5m
-Dcom.sun.management.jmxremote.autodiscovery=true
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9091
diff --git a/compose/cryostat_k8s.yml b/compose/cryostat_k8s.yml
index 9c99e84ae..aad0d546d 100644
--- a/compose/cryostat_k8s.yml
+++ b/compose/cryostat_k8s.yml
@@ -20,7 +20,7 @@ services:
environment:
CRYOSTAT_DISCOVERY_PODMAN_ENABLED: "false"
CRYOSTAT_DISCOVERY_JDP_ENABLED: "true"
- JAVA_OPTS_APPEND: "-XX:+FlightRecorder -XX:StartFlightRecording=name=onstart,settings=default,disk=true,maxage=5m -Dcom.sun.management.jmxremote.autodiscovery=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9091 -Dcom.sun.management.jmxremote.rmi.port=9091 -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false"
+ JAVA_OPTS_APPEND: "-XX:+FlightRecorder -XX:StartFlightRecording=filename=/tmp,name=onstart,settings=default,disk=true,maxage=5m -Dcom.sun.management.jmxremote.autodiscovery=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9091 -Dcom.sun.management.jmxremote.rmi.port=9091 -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false"
restart: always
healthcheck:
test: curl --fail http://localhost:8181/health/liveness || exit 1
diff --git a/compose/db.yml b/compose/db.yml
index b23fe2b73..02e015fdb 100644
--- a/compose/db.yml
+++ b/compose/db.yml
@@ -27,7 +27,7 @@ services:
test: pg_isready -U cryostat -d cryostat || exit 1
interval: 10s
retries: 3
- start_period: 30s
+ start_period: 10s
timeout: 5s
volumes:
diff --git a/compose/jfr-datasource.yml b/compose/jfr-datasource.yml
index 3136b1148..cc190cf08 100644
--- a/compose/jfr-datasource.yml
+++ b/compose/jfr-datasource.yml
@@ -29,8 +29,8 @@ services:
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
healthcheck:
- test: curl --fail ${CRYOSTAT_PROXY_PROTOCOL}://localhost:${CRYOSTAT_PROXY_PORT}/ || exit 1
+ test: curl --fail http://localhost:8080/ || exit 1
retries: 3
interval: 30s
- start_period: 30s
+ start_period: 10s
timeout: 1s
diff --git a/compose/sample_apps/vertx-cryostat-agent.yml b/compose/sample_apps/vertx-cryostat-agent.yml
index 501198a8b..cdcdf6179 100644
--- a/compose/sample_apps/vertx-cryostat-agent.yml
+++ b/compose/sample_apps/vertx-cryostat-agent.yml
@@ -63,7 +63,7 @@ services:
- "8911"
restart: always
healthcheck:
- test: curl --fail http://localhost:8081 || exit 1
+ test: curl --fail http://localhost:8082 || exit 1
interval: 10s
retries: 3
start_period: 30s
@@ -102,7 +102,7 @@ services:
- "8912"
restart: always
healthcheck:
- test: curl --fail http://localhost:8081 || exit 1
+ test: curl --fail http://localhost:8083 || exit 1
interval: 10s
retries: 3
start_period: 30s
@@ -126,7 +126,7 @@ services:
- "8084:8084"
restart: always
healthcheck:
- test: curl --fail http://localhost:8081 || exit 1
+ test: curl --fail http://localhost:8084 || exit 1
interval: 10s
retries: 3
start_period: 30s
diff --git a/pom.xml b/pom.xml
index 2c6a1a6ba..3f306488f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
${cryostat.imageVersionLower}
- 17
+ 21
${java.version}
${java.version}
${java.version}
@@ -35,11 +35,8 @@
4.0.0-SNAPSHOT
9.0.0
- 1.16.1
2.16.1
4.4
- 5.2.1
- 3.14.0
1.8.0
0.4.4
3.25.2
@@ -47,9 +44,8 @@
1.20.1
quarkus-bom
io.quarkus.platform
- 3.2.12.Final
- 2.2.5
- 4.1.108.Final
+ 3.8.6
+ 2.3.10
3.6.0
3.4.1
3.7.1
@@ -60,19 +56,12 @@
1.23.0
4.5
3.5.0
- 2
+ 0
3.5.0
${surefire.rerunFailingTestsCount}
-
- io.netty
- netty-bom
- ${io.netty.version}
- pom
- import
-
${quarkus.platform.group-id}
${quarkus.platform.artifact-id}
@@ -161,6 +150,10 @@
io.quarkus
quarkus-vertx
+
+ io.quarkus
+ quarkus-netty
+
io.quarkus
quarkus-smallrye-openapi
@@ -225,12 +218,10 @@
org.apache.commons
commons-lang3
- ${org.apache.commons.lang3.version}
commons-codec
commons-codec
- ${org.apache.commons.codec.version}
commons-io
@@ -327,7 +318,7 @@
- -Dcryostat.discovery.jdp.enabled=true -Dcryostat.discovery.podman.enabled=true -XX:+FlightRecorder -XX:StartFlightRecording=name=onstart,settings=default,disk=true,maxage=5m -Dcom.sun.management.jmxremote.autodiscovery=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9091 -Dcom.sun.management.jmxremote.rmi.port=9091 -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false
+ -Dcryostat.discovery.jdp.enabled=true -Dcryostat.discovery.podman.enabled=true -XX:+FlightRecorder -XX:StartFlightRecording=filename=/tmp/,name=onstart,settings=default,disk=true,maxage=5m -Dcom.sun.management.jmxremote.autodiscovery=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9091 -Dcom.sun.management.jmxremote.rmi.port=9091 -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false
@@ -566,7 +557,6 @@
io.netty
netty-transport-native-epoll
- ${io.netty.version}
${io.netty.netty-transport-native-epoll.classifier}
${io.netty.netty-transport-native-epoll.scope}
diff --git a/schema/openapi.yaml b/schema/openapi.yaml
index 27a342de4..d8b24ed8c 100644
--- a/schema/openapi.yaml
+++ b/schema/openapi.yaml
@@ -85,6 +85,7 @@ components:
DiscoveryPlugin:
properties:
builtin:
+ readOnly: true
type: boolean
callback:
format: uri
@@ -296,6 +297,7 @@ components:
Target:
properties:
agent:
+ readOnly: true
type: boolean
alias:
pattern: \S
@@ -347,11 +349,6 @@ components:
meta:
$ref: '#/components/schemas/Meta'
type: object
- securitySchemes:
- SecurityScheme:
- description: Authentication
- scheme: basic
- type: http
info:
contact:
email: cryostat-development@googlegroups.com
@@ -913,7 +910,7 @@ paths:
type: string
requestBody:
content:
- application/json:
+ text/plain:
schema:
type: string
responses:
@@ -1906,7 +1903,7 @@ paths:
responses:
"200":
content:
- application/json:
+ text/plain:
schema:
type: string
description: OK
@@ -2393,13 +2390,13 @@ paths:
type: integer
requestBody:
content:
- application/json:
+ text/plain:
schema:
type: string
responses:
"200":
content:
- application/json:
+ text/plain:
schema:
type: string
description: OK
@@ -2429,7 +2426,7 @@ paths:
responses:
"200":
content:
- application/json:
+ text/plain:
schema:
type: string
description: OK
diff --git a/src/main/docker/Dockerfile.jvm b/src/main/docker/Dockerfile.jvm
index 1851cd10d..7f769edb1 100644
--- a/src/main/docker/Dockerfile.jvm
+++ b/src/main/docker/Dockerfile.jvm
@@ -77,7 +77,7 @@
# accessed directly. (example: "foo.example.com,bar.example.com")
#
###
-FROM registry.access.redhat.com/ubi8/openjdk-17-runtime:1.20-3.1724181070
+FROM registry.access.redhat.com/ubi9/openjdk-21-runtime:1.20-2.1725851019
ENV LANGUAGE='en_US:en'
@@ -107,7 +107,7 @@ ENV SSL_TRUSTSTORE=$CONF_DIR/truststore.p12 \
USER root
RUN mkdir -p $CONF_DIR \
&& chmod -R g=u $CONF_DIR \
- && chown jboss:root $CONF_DIR
+ && chown default:root $CONF_DIR
USER 185
RUN /deployments/app/truststore-setup.bash
diff --git a/src/main/docker/include/truststore-setup.bash b/src/main/docker/include/truststore-setup.bash
index ab4d80cfa..57f964ec1 100755
--- a/src/main/docker/include/truststore-setup.bash
+++ b/src/main/docker/include/truststore-setup.bash
@@ -15,7 +15,7 @@ cd "$CONF_DIR"
keytool -importkeystore \
-noprompt \
-storetype PKCS12 \
- -srckeystore /usr/lib/jvm/jre-17-openjdk/lib/security/cacerts \
+ -srckeystore /usr/lib/jvm/jre-openjdk/lib/security/cacerts \
-srcstorepass changeit \
-destkeystore "$SSL_TRUSTSTORE" \
-deststorepass "$SSL_TRUSTSTORE_PASS"
diff --git a/src/main/java/io/cryostat/HibernateFormatMapperCustomization.java b/src/main/java/io/cryostat/HibernateFormatMapperCustomization.java
new file mode 100644
index 000000000..dd390869d
--- /dev/null
+++ b/src/main/java/io/cryostat/HibernateFormatMapperCustomization.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright The Cryostat Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.cryostat;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.quarkus.hibernate.orm.JsonFormat;
+import io.quarkus.hibernate.orm.PersistenceUnitExtension;
+import org.hibernate.type.descriptor.WrapperOptions;
+import org.hibernate.type.descriptor.java.JavaType;
+import org.hibernate.type.format.FormatMapper;
+import org.hibernate.type.format.jackson.JacksonJsonFormatMapper;
+
+@JsonFormat
+@PersistenceUnitExtension
+/**
+ * @see https://github.com/quarkusio/quarkus/issues/42596
+ */
+public class HibernateFormatMapperCustomization implements FormatMapper {
+
+ private final JacksonJsonFormatMapper delegate =
+ new JacksonJsonFormatMapper(new ObjectMapper().findAndRegisterModules());
+
+ @Override
+ public T fromString(
+ CharSequence charSequence, JavaType javaType, WrapperOptions wrapperOptions) {
+ return delegate.fromString(charSequence, javaType, wrapperOptions);
+ }
+
+ @Override
+ public String toString(T value, JavaType javaType, WrapperOptions wrapperOptions) {
+ return delegate.toString(value, javaType, wrapperOptions);
+ }
+}
diff --git a/src/main/java/io/cryostat/credentials/Credentials.java b/src/main/java/io/cryostat/credentials/Credentials.java
index 7f840be92..4d81ab6d4 100644
--- a/src/main/java/io/cryostat/credentials/Credentials.java
+++ b/src/main/java/io/cryostat/credentials/Credentials.java
@@ -25,7 +25,6 @@
import io.cryostat.expressions.MatchExpression;
import io.cryostat.expressions.MatchExpression.TargetMatcher;
-import io.smallrye.common.annotation.Blocking;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
@@ -113,7 +112,6 @@ static Map notificationResult(Credential credential) throws Scri
return result;
}
- @Blocking
static Map safeResult(Credential credential, TargetMatcher matcher)
throws ScriptException {
Map result = new HashMap<>();
@@ -124,7 +122,6 @@ static Map safeResult(Credential credential, TargetMatcher match
return result;
}
- @Blocking
static Map safeMatchedResult(Credential credential, TargetMatcher matcher)
throws ScriptException {
Map result = new HashMap<>();
diff --git a/src/main/java/io/cryostat/credentials/CredentialsFinder.java b/src/main/java/io/cryostat/credentials/CredentialsFinder.java
index a8f1bda00..52239c820 100644
--- a/src/main/java/io/cryostat/credentials/CredentialsFinder.java
+++ b/src/main/java/io/cryostat/credentials/CredentialsFinder.java
@@ -24,7 +24,6 @@
import io.cryostat.targets.Target.TargetDiscovery;
import io.quarkus.vertx.ConsumeEvent;
-import io.smallrye.common.annotation.Blocking;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.apache.commons.collections4.BidiMap;
@@ -52,7 +51,6 @@ void onMessage(TargetDiscovery event) {
}
}
- @Blocking
public Optional getCredentialsForTarget(Target target) {
return Optional.ofNullable(
cache.computeIfAbsent(
@@ -73,7 +71,6 @@ public Optional getCredentialsForTarget(Target target) {
.orElse(null)));
}
- @Blocking
public Optional getCredentialsForConnectUrl(URI connectUrl) {
return Target.find("connectUrl", connectUrl)
.singleResultOptional()
diff --git a/src/main/java/io/cryostat/discovery/ContainerDiscovery.java b/src/main/java/io/cryostat/discovery/ContainerDiscovery.java
index 0fdc154bf..fb9b5e2b7 100644
--- a/src/main/java/io/cryostat/discovery/ContainerDiscovery.java
+++ b/src/main/java/io/cryostat/discovery/ContainerDiscovery.java
@@ -187,7 +187,6 @@ public abstract class ContainerDiscovery {
protected long timerId;
- @Transactional
void onStart(@Observes StartupEvent evt) {
if (!enabled()) {
return;
@@ -201,7 +200,6 @@ void onStart(@Observes StartupEvent evt) {
}
logger.debugv("Starting {0} client", getRealm());
-
queryContainers();
this.timerId = vertx.setPeriodic(pollPeriod.toMillis(), unused -> queryContainers());
}
@@ -266,10 +264,9 @@ private Target toTarget(ContainerSpec desc) {
target.connectUrl = connectUrl;
target.alias = Optional.ofNullable(desc.Names.get(0)).orElse(desc.Id);
target.labels = desc.Labels;
- target.annotations = new Annotations();
- target.annotations
- .cryostat()
- .putAll(
+ target.annotations =
+ new Annotations(
+ null,
Map.of(
"REALM", // AnnotationKey.REALM,
getRealm(),
diff --git a/src/main/java/io/cryostat/discovery/CustomDiscovery.java b/src/main/java/io/cryostat/discovery/CustomDiscovery.java
index 460b331a5..09d37d612 100644
--- a/src/main/java/io/cryostat/discovery/CustomDiscovery.java
+++ b/src/main/java/io/cryostat/discovery/CustomDiscovery.java
@@ -200,9 +200,7 @@ Response doV2Create(
credential.ifPresent(c -> c.persist());
target.activeRecordings = new ArrayList<>();
- target.labels = Map.of();
- target.annotations = new Annotations();
- target.annotations.cryostat().putAll(Map.of("REALM", REALM));
+ target.annotations = new Annotations(null, Map.of("REALM", REALM));
DiscoveryNode node = DiscoveryNode.target(target, BaseNodeType.JVM);
target.discoveryNode = node;
diff --git a/src/main/java/io/cryostat/discovery/Discovery.java b/src/main/java/io/cryostat/discovery/Discovery.java
index 1eb867def..e45a28705 100644
--- a/src/main/java/io/cryostat/discovery/Discovery.java
+++ b/src/main/java/io/cryostat/discovery/Discovery.java
@@ -42,6 +42,7 @@
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jwt.proc.BadJWTException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.quarkus.narayana.jta.QuarkusTransaction;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
import io.vertx.core.json.JsonObject;
@@ -106,33 +107,42 @@ public class Discovery {
@Inject Scheduler scheduler;
@Inject URIUtil uriUtil;
- @Transactional
void onStart(@Observes StartupEvent evt) {
- DiscoveryPlugin.findAll().list().stream()
- .filter(p -> !p.builtin)
- .forEach(
- plugin -> {
- var dataMap = new JobDataMap();
- dataMap.put(PLUGIN_ID_MAP_KEY, plugin.id);
- dataMap.put(REFRESH_MAP_KEY, true);
- JobDetail jobDetail =
- JobBuilder.newJob(RefreshPluginJob.class)
- .withIdentity(plugin.id.toString(), JOB_STARTUP)
- .usingJobData(dataMap)
- .build();
- var trigger =
- TriggerBuilder.newTrigger()
- .usingJobData(jobDetail.getJobDataMap())
- .startNow()
- .withSchedule(
- SimpleScheduleBuilder.simpleSchedule()
- .withRepeatCount(0))
- .build();
- try {
- scheduler.scheduleJob(jobDetail, trigger);
- } catch (SchedulerException e) {
- logger.warn("Failed to schedule plugin prune job", e);
- }
+ QuarkusTransaction.requiringNew()
+ .run(
+ () -> {
+ DiscoveryPlugin.findAll().list().stream()
+ .filter(p -> !p.builtin)
+ .forEach(
+ plugin -> {
+ var dataMap = new JobDataMap();
+ dataMap.put(PLUGIN_ID_MAP_KEY, plugin.id);
+ dataMap.put(REFRESH_MAP_KEY, true);
+ JobDetail jobDetail =
+ JobBuilder.newJob(RefreshPluginJob.class)
+ .withIdentity(
+ plugin.id.toString(),
+ JOB_STARTUP)
+ .usingJobData(dataMap)
+ .build();
+ var trigger =
+ TriggerBuilder.newTrigger()
+ .usingJobData(
+ jobDetail.getJobDataMap())
+ .startNow()
+ .withSchedule(
+ SimpleScheduleBuilder
+ .simpleSchedule()
+ .withRepeatCount(0))
+ .build();
+ try {
+ scheduler.scheduleJob(jobDetail, trigger);
+ } catch (SchedulerException e) {
+ logger.warn(
+ "Failed to schedule plugin prune job",
+ e);
+ }
+ });
});
}
diff --git a/src/main/java/io/cryostat/discovery/DiscoveryNode.java b/src/main/java/io/cryostat/discovery/DiscoveryNode.java
index 164292e25..3446ad51b 100644
--- a/src/main/java/io/cryostat/discovery/DiscoveryNode.java
+++ b/src/main/java/io/cryostat/discovery/DiscoveryNode.java
@@ -196,7 +196,14 @@ static class Listener {
@Inject EventBus bus;
@PrePersist
- void prePersist(DiscoveryNode node) {}
+ void prePersist(DiscoveryNode node) {
+ if (node.children == null) {
+ node.children = new ArrayList<>();
+ }
+ if (node.labels == null) {
+ node.labels = new HashMap<>();
+ }
+ }
@PostPersist
void postPersist(DiscoveryNode node) {}
diff --git a/src/main/java/io/cryostat/discovery/JDPDiscovery.java b/src/main/java/io/cryostat/discovery/JDPDiscovery.java
index 2bc0a77d5..c448734ac 100644
--- a/src/main/java/io/cryostat/discovery/JDPDiscovery.java
+++ b/src/main/java/io/cryostat/discovery/JDPDiscovery.java
@@ -65,7 +65,6 @@ static JvmDiscoveryClient produceJvmDiscoveryClient() {
@ConfigProperty(name = "cryostat.discovery.jdp.enabled")
boolean enabled;
- @Transactional
void onStart(@Observes StartupEvent evt) {
if (!enabled) {
return;
@@ -118,11 +117,9 @@ void handleJdpEvent(JvmDiscoveryEvent evt) {
target.activeRecordings = new ArrayList<>();
target.connectUrl = connectUrl;
target.alias = evt.getJvmDescriptor().getMainClass();
- target.labels = Map.of();
- target.annotations = new Annotations();
- target.annotations
- .cryostat()
- .putAll(
+ target.annotations =
+ new Annotations(
+ null,
Map.of(
"REALM", // AnnotationKey.REALM,
REALM,
diff --git a/src/main/java/io/cryostat/discovery/KubeApiDiscovery.java b/src/main/java/io/cryostat/discovery/KubeApiDiscovery.java
index bed1a0cef..e9ccd2abe 100644
--- a/src/main/java/io/cryostat/discovery/KubeApiDiscovery.java
+++ b/src/main/java/io/cryostat/discovery/KubeApiDiscovery.java
@@ -129,7 +129,6 @@ protected HashMap> initialize()
// Priority is set higher than default 0 such that onStart is called first before onAfterStart
// This ensures realm node is persisted before initializing informers
- @Transactional
void onStart(@Observes @Priority(1) StartupEvent evt) {
if (!enabled()) {
return;
@@ -143,7 +142,6 @@ void onStart(@Observes @Priority(1) StartupEvent evt) {
logger.debugv("Starting {0} client", REALM);
}
- @Transactional
void onAfterStart(@Observes StartupEvent evt) {
if (!enabled() || !available()) {
return;
@@ -468,12 +466,13 @@ private Pair queryForNode(
newNode.nodeType = nodeType.getKind();
newNode.children = new ArrayList<>();
newNode.target = null;
- newNode.labels =
+ Map labels =
kubeObj != null
? kubeObj.getMetadata().getLabels()
: new HashMap<>();
// Add namespace to label to retrieve node later
- newNode.labels.put(DISCOVERY_NAMESPACE_LABEL_KEY, namespace);
+ labels.put(DISCOVERY_NAMESPACE_LABEL_KEY, namespace);
+ newNode.labels = labels;
return newNode;
});
return Pair.of(kubeObj, node);
@@ -614,14 +613,10 @@ public Target toTarget() {
target.activeRecordings = new ArrayList<>();
target.connectUrl = connectUrl;
target.alias = objRef.getName();
- target.labels = obj != null ? obj.getMetadata().getLabels() : new HashMap<>();
- target.annotations = new Annotations();
- target.annotations
- .platform()
- .putAll(obj != null ? obj.getMetadata().getAnnotations() : Map.of());
- target.annotations
- .cryostat()
- .putAll(
+ target.labels = (obj != null ? obj.getMetadata().getLabels() : new HashMap<>());
+ target.annotations =
+ new Annotations(
+ obj != null ? obj.getMetadata().getAnnotations() : Map.of(),
Map.of(
"REALM",
REALM,
diff --git a/src/main/java/io/cryostat/expressions/MatchExpressionEvaluator.java b/src/main/java/io/cryostat/expressions/MatchExpressionEvaluator.java
index c1acb8ae9..3053baee8 100644
--- a/src/main/java/io/cryostat/expressions/MatchExpressionEvaluator.java
+++ b/src/main/java/io/cryostat/expressions/MatchExpressionEvaluator.java
@@ -33,7 +33,6 @@
import io.quarkus.cache.CacheResult;
import io.quarkus.cache.CompositeCacheKey;
import io.quarkus.vertx.ConsumeEvent;
-import io.smallrye.common.annotation.Blocking;
import jakarta.annotation.Nullable;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@@ -77,7 +76,6 @@ void onMessage(ExpressionEvent event) {
}
@Transactional
- @Blocking
@ConsumeEvent(value = Target.TARGET_JVM_DISCOVERY, blocking = true)
void onMessage(TargetDiscovery event) {
var target = Target.find("id", event.serviceRef().id).singleResultOptional();
diff --git a/src/main/java/io/cryostat/graphql/ActiveRecordings.java b/src/main/java/io/cryostat/graphql/ActiveRecordings.java
index 0bb85bd7e..4bd7a0bf6 100644
--- a/src/main/java/io/cryostat/graphql/ActiveRecordings.java
+++ b/src/main/java/io/cryostat/graphql/ActiveRecordings.java
@@ -42,7 +42,6 @@
import io.cryostat.targets.Target;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import io.smallrye.common.annotation.Blocking;
import io.smallrye.graphql.api.Nullable;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
@@ -64,7 +63,6 @@ public class ActiveRecordings {
@ConfigProperty(name = ConfigProperties.CONNECTIONS_FAILED_TIMEOUT)
Duration timeout;
- @Blocking
@Transactional
@Mutation
@Description(
@@ -106,7 +104,6 @@ public List createRecording(
return recordings;
}
- @Blocking
@Transactional
@Mutation
@Description(
@@ -138,7 +135,6 @@ public List archiveRecording(
return archives;
}
- @Blocking
@Transactional
@Mutation
@Description(
@@ -169,7 +165,6 @@ public List stopRecording(
return list;
}
- @Blocking
@Transactional
@Mutation
@Description(
@@ -199,7 +194,6 @@ public List deleteRecording(
return list;
}
- @Blocking
@Transactional
@Mutation
@Description(
@@ -222,7 +216,6 @@ public List createSnapshot(@NonNull DiscoveryNodeFilter nodes)
return snapshots;
}
- @Blocking
@Transactional
@Description("Start a new Flight Recording on the specified Target")
public ActiveRecording doStartRecording(
@@ -245,7 +238,6 @@ public ActiveRecording doStartRecording(
.atMost(timeout);
}
- @Blocking
@Transactional
@Description("Create a new Flight Recorder Snapshot on the specified Target")
public ActiveRecording doSnapshot(@Source Target target) {
@@ -253,7 +245,6 @@ public ActiveRecording doSnapshot(@Source Target target) {
return recordingHelper.createSnapshot(fTarget).await().atMost(timeout);
}
- @Blocking
@Transactional
@Description("Stop the specified Flight Recording")
public ActiveRecording doStop(@Source ActiveRecording recording) throws Exception {
@@ -261,7 +252,6 @@ public ActiveRecording doStop(@Source ActiveRecording recording) throws Exceptio
return recordingHelper.stopRecording(ar).await().atMost(timeout);
}
- @Blocking
@Transactional
@Description("Delete the specified Flight Recording")
public ActiveRecording doDelete(@Source ActiveRecording recording) {
@@ -269,7 +259,6 @@ public ActiveRecording doDelete(@Source ActiveRecording recording) {
return recordingHelper.deleteRecording(ar).await().atMost(timeout);
}
- @Blocking
@Description("Archive the specified Flight Recording")
public ArchivedRecording doArchive(@Source ActiveRecording recording) throws Exception {
var ar = ActiveRecording.find("id", recording.id).singleResult();
@@ -317,7 +306,6 @@ public RecordingOptions asOptions() {
}
}
- @Blocking
@Transactional
@Description("Updates the metadata labels for an existing Flight Recording.")
public ActiveRecording doPutMetadata(
diff --git a/src/main/java/io/cryostat/graphql/ArchivedRecordings.java b/src/main/java/io/cryostat/graphql/ArchivedRecordings.java
index 171b355de..941dcfc64 100644
--- a/src/main/java/io/cryostat/graphql/ArchivedRecordings.java
+++ b/src/main/java/io/cryostat/graphql/ArchivedRecordings.java
@@ -29,7 +29,6 @@
import io.cryostat.recordings.Recordings.Metadata;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import io.smallrye.common.annotation.Blocking;
import io.smallrye.graphql.api.Nullable;
import jakarta.inject.Inject;
import org.eclipse.microprofile.graphql.GraphQLApi;
@@ -42,7 +41,6 @@ public class ArchivedRecordings {
@Inject RecordingHelper recordingHelper;
- @Blocking
@Query("archivedRecordings")
public TargetNodes.ArchivedRecordings listArchivedRecordings(ArchivedRecordingsFilter filter) {
var r = new TargetNodes.ArchivedRecordings();
@@ -78,7 +76,6 @@ public ArchivedRecording doDelete(@Source ArchivedRecording recording) {
return recording;
}
- @Blocking
@NonNull
public ArchivedRecording doPutMetadata(
@Source ArchivedRecording recording, MetadataLabels metadataInput) {
diff --git a/src/main/java/io/cryostat/graphql/EnvironmentNodes.java b/src/main/java/io/cryostat/graphql/EnvironmentNodes.java
index c5615312a..d70859989 100644
--- a/src/main/java/io/cryostat/graphql/EnvironmentNodes.java
+++ b/src/main/java/io/cryostat/graphql/EnvironmentNodes.java
@@ -20,7 +20,6 @@
import io.cryostat.discovery.DiscoveryNode;
import io.cryostat.graphql.RootNode.DiscoveryNodeFilter;
-import io.smallrye.common.annotation.Blocking;
import io.smallrye.graphql.api.Nullable;
import org.eclipse.microprofile.graphql.Description;
import org.eclipse.microprofile.graphql.GraphQLApi;
@@ -29,7 +28,6 @@
@GraphQLApi
public class EnvironmentNodes {
- @Blocking
@Query("environmentNodes")
@Description("Get all environment nodes in the discovery tree with optional filtering")
public List environmentNodes(@Nullable DiscoveryNodeFilter filter) {
diff --git a/src/main/java/io/cryostat/graphql/RootNode.java b/src/main/java/io/cryostat/graphql/RootNode.java
index 4af6eefa8..670bbb99f 100644
--- a/src/main/java/io/cryostat/graphql/RootNode.java
+++ b/src/main/java/io/cryostat/graphql/RootNode.java
@@ -24,7 +24,6 @@
import io.cryostat.graphql.matchers.LabelSelectorMatcher;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import io.smallrye.common.annotation.Blocking;
import io.smallrye.graphql.api.Nullable;
import org.eclipse.microprofile.graphql.Description;
import org.eclipse.microprofile.graphql.GraphQLApi;
@@ -34,14 +33,12 @@
@GraphQLApi
public class RootNode {
- @Blocking
@Query("rootNode")
@Description("Get the root target discovery node")
public DiscoveryNode getRootNode() {
return DiscoveryNode.getUniverse();
}
- @Blocking
@Description(
"Get target nodes that are descendants of this node. That is, get the set of leaf nodes"
+ " from anywhere below this node's subtree.")
diff --git a/src/main/java/io/cryostat/graphql/TargetNodes.java b/src/main/java/io/cryostat/graphql/TargetNodes.java
index f2f0e3dbc..afe9eb9f8 100644
--- a/src/main/java/io/cryostat/graphql/TargetNodes.java
+++ b/src/main/java/io/cryostat/graphql/TargetNodes.java
@@ -33,7 +33,6 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import graphql.schema.DataFetchingEnvironment;
-import io.smallrye.common.annotation.Blocking;
import io.smallrye.graphql.api.Context;
import io.smallrye.graphql.api.Nullable;
import jakarta.inject.Inject;
@@ -51,7 +50,6 @@ public class TargetNodes {
@Inject RecordingHelper recordingHelper;
@Inject TargetConnectionManager connectionManager;
- @Blocking
@Query("targetNodes")
@Description("Get the Target discovery nodes, i.e. the leaf nodes of the discovery tree")
public List getTargetNodes(DiscoveryNodeFilter filter) {
@@ -69,12 +67,6 @@ public List getTargetNodes(DiscoveryNodeFilter filter) {
.toList();
}
- // private static Predicate distinctWith(Function super T, ?> fn) {
- // Set