Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/activemq/_dev/build/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@

## Compatibility

This integration has been tested against ActiveMQ 5.17.1 (independent from the operating system).
This integration targets **Apache ActiveMQ Classic**. Elastic package system tests can run against **ActiveMQ Classic 6.2.2** (default) or **5.17.1** (see `_dev/deploy/variants.yml`). Use a **Java 17 or newer** JVM in the test image; ActiveMQ Classic 6.2.x requires Java 17+ on the broker, and 5.17.x runs on Java 17 for these tests.

Check notice on line 33 in packages/activemq/_dev/build/docs/README.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Elastic.Versions: Use 'or later' instead of 'or newer' when referring to versions.

Metrics are collected through the embedded **Jolokia** endpoint (Jolokia 2.x in ActiveMQ 6.2.x). The default path (`/api/jolokia/?ignoreErrors=true&canonicalNaming=false`) matches the web console `/api` context from the upstream distribution.

Log and audit parsing follow the default log line formats described below, which match the pipeline test fixtures for this package.

## What do I need to use this integration?

Expand Down
6 changes: 3 additions & 3 deletions packages/activemq/_dev/deploy/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM eclipse-temurin:11-jre
FROM eclipse-temurin:17-jre

ARG SERVICE_VERSION=${SERVICE_VERSION:-5.17.1}
ARG SERVICE_VERSION=${SERVICE_VERSION:-6.2.2}
ENV ACTIVEMQ_VERSION=${SERVICE_VERSION}

ENV ACTIVEMQ_HOME /opt/activemq
Expand Down Expand Up @@ -31,4 +31,4 @@ EXPOSE $ACTIVEMQ_STOMP $ACTIVEMQ_REST
HEALTHCHECK --interval=1s --retries=90 CMD nc -w 1 -v 127.0.0.1 $ACTIVEMQ_STOMP </dev/null && \
nc -w 1 -v 127.0.0.1 $ACTIVEMQ_REST </dev/null

CMD ["/bin/sh", "-c", "bin/activemq console & ./entrypoint.d/entrypoint.sh"]
CMD ["/bin/sh", "-c", "./entrypoint.d/entrypoint.sh"]
8 changes: 5 additions & 3 deletions packages/activemq/_dev/deploy/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ services:
build: .
volumes:
- ./sample_logs:/sample_logs:ro
- ${SERVICE_LOGS_DIR}:/opt/apache-activemq-5.17.1/logs/
- ./files/jetty.xml:/opt/apache-activemq-5.17.1/conf/jetty.xml
- ./files/jolokia-access.xml:/opt/apache-activemq-5.17.1/conf/jolokia-access.xml
- ${SERVICE_LOGS_DIR}:/opt/activemq/logs/
- ./files/jetty-5.17.xml:/integration-templates/jetty-5.17.xml:ro
- ./files/jetty-6.2.xml:/integration-templates/jetty-6.2.xml:ro
- ./files/jolokia-5.17.xml:/integration-templates/jolokia-5.17.xml:ro
- ./files/jolokia-6.2.xml:/integration-templates/jolokia-6.2.xml:ro
ports:
- 8161
- 61613
26 changes: 20 additions & 6 deletions packages/activemq/_dev/deploy/docker/entrypoint.d/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
#!/bin/sh
# Install Jetty / Jolokia overrides that match the ActiveMQ major line before the broker starts.
case "${ACTIVEMQ_VERSION}" in
5.*)
cp /integration-templates/jetty-5.17.xml "${ACTIVEMQ_HOME}/conf/jetty.xml"
cp /integration-templates/jolokia-5.17.xml "${ACTIVEMQ_HOME}/conf/jolokia-access.xml"
;;
*)
cp /integration-templates/jetty-6.2.xml "${ACTIVEMQ_HOME}/conf/jetty.xml"
cp /integration-templates/jolokia-6.2.xml "${ACTIVEMQ_HOME}/conf/jolokia-access.xml"
;;
esac

# Whenever docker container is ran it will remove log files from SERVICE_LOGS_DIR, so to make them accessible again for the docker container to run system test,
# following commands will help to copy and accesses these files from SERVICE_LOGS_DIR again.
mkdir logs
cp /sample_logs/* /opt/apache-activemq-5.17.1/logs/
chmod a+rw -R /opt/apache-activemq-5.17.1/logs/
# following commands will help to copy and accesses these files from SERVICE_LOGS_DIR again.
mkdir -p "${ACTIVEMQ_HOME}/logs"
cp /sample_logs/* "${ACTIVEMQ_HOME}/logs/" 2>/dev/null || true
chmod a+rw -R "${ACTIVEMQ_HOME}/logs/"

bin/activemq console &
sleep 10

while :
do
curl -u admin:admin -d "body=message" http://localhost:8161/api/message/TEST?type=queue
sleep 1
sleep 1
done

219 changes: 219 additions & 0 deletions packages/activemq/_dev/deploy/docker/files/jetty-6.2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for additional
information regarding copyright ownership. The ASF licenses this file to You 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.
-->
<!--
An embedded servlet engine for serving up the Admin consoles, REST and Ajax APIs and
some demos Include this file in your configuration to enable ActiveMQ web components
e.g. <import resource="jetty.xml"/>
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<property name="sendServerVersion" value="false"/>
</bean>

<bean id="jaasLoginService" class="org.eclipse.jetty.jaas.JAASLoginService">
<property name="name" value="ActiveMQRealm"/>
<property name="loginModuleName" value="activemq"/>
<property name="roleClassNames">
<list>
<value>org.apache.activemq.jaas.GroupPrincipal</value>
</list>
</property>
</bean>

<bean id="identityService" class="org.eclipse.jetty.security.DefaultIdentityService"/>

<bean id="securityConstraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="BASIC" />
<property name="roles" value="users,admins" />
<!-- set authenticate=false to disable login -->
<property name="authenticate" value="true" />
</bean>
<bean id="adminSecurityConstraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="BASIC" />
<property name="roles" value="admins" />
<!-- set authenticate=false to disable login -->
<property name="authenticate" value="true" />
</bean>
<bean id="securityConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="securityConstraint" />
<property name="pathSpec" value="/" />
</bean>
<bean id="adminSecurityConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="adminSecurityConstraint" />
<property name="pathSpec" value="*.action" />
</bean>

<bean id="rewriteHandler" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
<property name="rules">
<list>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-FRAME-OPTIONS"/>
<property name="value" value="SAMEORIGIN"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-XSS-Protection"/>
<property name="value" value="1; mode=block"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-Content-Type-Options"/>
<property name="value" value="nosniff"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Cache-Control"/>
<property name="value" value="no-store"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Content-Security-Policy"/>
<property name="value" value="style-src-elem 'self'; style-src 'self'; img-src 'self'; script-src-elem 'self'; default-src 'none'; object-src 'none'; frame-ancestors 'none'; base-uri 'none';" />
</bean>
<!-- More relaxed rules to allow browsers to properly render XML -->
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
Comment on lines +62 to +88
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These HeaderPatternRule beans are all declared with the same bean id ("header"). In Spring XML, bean ids are expected to be unique; duplicates can either fail parsing or silently override earlier definitions depending on the bean factory settings. Drop the id attributes (since they are not referenced) or make them unique to avoid unpredictable behavior.

Suggested change
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-FRAME-OPTIONS"/>
<property name="value" value="SAMEORIGIN"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-XSS-Protection"/>
<property name="value" value="1; mode=block"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-Content-Type-Options"/>
<property name="value" value="nosniff"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Cache-Control"/>
<property name="value" value="no-store"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Content-Security-Policy"/>
<property name="value" value="style-src-elem 'self'; style-src 'self'; img-src 'self'; script-src-elem 'self'; default-src 'none'; object-src 'none'; frame-ancestors 'none'; base-uri 'none';" />
</bean>
<!-- More relaxed rules to allow browsers to properly render XML -->
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<bean class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-FRAME-OPTIONS"/>
<property name="value" value="SAMEORIGIN"/>
</bean>
<bean class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-XSS-Protection"/>
<property name="value" value="1; mode=block"/>
</bean>
<bean class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="X-Content-Type-Options"/>
<property name="value" value="nosniff"/>
</bean>
<bean class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Cache-Control"/>
<property name="value" value="no-store"/>
</bean>
<bean class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Content-Security-Policy"/>
<property name="value" value="style-src-elem 'self'; style-src 'self'; img-src 'self'; script-src-elem 'self'; default-src 'none'; object-src 'none'; frame-ancestors 'none'; base-uri 'none';" />
</bean>
<!-- More relaxed rules to allow browsers to properly render XML -->
<bean class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">

Copilot uses AI. Check for mistakes.
<property name="pattern" value="/admin/xml/*"/>
<property name="name" value="Content-Security-Policy"/>
<property name="value" value="style-src-elem 'self' 'unsafe-inline'; style-src 'self'; img-src 'self' data:; script-src-elem 'self'; default-src 'none'; object-src 'none'; frame-ancestors 'none'; base-uri 'none';" />
</bean>
</list>
</property>
</bean>

<bean id="secHandlerCollection" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="rewriteHandler"/>
<bean class="org.eclipse.jetty.webapp.WebAppContext">
<property name="contextPath" value="/admin" />
<property name="resourceBase" value="${activemq.home}/webapps/admin" />
<property name="logUrlOnStart" value="true" />
</bean>
<bean class="org.eclipse.jetty.webapp.WebAppContext">
<property name="contextPath" value="/api" />
<property name="resourceBase" value="${activemq.home}/webapps/api" />
<property name="logUrlOnStart" value="true" />
</bean>
<bean class="org.eclipse.jetty.server.handler.ResourceHandler">
<property name="directoriesListed" value="false" />
<property name="welcomeFiles">
<list>
<value>index.html</value>
</list>
</property>
<property name="resourceBase" value="${activemq.home}/webapps/" />
</bean>
<bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler">
<property name="serveIcon" value="false" />
</bean>
</list>
</property>
</bean>
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="identityService" ref="identityService" />
<property name="loginService" ref="jaasLoginService" />
<property name="authenticator">
<bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator" />
</property>
<property name="constraintMappings">
<list>
<ref bean="adminSecurityConstraintMapping" />
<ref bean="securityConstraintMapping" />
</list>
</property>
<property name="handler" ref="secHandlerCollection" />
</bean>

<bean id="contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
</bean>

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="0.0.0.0"/>
<property name="port" value="8161"/>
</bean>

<bean id="Server" depends-on="jettyPort" class="org.eclipse.jetty.server.Server"
destroy-method="stop">

<property name="handler">
<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="contexts" />
<ref bean="securityHandler" />
</list>
</property>
</bean>
</property>

</bean>

<bean id="invokeConnectors" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="Server" />
<property name="targetMethod" value="setConnectors" />
<property name="arguments">
<list>
<bean id="Connector" class="org.eclipse.jetty.server.ServerConnector">
<constructor-arg ref="Server"/>
<constructor-arg>
<list>
<bean id="httpConnectionFactory" class="org.eclipse.jetty.server.HttpConnectionFactory">
<constructor-arg ref="httpConfig"/>
</bean>
</list>
</constructor-arg>
<!-- see the jettyPort bean -->
<property name="host" value="#{systemProperties['jetty.host']}" />
<property name="port" value="#{systemProperties['jetty.port']}" />
</bean>
<!--
Enable this connector if you wish to use https with web console
-->
<!-- bean id="SecureConnector" class="org.eclipse.jetty.server.ServerConnector">
<constructor-arg ref="Server" />
<constructor-arg>
<bean id="handlers" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
<property name="keyStorePath" value="${activemq.conf}/broker.ks" />
<property name="keyStorePassword" value="password" />
</bean>
</constructor-arg>
<property name="port" value="8162" />
</bean -->
</list>
</property>
</bean>

<bean id="configureJetty" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.activemq.web.config.JspConfigurer.configureJetty" />
<property name="arguments">
<list>
<ref bean="Server" />
<ref bean="secHandlerCollection" />
</list>
</property>
</bean>

<bean id="invokeStart" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="configureJetty, invokeConnectors">
<property name="targetObject" ref="Server" />
<property name="targetMethod" value="start" />
</bean>


</beans>

81 changes: 81 additions & 0 deletions packages/activemq/_dev/deploy/docker/files/jolokia-6.2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.

Based on Apache ActiveMQ Classic 6.2.x conf/jolokia-access.xml, with relaxed
CORS and HTTP method settings so Elastic Agent / Metricbeat can read metrics
without browser Origin headers during integration tests.
-->
<restrict>

<cors>
<allow-origin>http://localhost:*</allow-origin>
<allow-origin>http://127.0.0.1:*</allow-origin>
<allow-origin>*</allow-origin>
Comment on lines +20 to +27
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<allow-origin>*</allow-origin> makes the Jolokia endpoint permissive to any Origin. Even for system tests, it’s safer to avoid the wildcard and allow only the origins you need (localhost/127.0.0.1) or explicitly document that this file must only be used in local/CI test environments and never in production-like deployments.

Suggested change
without browser Origin headers during integration tests.
-->
<restrict>
<cors>
<allow-origin>http://localhost:*</allow-origin>
<allow-origin>http://127.0.0.1:*</allow-origin>
<allow-origin>*</allow-origin>
without browser Origin headers during integration tests. This file is for
local/CI test environments only and restricts browser origins to localhost
and 127.0.0.1 instead of allowing arbitrary origins.
-->
<restrict>
<cors>
<allow-origin>http://localhost:*</allow-origin>
<allow-origin>http://127.0.0.1:*</allow-origin>

Copilot uses AI. Check for mistakes.
</cors>

<http>
<method>post</method>
<method>get</method>
</http>

<!-- By default don't allow write or exec operations -->
<commands>
<command>read</command>
<command>list</command>
<command>version</command>
<command>search</command>
</commands>

<allow>
<!-- Allow all operations for the broker itself -->
<mbean>
<name>org.apache.activemq:*</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<!-- Allow all operations for Jolokia Config -->
<mbean>
<name>jolokia:type=Config</name>
<operation>*</operation>
</mbean>
</allow>

<!-- deny all operations or getting attributes from these mbeans -->
<deny>
<mbean>
<name>org.apache.logging.log4j2:*</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>com.sun.management:type=DiagnosticCommand</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>com.sun.management:type=HotSpotDiagnostic</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>jdk.management.jfr:type=FlightRecorder</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
</deny>

</restrict>
4 changes: 3 additions & 1 deletion packages/activemq/_dev/deploy/variants.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
variants:
"v6.2.2":
SERVICE_VERSION: 6.2.2
"v5.17.1":
SERVICE_VERSION: 5.17.1
default: v5.17.1
default: v6.2.2
5 changes: 5 additions & 0 deletions packages/activemq/changelog.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# newer versions go on top
- version: "1.10.0"
changes:
- description: Align system tests and documentation with Apache ActiveMQ Classic 6.2.x (Java 17, Jetty 11 / Jolokia 2.x). Update deploy Docker assets (paths, version-specific jetty/jolokia templates) while keeping the 5.17.1 service variant for regression tests.
type: enhancement
link: https://github.com/elastic/integrations/pull/18417
- version: "1.9.0"
changes:
- description: Improve documentation
Expand Down
Loading
Loading