Skip to content

Commit

Permalink
Make connection factories injectable
Browse files Browse the repository at this point in the history
Update kernel
  • Loading branch information
adrienlauer committed Jul 1, 2020
1 parent 7068989 commit 40af915
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 74 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Version 3.1.1 (2019-07-31)

* [new] Make connection factories injectable with their name as qualifier: `@Named("myCf")`.

# Version 3.1.0 (2019-12-19)

* [new] Support disabling JMS listeners by setting destination type to "DISABLED". This can be substituted with configuration with the `destinationTypeStr` annotation parameter.
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

<groupId>org.seedstack.addons.jms</groupId>
<artifactId>jms</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.1.1-SNAPSHOT</version>

<properties>
<seed.version>3.9.2-SNAPSHOT</seed.version>
<seed.version>3.10.0-SNAPSHOT</seed.version>

<compatibility.version>3.0.0</compatibility.version>

Expand Down
70 changes: 50 additions & 20 deletions src/main/java/org/seedstack/jms/internal/JmsFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

package org.seedstack.jms.internal;

import com.google.common.base.Strings;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
Expand All @@ -19,11 +22,11 @@
import javax.naming.NamingException;
import jodd.bean.BeanUtil;
import jodd.bean.BeanUtilBean;
import org.apache.commons.lang.StringUtils;
import org.seedstack.jms.JmsConfig;
import org.seedstack.jms.spi.ConnectionDefinition;
import org.seedstack.jms.spi.JmsFactory;
import org.seedstack.seed.SeedException;
import org.seedstack.shed.reflect.Classes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -46,21 +49,30 @@ class JmsFactoryImpl implements JmsFactory {
configureConnectionFactories();
}

@Override
public Map<String, ConnectionFactory> getConnectionFactories() {
return Collections.unmodifiableMap(connectionFactoryMap);
}

@Override
public Connection createConnection(ConnectionDefinition connectionDefinition) throws JMSException {
Connection connection;

if (connectionDefinition.isManaged()) {
connection = new ManagedConnection(connectionDefinition, this);
if (connectionDefinition.getExceptionListenerClass() != null) {
LOGGER.debug("Setting exception listener {} on managed connection {}", connectionDefinition.getExceptionListenerClass(), connectionDefinition.getName());
LOGGER.debug("Setting exception listener {} on managed connection {}",
connectionDefinition.getExceptionListenerClass(),
connectionDefinition.getName());
connection.setExceptionListener(new ExceptionListenerAdapter(connectionDefinition.getName()));
}
} else {
connection = createRawConnection(connectionDefinition);
if (!connectionDefinition.isJeeMode()) {
if (connectionDefinition.getExceptionListenerClass() != null) {
LOGGER.debug("Setting exception listener {} on connection {}", connectionDefinition.getExceptionListenerClass(), connectionDefinition.getName());
LOGGER.debug("Setting exception listener {} on connection {}",
connectionDefinition.getExceptionListenerClass(),
connectionDefinition.getName());
connection.setExceptionListener(new ExceptionListenerAdapter(connectionDefinition.getName()));
}
}
Expand All @@ -70,22 +82,24 @@ public Connection createConnection(ConnectionDefinition connectionDefinition) th
}

@Override
@SuppressWarnings("unchecked")
public ConnectionDefinition createConnectionDefinition(String connectionName, JmsConfig.ConnectionConfig connectionConfig, ConnectionFactory connectionFactory) {
public ConnectionDefinition createConnectionDefinition(String connectionName,
JmsConfig.ConnectionConfig connectionConfig, ConnectionFactory connectionFactory) {
// Find connection factory if not given explicitly
if (connectionFactory == null) {
connectionFactory = connectionFactoryMap.get(connectionConfig.getConnectionFactory());

if (connectionFactory == null) {
throw SeedException.createNew(JmsErrorCode.MISSING_CONNECTION_FACTORY).put("connectionName", connectionName);
throw SeedException.createNew(JmsErrorCode.MISSING_CONNECTION_FACTORY)
.put("connectionName", connectionName);
}
}

boolean jeeMode = connectionConfig.isJeeMode();
boolean shouldSetClientId = connectionConfig.isSetClientId();

if (jeeMode && shouldSetClientId) {
throw SeedException.createNew(JmsErrorCode.CANNOT_SET_CLIENT_ID_IN_JEE_MODE).put(JmsPlugin.ERROR_CONNECTION_NAME, connectionName);
throw SeedException.createNew(JmsErrorCode.CANNOT_SET_CLIENT_ID_IN_JEE_MODE)
.put(JmsPlugin.ERROR_CONNECTION_NAME, connectionName);
}

return new ConnectionDefinition(
Expand All @@ -106,22 +120,26 @@ public ConnectionDefinition createConnectionDefinition(String connectionName, Jm
Connection createRawConnection(ConnectionDefinition connectionDefinition) throws JMSException {
Connection connection;
if (connectionDefinition.getUser() != null) {
connection = connectionDefinition.getConnectionFactory().createConnection(connectionDefinition.getUser(), connectionDefinition.getPassword());
connection = connectionDefinition.getConnectionFactory()
.createConnection(connectionDefinition.getUser(), connectionDefinition.getPassword());
} else {
connection = connectionDefinition.getConnectionFactory().createConnection();
}

// client id is set here on raw connection
if (connectionDefinition.isShouldSetClientId()) {
LOGGER.debug("Setting client id as {} on connection {}", connectionDefinition.getClientId(), connectionDefinition.getName());
LOGGER.debug("Setting client id as {} on connection {}",
connectionDefinition.getClientId(),
connectionDefinition.getName());
connection.setClientID(connectionDefinition.getClientId());
}

return connection;
}

private void configureConnectionFactories() {
for (Map.Entry<String, JmsConfig.ConnectionFactoryConfig> entry : jmsConfig.getConnectionFactories().entrySet()) {
for (Map.Entry<String, JmsConfig.ConnectionFactoryConfig> entry : jmsConfig.getConnectionFactories()
.entrySet()) {
String connectionFactoryName = entry.getKey();
JmsConfig.ConnectionFactoryConfig connectionFactoryConfig = entry.getValue();

Expand All @@ -130,21 +148,24 @@ private void configureConnectionFactories() {
Class<? extends ConnectionFactory> connectionFactoryClass = connectionFactoryConfig.getVendorClass();

Object connectionFactory;
if (StringUtils.isNotBlank(jndiName)) {
if (!Strings.isNullOrEmpty(jndiName)) {
connectionFactory = lookupConnectionFactory(connectionFactoryName, jndiContext, jndiName);
} else if (connectionFactoryClass != null) {
try {
connectionFactory = connectionFactoryClass.newInstance();
connectionFactory = Classes.instantiateDefault(connectionFactoryClass);
setProperties(connectionFactory, connectionFactoryConfig.getVendorProperties());
} catch (Exception e) {
throw SeedException.wrap(e, JmsErrorCode.UNABLE_TO_CREATE_CONNECTION_FACTORY).put("connectionFactoryName", connectionFactoryName);
throw SeedException.wrap(e, JmsErrorCode.UNABLE_TO_CREATE_CONNECTION_FACTORY)
.put("connectionFactoryName", connectionFactoryName);
}
} else {
throw SeedException.createNew(JmsErrorCode.MISCONFIGURED_CONNECTION_FACTORY).put("connectionFactoryName", connectionFactoryName);
throw SeedException.createNew(JmsErrorCode.MISCONFIGURED_CONNECTION_FACTORY)
.put("connectionFactoryName", connectionFactoryName);
}

if (!(connectionFactory instanceof ConnectionFactory)) {
throw SeedException.createNew(JmsErrorCode.UNRECOGNIZED_CONNECTION_FACTORY).put("className", connectionFactoryClass);
throw SeedException.createNew(JmsErrorCode.UNRECOGNIZED_CONNECTION_FACTORY)
.put("className", connectionFactoryClass);
}

connectionFactoryMap.put(connectionFactoryName, (ConnectionFactory) connectionFactory);
Expand All @@ -154,17 +175,21 @@ private void configureConnectionFactories() {
private Object lookupConnectionFactory(String connectionFactoryName, String contextName, String jndiName) {
try {
if (this.jndiContexts == null || this.jndiContexts.isEmpty()) {
throw SeedException.createNew(JmsErrorCode.NO_JNDI_CONTEXT).put("connectionFactoryName", connectionFactoryName);
throw SeedException.createNew(JmsErrorCode.NO_JNDI_CONTEXT)
.put("connectionFactoryName", connectionFactoryName);
}

Context context = this.jndiContexts.get(contextName);
if (context == null) {
throw SeedException.createNew(JmsErrorCode.MISSING_JNDI_CONTEXT).put("contextName", contextName).put("connectionFactoryName", connectionFactoryName);
throw SeedException.createNew(JmsErrorCode.MISSING_JNDI_CONTEXT)
.put("contextName", contextName)
.put("connectionFactoryName", connectionFactoryName);
}

return context.lookup(jndiName);
} catch (NamingException e) {
throw SeedException.wrap(e, JmsErrorCode.JNDI_LOOKUP_ERROR).put("connectionFactoryName", connectionFactoryName);
throw SeedException.wrap(e, JmsErrorCode.JNDI_LOOKUP_ERROR)
.put("connectionFactoryName", connectionFactoryName);
}
}

Expand All @@ -174,12 +199,17 @@ private void setProperties(Object bean, Properties properties) {
String value = properties.getProperty(key);
try {
if (!beanUtil.hasProperty(bean, key)) {
throw SeedException.createNew(JmsErrorCode.PROPERTY_NOT_FOUND).put("property", key).put("class", bean.getClass().getCanonicalName());
throw SeedException.createNew(JmsErrorCode.PROPERTY_NOT_FOUND)
.put("property", key)
.put("class", bean.getClass().getCanonicalName());
}

beanUtil.setProperty(bean, key, value);
} catch (Exception e) {
throw SeedException.wrap(e, JmsErrorCode.UNABLE_TO_SET_PROPERTY).put("property", key).put("class", bean.getClass().getCanonicalName()).put("value", value);
throw SeedException.wrap(e, JmsErrorCode.UNABLE_TO_SET_PROPERTY)
.put("property", key)
.put("class", bean.getClass().getCanonicalName())
.put("value", value);
}
}
}
Expand Down
56 changes: 28 additions & 28 deletions src/main/java/org/seedstack/jms/internal/JmsModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,38 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.jms.internal;

package org.seedstack.jms.internal;

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;
import com.google.inject.util.Providers;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.ExceptionListener;
import javax.jms.MessageListener;
import javax.jms.Session;
import org.seedstack.jms.spi.ConnectionDefinition;
import org.seedstack.jms.spi.JmsExceptionHandler;
import org.seedstack.jms.spi.JmsFactory;
import org.seedstack.jms.spi.MessageListenerDefinition;
import org.seedstack.jms.spi.MessageListenerInstanceDefinition;
import org.seedstack.jms.spi.JmsFactory;
import org.seedstack.jms.spi.MessagePoller;
import org.seedstack.seed.core.internal.transaction.TransactionalProxy;

import javax.jms.Connection;
import javax.jms.ExceptionListener;
import javax.jms.MessageListener;
import javax.jms.Session;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;

class JmsModule extends AbstractModule {
private final JmsFactory jmsFactory;
private final Map<String, Connection> connections;
private final Map<String, MessageListenerDefinition> messageListenerDefinitions;
private final Map<String, ConnectionDefinition> connectionDefinitions;
private final Collection<MessagePoller> pollers;

public JmsModule(JmsFactory jmsFactory, ConcurrentMap<String, Connection> connections, ConcurrentMap<String, ConnectionDefinition> connectionDefinitions, Map<String, MessageListenerDefinition> messageListenerDefinitions, Collection<MessagePoller> pollers) {
public JmsModule(JmsFactory jmsFactory, ConcurrentMap<String, Connection> connections,
ConcurrentMap<String, ConnectionDefinition> connectionDefinitions,
Map<String, MessageListenerDefinition> messageListenerDefinitions, Collection<MessagePoller> pollers) {
this.jmsFactory = jmsFactory;
this.connections = connections;
this.connectionDefinitions = connectionDefinitions;
Expand All @@ -53,17 +55,11 @@ protected void configure() {
JmsSessionLink jmsSessionLink = new JmsSessionLink();
bind(Session.class).toInstance(TransactionalProxy.create(Session.class, jmsSessionLink));

for (Map.Entry<String, Connection> entry : connections.entrySet()) {
bindConnection(connectionDefinitions.get(entry.getKey()), entry.getValue(), jmsSessionLink);
}

for (Map.Entry<String, MessageListenerDefinition> entry : messageListenerDefinitions.entrySet()) {
bindMessageListener(entry.getValue());
}

for (MessagePoller poller : pollers) {
requestInjection(poller);
}
jmsFactory.getConnectionFactories()
.forEach((name, cf) -> bind(ConnectionFactory.class).annotatedWith(Names.named(name)).toInstance(cf));
connections.forEach((key, value) -> bindConnection(connectionDefinitions.get(key), value, jmsSessionLink));
messageListenerDefinitions.forEach((key, value) -> bindMessageListener(value));
pollers.forEach(this::requestInjection);
}

private void bindMessageListener(MessageListenerDefinition messageListenerDefinition) {
Expand All @@ -74,26 +70,30 @@ private void bindMessageListener(MessageListenerDefinition messageListenerDefini
.toInstance(new JmsListenerTransactionHandler(messageListenerDefinition.getSession()));

if (messageListenerDefinition instanceof MessageListenerInstanceDefinition) {
MessageListener messageListener = ((MessageListenerInstanceDefinition) messageListenerDefinition).getMessageListener();
MessageListener messageListener =
((MessageListenerInstanceDefinition) messageListenerDefinition).getMessageListener();
bind(MessageListener.class).annotatedWith(Names.named(name)).toInstance(messageListener);
} else {
bind(MessageListener.class).annotatedWith(Names.named(name)).to(messageListenerDefinition.getMessageListenerClass());
bind(MessageListener.class).annotatedWith(Names.named(name))
.to(messageListenerDefinition.getMessageListenerClass());
}
}


private void bindConnection(ConnectionDefinition connectionDefinition, Connection connection, JmsSessionLink jmsSessionLink) {
private void bindConnection(ConnectionDefinition connectionDefinition, Connection connection,
JmsSessionLink jmsSessionLink) {
String name = connectionDefinition.getName();

Class<? extends JmsExceptionHandler> jmsExceptionHandlerClass = connectionDefinition.getJmsExceptionHandlerClass();
Class<? extends JmsExceptionHandler> jmsExceptionHandlerClass =
connectionDefinition.getJmsExceptionHandlerClass();
if (jmsExceptionHandlerClass != null) {
bind(JmsExceptionHandler.class).annotatedWith(Names.named(name)).to(jmsExceptionHandlerClass);
} else {
bind(JmsExceptionHandler.class).annotatedWith(Names.named(name)).toProvider(Providers.of(null));
}

if (connectionDefinition.getExceptionListenerClass() != null) {
bind(ExceptionListener.class).annotatedWith(Names.named(name)).to(connectionDefinition.getExceptionListenerClass());
bind(ExceptionListener.class).annotatedWith(Names.named(name))
.to(connectionDefinition.getExceptionListenerClass());
}

bind(Connection.class).annotatedWith(Names.named(name)).toInstance(connection);
Expand Down
Loading

0 comments on commit 40af915

Please sign in to comment.