Spring boot Artemis embedded broker behaviour

louis gueye picture louis gueye · Sep 30, 2016 · Viewed 8.1k times · Source

Morning all,

I've been struggling lately with the spring-boot-artemis-starter. My understanding of its spring-boot support was the following:

  • set spring.artemis.mode=embedded and, like tomcat, spring-boot will instanciate a broker reachable through tcp (server mode). The following command should be successful: nc -zv localhost 61616
  • set spring.artmis.mode=native and spring-boot will only configure the jms template according to the spring.artemis.* properties (client mode).

The client mode works just fine with a standalone artemis server on my machine. Unfortunatelly, I could never manage to reach the tcp port in server mode.

I would be grateful if somebody confirms my understanding of the embedded mode.

Thank you for tour help

After some digging I noted that the implementation provided out of the box by the spring-boot-starter-artemis uses org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory acceptor. I'm wondering if that's not the root cause (again I'm by no means an expert). But it appears that there is a way to customize artemis configuration. Therefore I tried the following configuration without any luck:

@SpringBootApplication
public class MyBroker {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(MyBroker.class, args);
    }

    @Autowired
    private ArtemisProperties artemisProperties;

    @Bean
    public ArtemisConfigurationCustomizer artemisConfigurationCustomizer() {
        return configuration -> {
            try {
               configuration.addAcceptorConfiguration("netty", "tcp://localhost:" + artemisProperties.getPort());
            } catch (Exception e) {
                throw new RuntimeException("Failed to add netty transport acceptor to artemis instance");
            }
        };
    }

}

Answer

Szilárd Fodor picture Szilárd Fodor · Mar 19, 2017

You just have to add a Connector and an Acceptor to your Artemis Configuration. With Spring Boot Artemis starter Spring creates a Configuration bean which will be used for EmbeddedJMS configuration. You can see this in ArtemisEmbeddedConfigurationFactory class where an InVMAcceptorFactory will be set for the configuration. You can edit this bean and change Artemis behaviour through custom ArtemisConfigurationCustomizer bean which will be sucked up by Spring autoconfig and be applied to the Configuration.

An example config class for your Spring Boot application:

import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConfigurationCustomizer;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ArtemisConfig implements ArtemisConfigurationCustomizer {
    @Override
    public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) {
        configuration.addConnectorConfiguration("nettyConnector", new TransportConfiguration(NettyConnectorFactory.class.getName()));
        configuration.addAcceptorConfiguration(new TransportConfiguration(NettyAcceptorFactory.class.getName()));
    }
}