How to turn on schedulerSupport in TomEE ActiveMQ - activemq

I have never configured activemq, I just use the totally default configuration in TomEE Plus 1.7.1 and it works perfectly. I use JMS for asynchron e-mail sending. Now I would like to use the scheduler support, like this:
...
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY,
delayMinute * 60000);
...
But message is not delayed. I read that schedulerSupport should have been turned on in an xml file (probably activemq.xml (?)) but I don't have such a file.
I tried this in tomee.xml, but it does not work:
<Resource id="myActiveMQResourceAdapter" type="ActiveMQResourceAdapter">
schedulerSupport = true
</Resource>
Where should I put the schedulerSupport = true configuration property? I don't want to declare new Broker's or any other things. Just I would like to use the default settings plus scheduler support.

Scheduler support is disabled by default in ActiveMQ. In order to use it you must set the property 'schedulerSupport' to true which means you will need to modify the default broker configuration, no way around that.
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">

Related

RabbitMQ SSL Connection with Apring AMQP 1.4.3

I am trying to connect to RabbitMQ over SSL. I have followed the RabbitMQ SSL documentation linked [here}(https://www.rabbitmq.com/ssl.html).
As per RabbitMQ SSL documentation connecting using SSLv3 and TLSv1 is not recommeded due to known vulnerabilities. Due to this I have disabled these protocols on RabbitMQ as per instructions.
I am using Spring AMQP 1.4.3 to connect to RabbitMQ.
ApplicationContext context = new GenericXmlApplicationContext("classpath:/testConfig/testrabbit-context.xml");
RabbitTemplate template = context.getBean(RabbitTemplate.class);
MessageProperties messageProperties = new MessageProperties();
org.springframework.amqp.core.Message amqpMessage = new org.springframework.amqp.core.Message("Test".getBytes(), messageProperties);
String routingKey = "TEST.businessevent.route";
template.send(routingKey, amqpMessage);
My config:
<rabbit:connection-factory id="rabbitConnectionFactory"
connection-factory="clientConnectionFactory"
host="localhost"
port="5671"
username="username"
password="password"
virtual-host="test_host" />
<rabbit:admin connection-factory="rabbitConnectionFactory" />
<rabbit:template id="rabbitTemplate"
connection-factory="rabbitConnectionFactory" exchange="test_topic" />
<rabbit:topic-exchange name="test_topic" durable="true" />
<bean id="clientConnectionFactory" class="org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean">
<property name="useSSL" value="true" />
<property name="sslPropertiesLocation" value="/testconfig/rabbitSSL.properties"/>
</bean>
rabbitSSL.properties:
keyStore=file:/client/keycert.p12
trustStore=file:/lib/security/rabbitStore
keyStore.passPhrase=testpassword
trustStore.passPhrase=testpassword
However when I use the above code and config to connect to RabbitMQ over SSL I am getting a fatal alert: protocol_version.
When I looked at the org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean class that Spring is using to connect to RabbitMQ, I can see that the protocol appears to be hard coded to SSLv3.
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
this.connectionFactory.useSslProtocol(context);
This code works fine if I do not disable SSLv3 on RabbitMQ. However I need to connect to RabbitMQ using Tlsv1.2. Can I do that using Spring AMQP 1.4.3 or do I need to use another version.
Thanks for any help you can provide me with this issue.
While searching for RabbitMQ remote access I came across the below Spring application.properties configuration settings that can be done in Spring to configure the RabbitMQ connections.
https://www.oodlestechnologies.com/blogs/Connect-to-SSL-enabled-RabbitMQ-server-Springboot/
spring.rabbitmq.host=hostURL
spring.rabbitmq.port = hostPort
spring.rabbitmq.username = username
spring.rabbitmq.password = password
spring.rabbitmq.virtual-host=virtualHost
spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.2
https://www.baeldung.com/spring-remoting-amqp#2-configuration
I have opened a JIRA Issue for this.
In the meantime, the RabbitConnectionFactoryBean is just a convenience class to make configuring an underlying connection factory more "Spring friendly" with defaults.
Instead, you can perform this initialization in your own code (perhaps using a #Bean declaration using Java Configuration).
Okay, I was trying to connect by Spring Boot application(2.1.4.RELEASE) that uses spring-boot-starter-amqp (2.1.4.RELEASE) to an AWS Managed instance of RabbitMQ aka Amazon MQ and it would fail with a similar error. What worked for me was setting these properties.
spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.3
Setting these properties explicitly was not required in an application that was using Spring Boot and spring-boot-starter-amqp (2.7.8) and they worked out of the box. Here's a mention of the same in Spring AMQP Documentation.
https://docs.spring.io/spring-amqp/reference/html/#rabbitconnectionfactorybean-configuring-ssl

Arquillian tomee remote

Using Arquillian 1.1.4.Final and Tomee 1.6.0.2
Took the tomee-plus-remote profile setup from the Tomee information about arqullian adapters and put it into the Maven pom.xml (with activeByDefault true).
Goal is to deploy a MQ JCA rar into the remote Tomee and configure a connection factory to MQ.
Set the arqullian.xml initially to:
<container qualifier="tomee" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
</configuration>
</container>
Running via JUnit not sure why the webprofile is initialized and started rather than plus (when I have tomee plus specified in Maven):
Info: Succeeded in installing singleton service
jun 11, 2014 11:07:52 FM org.apache.openejb.config.ConfigurationFactory init
Info: openejb configuration file is 'C:\Users\MYG\AppData\Local\Temp\arquillian-apache-tomee\apache-tomee-webprofile-1.6.0.2\conf\tomee.xml'
Another thing is how to load a tomee.xml configuration. Thought, the "serverXml" in the arquillian.xml (set to src/test/resources/tomee.xml) would work but then everything inside that xml is not recognized as a valid rule. Can't add directives like Deployments as one does with resources. So how to configure the remote tomee from arquillian?
Yeah, tomee.xml was not really designed for arquillian.xml since all its config can be passed to properties attribute of tomee container using properties format
By adding a conf property to the arquillian.xml to for example src/test/conf where there is a tomee.xml file then it is loaded. This must be Tomee thing that I didn't know about until now.

remove server header tomcat

I am able to rename the value of org.apache.coyote.http11.Http11Protocol.SERVER to anything else, so the HTTP-Response-Header contains something like:
Server:Apache
instead of the default
Server:Apache-Coyote/1.1
Using a empty value for org.apache.coyote.http11.Http11Protocol.SERVER does not remove the Server-Header.
How can I remove the Server-Header from my responses?
You can modify your tomcat server.xml and add a "server" option and set it to whatever you want. The server option should be set for any http or ssl connectors that you have running. For example, below is a sample HTTP Connector configuration from an example server.xml file
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" enableLookups="false" xpoweredby="false" server="Web"/>
Short answer - you can't remove the header, but you should modify it (see other answers).
The server header is defined in the RFC and it is mandatory. (not defined as optional in the spec)
Taken from http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.38
14.38 Server
The Server response-header field contains information about the software used by the origin server to handle the request.
The field can contain multiple product tokens (section 3.8) and
comments identifying the server and any significant subproducts. The
product tokens are listed in order of their significance for
identifying the application.
If the response is being forwarded through a proxy, the proxy application MUST NOT modify the Server
response-header. Instead, it SHOULD include a Via field (as described
in section 14.45).
Note: Revealing the specific software version of the server might
allow the server machine to become more vulnerable to attacks
against software that is known to contain security holes. Server
implementors are encouraged to make this field a configurable
option.
It should be possible since Tomcat 5.5. Check out this discussion: https://mail-archives.apache.org/mod_mbox/tomcat-users/200508.mbox/%3C42FBE8AA.1060401#joedog.org%3E
and this link:
https://tomcat.apache.org/tomcat-4.1-doc/config/coyote.html
Accordingly the following should set the server header to TEST. Empty should make it empty.
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="8180" inProcessors="5" maxProcessors="75" enableLookups="true" acceptCount="10" debug="0" connectionTimeout="20000" useURIValidationHack="false" server="TEST"/>
Setting the Server header to Apache should security-wise be good enough in most cases. Just from that it won't be possible to infer which OS nor which exact version with which modules and the versions of the modules running.
if you are using embedded tomcat then you can try below code.
import org.apache.catalina.startup.Tomcat;
final Tomcat server = new Tomcat();
server.getConnector().setXpoweredBy(false);
server.getConnector().setAttribute("server", "");
For Web application.
Set Server header from the code.
It worked for me in Java Spring boot project.
response.setHeader("Server", "none");
Try adding from code if it is deployed in tomcat.

configure JMX for ActiveMQ for remoting access

Anyone can give the detailed steps on how to enable JMX (can be access remotely) on a newly installed 5.5.0 version?
In your activemq.xml file, you need make sure useJmx is true on your broker element:
<broker xmlns="http://activemq.org/config/1.0" brokerName="localhost" useJmx="true">
and ensure that you have a management context
<managementContext>
<managementContext createConnector="true" connectorPort="1099"/>
</managementContext>
From there it is just a matter of making sure you can connect over TCP to your broker on port 1099 or whatever port you specify. This doesn't work quite so straightforward on services like EC2 or anything that does some heavy NAT'ing: http://jmsbrdy.com/monitoring-java-applications-running-on-ec2-i

Active MQ JMX SSL

I'm trying to use SSL with the JMX connector that Active MQ creates, but with no success. I'm able to get SSL working with the JVM platform JMX connector, but that requires storing keystore and truststore passwords plaintext, which is a no-go for our project.
Using the instructions here, I set up managementContext in activemq.xml as follows:
<managementContext>
<managementContext createConnector="true">
<property xmlns="http://www.springframework.org/schema/beans" name="environment">
<map xmlns="http://www.springframework.org/schema/beans">
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.keyStore"
value="${activemq.base}/conf/keystore.jks"/>
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.keyStorePassword"
value="${keystore.password}"/>
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.trustStore"
value="${activemq.base}/conf/truststore.jks"/>
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.trustStorePassword"
value="${truststore.password}"/>
</map>
</property>
</managementContext>
</managementContext>
This section seems to be completely ignored when the connector starts up. I can connect without credentials. I also tried using username and password authentication instead of ssl for JMX, as seen here, and that worked fine.
Has anyone seen this before? Any ideas? Thanks!
Have you enabled jmx ssl in the activemq launch scripts? On windows in the activemq-admin or activemq batch files, uncomment and modify the SUNJMX settings.
JMX authentiation is independent of whether ssl is used. It is controlled by the authenticate attribute. By default it will use the jmx access files in your jre, so re-point them with the system properties shown below. You may get an error message stating that the files themselves must be access controlled, so set them with chmod on unix or cacls on windows. I would suggest even turning off the ssl and getting the authentication to work first. You can test with jconsole with a remote connection to confirm that it wants credentials. Then follow-up with the ssl stuff.
set SUNJMX=-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=1199 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=true -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.password.file=%ACTIVEMQ_BASE%/conf/access/jmx.password -Dcom.sun.management.jmxremote.access.file=%ACTIVEMQ_BASE%/conf/access/jmx.access
I had the same issue regarding the ActiveMQ SSL configuration (keystore & password) in the XML not working.
My requirement was to enable remote JMX monitoring of ActiveMQ with SSL and authentication through a firewall.
I resolved it using a custom JMX connector (via a Java Agent), rather than using the JMX connector that Active MQ creates.
see: JMX connectivity through a firewall for an example (JMXAgent.java)
The important entries for configuring SSL in the JMXAgent.java are:
Map<String, Object> env = new HashMap<String, Object>();
SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
You can also specify your authentication files in the env Map:
env.put("jmx.remote.x.password.file", System.getProperty("password.file","<default_path>"));
env.put("jmx.remote.x.access.file", System.getProperty("access.file","<default_path>"));
The Java Agent needs to be compiled and put into a jar with a valid manifest file as described here
Add the following to the activemq launch configuration (depending on activemq version/ environment and run ActiveMQ:
-javaagent:<full_path_to_agent_jar_file> \
-Dpassword.file=<full_path_to_jmx.password_file> \
-Daccess.file=<full_path_to_jmx.access_file> \
-Djavax.net.ssl.keyStore=<full_path_to_keystore_file> \
-Djavax.net.ssl.keyStorePassword=<password>
You should then be able to connect through jconsole (with correct security parameters)
The remote JMX connection URL will be something like:
service:jmx:rmi://<host>:<rmi_server_port>/jndi/rmi://<host>:<port>/jmxrmi
Note - ports can be configured in the Java Agent.