HawtIO Diagnostic Console Guide Red Hat build of Apache Camel 4.8 Manage applications with Red Hat build of HawtIO

Commands:
<?xml version="1.0"?> <settings> <profiles> <profile> <id>extra-repos</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>redhat-ga-repository</id> <url>https://maven.repository.redhat.com/ga</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>redhat-ea-repository</id> <url>https://maven.repository.redhat.com/earlyaccess/all</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>redhat-ga-repository</id> <url>https://maven.repository.redhat.com/ga</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>redhat-ea-repository</id> <url>https://maven.repository.redhat.com/earlyaccess/all</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles> <activeProfiles> <activeProfile>extra-repos</activeProfile> </activeProfiles> </settings>
jbang app install -Dhawtio.jbang.version=4.1.0.redhat-00015 hawtio@hawtio/hawtio
hawtio
hawtio --port 8090
hawtio --help Usage: hawtio [-hjoV] [-c=<contextPath>] [-d=<plugins>] [-e=<extraClassPath>] [-H=<host>] [-k=<keyStore>] [-l=<warLocation>] [-p=<port>] [-s=<keyStorePass>] [-w=<war>] Run HawtIO -c, --context-path=<contextPath> Context path. -d, --plugins-dir=<plugins> Directory to search for .war files to install as 3rd party plugins. -e, --extra-class-path=<extraClassPath> Extra class path. -h, --help Print usage help and exit. -H, --host=<host> Hostname to listen to. -j, --join Join server thread. -k, --key-store=<keyStore> JKS keyStore with the keys for https. -l, --war-location=<warLocation> Directory to search for .war files. -o, --open-url Open the web console automatic in the web browser. -p, --port=<port> Port number. -s, --key-store-pass=<keyStorePass> Password for the JKS keyStore with the keys for https. -V, --version Print HawtIO version -w, --war=<war> War file or directory of the hawtio web application.
<dependencyManagement> <dependencies> <dependency> <groupId>io.hawt</groupId> <artifactId>hawtio-bom</artifactId> <version>4.1.0.redhat-00015</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> <!-- ... other BOMs or dependencies ... --> </dependencyManagement> <dependencies> <dependency> <groupId>io.hawt</groupId> <artifactId>hawtio-quarkus</artifactId> </dependency> <!-- Mandatory for enabling Camel management via JMX / HawtIO --> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-management</artifactId> </dependency> <!-- (Optional) Required for HawtIO Camel route diagram tab --> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-jaxb</artifactId> </dependency> <!-- ... other dependencies ... --> </dependencies>
quarkus.hawtio.authenticationEnabled = false
mvn compile quarkus:dev
<dependencyManagement> <dependencies> <dependency> <groupId>io.hawt</groupId> <artifactId>hawtio-bom</artifactId> <version>4.1.0.redhat-00015</version> <type>pom</type> <scope>import</scope> </dependency> <!-- ... other BOMs or dependencies ... --> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.hawt</groupId> <artifactId>hawtio-springboot</artifactId> </dependency> <!-- Mandatory for enabling Camel management via JMX / HawtIO --> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-management-starter</artifactId> </dependency> <!-- (Optional) Required for HawtIO Camel route diagram tab --> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-xml-starter</artifactId> </dependency> <!-- ... other dependencies ... --> </dependencies>
spring.jmx.enabled = true management.endpoints.web.exposure.include = hawtio,jolokia
mvn spring-boot:run
management.endpoints.web.base-path = /
management.endpoints.web.path-mapping.hawtio = hawtio/console
quarkus.hawtio.disableProxy = true
hawtio.disableProxy = true
jolokia.policyLocation = file:///opt/hawtio/my-jolokia-access.xml
{ "branding": { "appName": "HawtIO Management Console", "showAppName": false, "appLogoUrl": "hawtio-logo.svg", "companyLogoUrl": "hawtio-logo.svg", "css": "", "favicon": "favicon.ico" }, "login": { "description": "Login page for HawtIO Management Console.", "links": [ { "url": "#terms", "text": "Terms of Use" }, { "url": "#help", "text": "Help" }, { "url": "#privacy", "text": "Privacy Policy" } ] }, "about": { "title": "HawtIO Management Console", "description": "A HawtIO reimplementation based on TypeScript + React.", "imgSrc": "hawtio-logo.svg", "productInfo": [ { "name": "ABC", "value": "1.2.3" }, { "name": "XYZ", "value": "7.8.9" } ], "copyright": "(c) HawtIO project" }, "disabledRoutes": [ "/disabled" ] }
"branding": { "appName": "HawtIO Management Console", "showAppName": false, "appLogoUrl": "hawtio-logo.svg", "companyLogoUrl": "hawtio-logo.svg", "css": "", "favicon": "favicon.ico" }
"login": { "description": "Login page for HawtIO Management Console.", "links": [ { "url": "#terms", "text": "Terms of Use" }, { "url": "#help", "text": "Help" }, { "url": "#privacy", "text": "Privacy Policy" } ] }
"about": { "title": "HawtIO Management Console", "description": "A HawtIO reimplementation based on TypeScript + React.", "imgSrc": "hawtio-logo.svg", "productInfo": [ { "name": "ABC", "value": "1.2.3" }, { "name": "XYZ", "value": "7.8.9" } ], "copyright": "(c) HawtIO project" }
"disabledRoutes": [ "/disabled" ]
<domain>/<prop1>=<value1>,<prop2>=<value2>,
"jmx": { "workspace": [ "hawtio", "java.lang/type=Memory", "org.apache.camel", "no.such.domain" ] }
"online": { "projectSelector": "myproject", "consoleLink": { "text": "HawtIO Management Console", "section": "HawtIO", "imageRelativePath": "/online/img/favicon.ico" } }
import { HawtIOPlugin, configManager } from '@hawtio/react' /** * The entry function of your plugin. */ export const plugin: HawtIOPlugin = () => { } // Register the custom plugin version to HawtIO // See package.json "replace-version" script for how to replace the version placeholder with a real version configManager.addProductInfo('HawtIO Sample Plugin', '__PACKAGE_VERSION_PLACEHOLDER__') /* * This example also demonstrates how branding and styles can be customised from a WAR plugin. * * The Plugin API `configManager` provides `configure(configurer: (config: Hawtconfig) => void)` method * and you can customise the `Hawtconfig` by invoking it from the plugin's `index.ts`. */ configManager.configure(config => { // Branding & styles config.branding = { appName: 'HawtIO Sample WAR Plugin', showAppName: true, appLogoUrl: '/sample-plugin/branding/Logo-RedHat-A-Reverse-RGB.png', css: '/sample-plugin/branding/app.css', favicon: '/sample-plugin/branding/favicon.ico', } // Login page config.login = { description: 'Login page for HawtIO Sample WAR Plugin application.', links: [ { url: '#terms', text: 'Terms of use' }, { url: '#help', text: 'Help' }, { url: '#privacy', text: 'Privacy policy' }, ], } // About modal if (!config.about) { config.about = {} } config.about.title = 'HawtIO Sample WAR Plugin' config.about.description = 'About page for HawtIO Sample WAR Plugin application.' config.about.imgSrc = '/sample-plugin/branding/Logo-RedHat-A-Reverse-RGB.png' if (!config.about.productInfo) { config.about.productInfo = [] } config.about.productInfo.push( { name: 'HawtIO Sample Plugin - simple-plugin', value: '1.0.0' }, { name: 'HawtIO Sample Plugin - custom-tree', value: '1.0.0' }, ) // If you want to disable specific plugins, you can specify the paths to disable them. //config.disabledRoutes = ['/simple-plugin'] })
quarkus.hawtio.authenticationEnabled = false
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-elytron-security-properties-file</artifactId> </dependency>
quarkus.security.users.embedded.enabled = true quarkus.security.users.embedded.plain-text = true quarkus.security.users.embedded.users.hawtio = s3cr3t! quarkus.security.users.embedded.roles.hawtio = admin
hawtio.authenticationEnabled = false
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
spring.security.user.name = hawtio spring.security.user.password = s3cr3t! spring.security.user.roles = admin,viewer
@EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated() ) .formLogin(withDefaults()) .httpBasic(withDefaults()) .csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .csrfTokenRequestHandler(new SpaCsrfTokenRequestHandler()) ) .addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class); return http.build(); } }
import org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaEndpoint; import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // Disable CSRF protection for the Jolokia endpoint http.csrf().ignoringRequestMatchers(EndpointRequest.to(JolokiaEndpoint.class)); return http.build(); } }
<restrict> <cors> <allow-origin>http*://localhost:*</allow-origin> <allow-origin>http*://127.0.0.1:*</allow-origin> <allow-origin>http*://*.example.com</allow-origin> <allow-origin>http*://*.example.com:*</allow-origin> <strict-checking /> </cors> </restrict>
docker run -d --name keycloak -p 18080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak start-dev
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency>
quarkus.oidc.auth-server-url = http://localhost:18080/realms/hawtio-demo quarkus.oidc.client-id = hawtio-client quarkus.oidc.credentials.secret = secret quarkus.oidc.application-type = web-app quarkus.oidc.token-state-manager.split-tokens = true quarkus.http.auth.permission.authenticated.paths = "/*" quarkus.http.auth.permission.authenticated.policy = authenticated
realm: hawtio-demo
clientId: hawtio-client
url: http://localhost:18080/
jaas: no
pkceMethod: S256
<dependency> <groupId>io.hawt</groupId> <artifactId>hawtio-springboot-keycloak</artifactId> <version>4.x.y</version> </dependency>
keycloak.realm = hawtio-demo keycloak.resource = hawtio-client keycloak.auth-server-url = http://localhost:18080/ keycloak.ssl-required = external keycloak.public-client = true keycloak.principal-attribute = preferred_username
realm: hawtio-demo
clientId: hawtio-client
url: http://localhost:18080/
jaas: no
auth can-i update pods/<pod> --as <user>
auth can-i get pods/<pod> --as <user>
project hawtio-test
process -f https://raw.githubusercontent.com/hawtio/hawtio-online/2.x/docker/ACL.yaml -p APP_NAME=custom-hawtio | oc create -f -
edit ConfigMap custom-hawtio-rbac
apiVersion: hawt.io/v1 kind: HawtIO metadata: name: hawtio-console spec: type: Namespace nginx: clientBodyBufferSize: 256k proxyBuffers: 16 128k subrequestOutputBufferSize: 100m
camel.routecontroller.enabled = true
mvn archetype:generate -DarchetypeGroupId=org.apache.camel.archetypes -DarchetypeArtifactId=camel-archetype-spring-boot -DarchetypeVersion=4.8.0.redhat-00022 -DgroupId=io.hawt.online.examples -DartifactId=hawtio-online-example -Dversion=1.0.0 -DinteractiveMode=false -Dpackage=io.hawtio
mvn spring-boot:run
<dependencies> <!-- Camel --> <!-- Dependency is mandatory for exposing Jolokia endpoint --> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-jolokia-starter</artifactId> </dependency> <!-- Optional: enables debugging support for Camel --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-debug</artifactId> <version>4.8.0</version> </dependency> </dependencies>
camel.springboot.inflight-repository-browse-enabled=true
spec: containers: - name: my-container ports: - name: jolokia containerPort: 8778 protocol: TCP ..... ....
mvn clean install -DskipTests -P openshift
mvn io.quarkus.platform:quarkus-maven-plugin:3.14.2:create -DprojectGroupId=org.hawtio -DprojectArtifactId=quarkus-helloworld -Dextensions='openshift,camel-quarkus-quartz'
Set the Docker build strategy quarkus.openshift.build-strategy=docker # Expose the service to create an OpenShift Container Platform route quarkus.openshift.route.expose=true
package org.hawtio; import jakarta.enterprise.context.ApplicationScoped; import org.apache.camel.builder.endpoint.EndpointRouteBuilder; @ApplicationScoped public class SampleCamelRoute extends EndpointRouteBuilder { @Override public void configure() { from(quartz("cron").cron("{{quartz.cron}}")).routeId("cron") .setBody().constant("Hello Camel! - cron") .to(stream("out")) .to(mock("result")); from("quartz:simple?trigger.repeatInterval={{quartz.repeatInterval}}").routeId("simple") .setBody().constant("Hello Camel! - simple") .to(stream("out")) .to(mock("result")); } }
Camel camel.context.name = SampleCamel # Uncomment the following to enable the Camel plugin Trace tab #camel.main.tracing = true #camel.main.backlogTracing = true #camel.main.useBreadcrumb = true # Uncomment to enable debugging of the application and in turn # enables the Camel plugin Debug tab even in non-development # environment #quarkus.camel.debug.enabled = true # Define properties for the Camel quartz component used in the # example quartz.cron = 0/10 * * * * ? quartz.repeatInterval = 10000
<dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-stream</artifactId> </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-mock</artifactId> </dependency>
<resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources>
<properties> <!-- The current HawtIO Jolokia Version --> <jolokia-version>2.1.0</jolokia-version> <!-- =============================================================== === Jolokia agent configuration for the connection with HawtIO =============================================================== It should use HTTPS and SSL client authentication at minimum. The client principal should match those the HawtIO instance provides (the default is `hawtio-online.hawtio.svc`). --> <jolokia.protocol>https</jolokia.protocol> <jolokia.host>*</jolokia.host> <jolokia.port>8778</jolokia.port> <jolokia.useSslClientAuthentication>true</jolokia.useSslClientAuthentication> <jolokia.caCert>/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt</jolokia.caCert> <jolokia.clientPrincipal.1>cn=hawtio-online.hawtio.svc</jolokia.clientPrincipal.1> <jolokia.extendedClientCheck>true</jolokia.extendedClientCheck> <jolokia.discoveryEnabled>false</jolokia.discoveryEnabled> </properties>
<!-- This dependency is required for enabling Camel management via JMX / HawtIO. --> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-management</artifactId> </dependency> <!-- This dependency is optional for monitoring with HawtIO but is required for HawtIO view the Camel routes source XML. --> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-jaxb</artifactId> </dependency> <!-- Add this optional dependency, to enable Camel plugin debugging feature. --> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-debug</artifactId> </dependency> <!-- This dependency is required to include the Jolokia agent jvm for access to JMX beans. --> <dependency> <groupId>org.jolokia</groupId> <artifactId>jolokia-agent-jvm</artifactId> <version>USD{jolokia-version}</version> <classifier>javaagent</classifier> </dependency>
Enable the jolokia java-agent on the quarkus application quarkus.openshift.env.vars.JAVA_OPTS_APPEND=-javaagent:lib/main/org.jolokia.jolokia-agent-jvm-USD{jolokia-version}-javaagent.jar=protocol=USD{jolokia.protocol}\,host=USD{jolokia.host}\,port=USD{jolokia.port}\,useSslClientAuthentication=USD{jolokia.useSslClientAuthentication}\,caCert=USD{jolokia.caCert}\,clientPrincipal.1=USD{jolokia.clientPrincipal.1}\,extendedClientCheck=USD{jolokia.extendedClientCheck}\,discoveryEnabled=USD{jolokia.discoveryEnabled}
Define the Jolokia port on the container for HawtIO access quarkus.openshift.ports.jolokia.container-port=USD{jolokia.port} quarkus.openshift.ports.jolokia.protocol=TCP
./mvnw clean package -Dquarkus.kubernetes.deploy=true
OpenID Connect configuration requred at client side URL of OpenID Connect Provider - the URL after which ".well-known/openid-configuration" can be appended for discovery purposes provider = http://localhost:18080/realms/hawtio-demo OpenID client identifier client_id = hawtio-client response mode according to https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html response_mode = fragment scope to request when performing OpenID authentication. MUST include "openid" and required permissions scope = openid email profile redirect URI after OpenID authentication - must also be configured at provider side redirect_uri = http://localhost:8080/hawtio challenge method according to https://datatracker.ietf.org/doc/html/rfc7636 code_challenge_method = S256 prompt hint according to https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest prompt = login additional configuration for the server side if true, .well-known/openid-configuration will be fetched at server side. This is required for proper JWT access token validation oidc.cacheConfig = true time in minutes to cache public keys from jwks_uri jwks.cacheTime = 60 a path for an array of roles found in JWT payload. Property placeholders can be used for parameterized parts of the path (like for Keycloak) - but only for properties from this particular file example for properly configured Entra ID token #oidc.rolesPath = roles example for Keycloak with use-resource-role-mappings=true #oidc.rolesPath = resource_access.USD{client_id}.roles example for Keycloak with use-resource-role-mappings=false oidc.rolesPath = realm_access.roles properties for role mapping. Each property with "roleMapping." prefix is used to map an original role from JWT token (found at USD{oidc.rolesPath}) to a role used by the application roleMapping.admin = admin roleMapping.user = user roleMapping.viewer = viewer roleMapping.manager = manager timeout for connection establishment (milliseconds) http.connectionTimeout = 5000 timeout for reading from established connection (milliseconds) http.readTimeout = 10000 HTTP proxy to use when connecting to OpenID Connect provider #http.proxyURL = http://127.0.0.1:3128 TLS configuration (system properties can be used, e.g., "USD{catalina.home}/conf/hawtio.jks") #ssl.protocol = TLSv1.3 #ssl.truststore = src/test/resources/hawtio.jks #ssl.truststorePassword = hawtio #ssl.keystore = src/test/resources/hawtio.jks #ssl.keystorePassword = hawtio #ssl.keyAlias = openid connect test provider #ssl.keyPassword = hawtio
-Dhawtio.rolePrincipalClasses=org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal
run -d --name keycloak -p 18080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:latest start-dev
{ "exp": 1709552728, "iat": 1709552428, "jti": "0f33971f-c4f7-4a5c-a240-c18ba3f97aa1", "iss": "http://localhost:18080/realms/hawtio-demo", "aud": "account", "sub": "84d156fa-e4cc-4785-91c1-4e0bda4b8ed9", "typ": "Bearer", "azp": "hawtio-client", "session_state": "181a30ac-fce1-4f4f-aaee-110304ccb0e6", "acr": "1", "allowed-origins": [ "http://0.0.0.0:8181", "http://localhost:8080", "http://localhost:8181", "http://0.0.0.0:10001", "http://0.0.0.0:8080", "http://localhost:10001", "http://localhost:10000", "http://0.0.0.0:10000" ], "realm_access": { "roles": [ "viewer", "manager", "admin", "user" ] }, "resource_access": { "account": { "roles": [ "manage-account", "manage-account-links", "view-profile" ] } }, "scope": "openid profile email", "sid": "181a30ac-fce1-4f4f-aaee-110304ccb0e6", "email_verified": false, "name": "Admin HawtIO", "preferred_username": "admin", "given_name": "Admin", "family_name": "HawtIO", "email": "admin@hawt.io" }
example for Keycloak with use-resource-role-mappings=false oidc.rolesPath = realm_access.roles
OpenID Connect configuration requred at client side URL of OpenID Connect Provider - the URL after which ".well-known/openid-configuration" can be appended for discovery purposes provider = https://login.microsoftonline.com/00000000-1111-2222-3333-444444444444/v2.0 OpenID client identifier client_id = 55555555-6666-7777-8888-999999999999 response mode according to https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html response_mode = fragment scope to request when performing OpenID authentication. MUST include "openid" and required permissions scope = openid email profile redirect URI after OpenID authentication - must also be configured at provider side redirect_uri = http://localhost:8080/hawtio challenge method according to https://datatracker.ietf.org/doc/html/rfc7636 code_challenge_method = S256 prompt hint according to https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest prompt = login
aud: 00000003-0000-0000-c000-000000000000
iss: https://sts.windows.net/8fd8ed3d-c739-410f-83ab-ac2228fa6bbf/
app_displayname: hawtio
scp: email openid profile User.Read
scope to request when performing OpenID authentication. MUST include "openid" and required permissions scope = openid email profile api://hawtio-server/Jolokia.Access
"optionalClaims": { "idToken": [ { "name": "groups", "source": null, "essential": false, "additionalProperties": [] } ], "accessToken": [ { "name": "groups", "source": null, "essential": false, "additionalProperties": [ "sam_account_name" ] },
{ "aud": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "iss": "https://sts.windows.net/.../", "iat": 1709626257, "nbf": 1709626257, "exp": 1709630939, "appid": "55555555-6666-7777-8888-999999999999", "groups": [ ], "name": "hawtio-viewer", "roles": [ "HawtIO.User" ], "scp": "Jolokia.Access",
a path for an array of roles found in JWT payload. Property placeholders can be used for parameterized parts of the path (like for Keycloak) - but only for properties from this particular file example for properly configured Entra ID token #oidc.rolesPath = roles properties for role mapping. Each property with "roleMapping." prefix is used to map an original role from JWT token (found at USD{oidc.rolesPath}) to a role used by the application roleMapping.HawtIO.User = user