diff --git a/archetype/app/quickstart/appdefn/pom.xml b/archetype/app/quickstart/appdefn/pom.xml index 56a40a1a6..27c9a66f1 100644 --- a/archetype/app/quickstart/appdefn/pom.xml +++ b/archetype/app/quickstart/appdefn/pom.xml @@ -182,6 +182,10 @@ org.isisaddons.module.publishmq isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + org.isisaddons.module.publishmq isis-module-publishmq-dom-servicespi diff --git a/archetype/arch/quickstart/src/main/resources/archetype-resources/appdefn/pom.xml b/archetype/arch/quickstart/src/main/resources/archetype-resources/appdefn/pom.xml index 5146ec3e4..d7866fa29 100644 --- a/archetype/arch/quickstart/src/main/resources/archetype-resources/appdefn/pom.xml +++ b/archetype/arch/quickstart/src/main/resources/archetype-resources/appdefn/pom.xml @@ -211,6 +211,10 @@ org.isisaddons.module.publishmq isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + org.isisaddons.module.publishmq isis-module-publishmq-dom-servicespi diff --git a/modules/ext/flywaydb/fixture/pom.xml b/modules/ext/flywaydb/fixture/pom.xml index 80d4604dc..2f8d98d0e 100644 --- a/modules/ext/flywaydb/fixture/pom.xml +++ b/modules/ext/flywaydb/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/lib/docx/fixture/pom.xml b/modules/lib/docx/fixture/pom.xml index 5347b89a1..6f6342f58 100644 --- a/modules/lib/docx/fixture/pom.xml +++ b/modules/lib/docx/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/lib/excel/fixture/pom.xml b/modules/lib/excel/fixture/pom.xml index 4a770de33..fdf2a1a6d 100644 --- a/modules/lib/excel/fixture/pom.xml +++ b/modules/lib/excel/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/lib/fakedata/fixture/pom.xml b/modules/lib/fakedata/fixture/pom.xml index 2e3104d11..698e41846 100644 --- a/modules/lib/fakedata/fixture/pom.xml +++ b/modules/lib/fakedata/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/lib/poly/fixture/pom.xml b/modules/lib/poly/fixture/pom.xml index 7feafa4ed..9bd9ad067 100644 --- a/modules/lib/poly/fixture/pom.xml +++ b/modules/lib/poly/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/lib/servletapi/fixture/pom.xml b/modules/lib/servletapi/fixture/pom.xml index 61a03abdf..5e791de19 100644 --- a/modules/lib/servletapi/fixture/pom.xml +++ b/modules/lib/servletapi/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/lib/stringinterpolator/fixture/pom.xml b/modules/lib/stringinterpolator/fixture/pom.xml index 14fda87b7..6d9890240 100644 --- a/modules/lib/stringinterpolator/fixture/pom.xml +++ b/modules/lib/stringinterpolator/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/pom.xml b/modules/pom.xml index 1473e5641..12a28e053 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -695,6 +695,18 @@ test-jar test + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + ${incode-platform.version} + + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + ${incode-platform.version} + test-jar + test + org.isisaddons.module.publishmq isis-module-publishmq-dom-camel @@ -1215,6 +1227,25 @@ + + publishmq + + + publishmq + + + + + lib/base/impl + lib/fakedata/impl + + spi/publishmq/fixture + spi/publishmq/impl + spi/publishmq/integtests + + + + default-modules diff --git a/modules/spi/audit/fixture/pom.xml b/modules/spi/audit/fixture/pom.xml index 15865c819..0e26f51e9 100644 --- a/modules/spi/audit/fixture/pom.xml +++ b/modules/spi/audit/fixture/pom.xml @@ -172,6 +172,10 @@ TODO: to reinstate, think that FixturesManifest needs some attention. org.isisaddons.module.publishmq isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + org.isisaddons.module.security diff --git a/modules/spi/audit/integtests/pom.xml b/modules/spi/audit/integtests/pom.xml index f5c1b8bbb..0e3274a27 100644 --- a/modules/spi/audit/integtests/pom.xml +++ b/modules/spi/audit/integtests/pom.xml @@ -112,6 +112,12 @@ test + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + test + + org.isisaddons.module.publishmq isis-module-publishmq-dom-camel diff --git a/modules/spi/command/fixture/pom.xml b/modules/spi/command/fixture/pom.xml index ac6cc9821..31c066d37 100644 --- a/modules/spi/command/fixture/pom.xml +++ b/modules/spi/command/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/spi/command/integtests/pom.xml b/modules/spi/command/integtests/pom.xml index a0ad79781..15be68949 100644 --- a/modules/spi/command/integtests/pom.xml +++ b/modules/spi/command/integtests/pom.xml @@ -112,6 +112,12 @@ test + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + test + + org.isisaddons.module.publishmq isis-module-publishmq-dom-camel diff --git a/modules/spi/publishmq/fixture/pom.xml b/modules/spi/publishmq/fixture/pom.xml index b186bdd8a..511fe21d3 100644 --- a/modules/spi/publishmq/fixture/pom.xml +++ b/modules/spi/publishmq/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/spi/publishmq/impl/mq/log4j.properties b/modules/spi/publishmq/impl/mq/log4j.properties new file mode 100644 index 000000000..20ec65402 --- /dev/null +++ b/modules/spi/publishmq/impl/mq/log4j.properties @@ -0,0 +1,22 @@ + +# Basic logging goes to "datanucleus.log" +log4j.appender.A1=org.apache.log4j.FileAppender +log4j.appender.A1.File=datanucleus.log +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d{HH:mm:ss,SSS} (%t) %-5p [%c] - %m%n +#log4j.appender.A1.Threshold=INFO + +# Categories +# Each category can be set to a "level", and to direct to an appender + +# Default to DEBUG level for all DataNucleus categories +log4j.logger.DataNucleus = DEBUG, A1 + +log4j.category.com.mchange.v2.c3p0=INFO, A1 +log4j.category.com.mchange.v2.resourcepool=INFO, A1 +log4j.category.org.logicalcobwebs.proxool=INFO,A1 + + +# Hbase libs logging +log4j.category.org.apache.hadoop=INFO,A1 +log4j.category.org.apache.zookeeper=INFO,A1 \ No newline at end of file diff --git a/modules/spi/publishmq/impl/mq/pom.xml b/modules/spi/publishmq/impl/mq/pom.xml new file mode 100644 index 000000000..43ca57cf8 --- /dev/null +++ b/modules/spi/publishmq/impl/mq/pom.xml @@ -0,0 +1,183 @@ + + + 4.0.0 + + + org.isisaddons.module.publishmq + isis-module-publishmq-dom + ${revision} + + isis-module-publishmq-dom-mq + + jar + + Incode Platform SPI PublishMQ Impl MQ Plugin + + A module providing publishmq service SPI implementation + + + + org.incode.platform.spi.publishmq.mq + org/incode/platform/spi/publishmq/mq + + ${project.basedir}/../../../../../.git + + + + + + false + src/main/java + + ** + + + **/*.java + + + + + + com.github.odavid.maven.plugins + mixin-maven-plugin + 0.1-alpha-39 + true + + + + com.danhaywood.mavenmixin + enforcerrelaxed + + + com.danhaywood.mavenmixin + sourceandjavadoc + + + com.danhaywood.mavenmixin + standard + + + com.danhaywood.mavenmixin + surefire + + + + + + + + + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-servicespi + + + + org.apache.isis.core + isis-core-applib + + + org.apache.isis.core + isis-core-schema + + + org.apache.activemq + activemq-all + + + + + org.apache.isis.core + isis-core-unittestsupport + test + + + + org.incode.module.base + incode-module-base-dom + test + test-jar + + + + junit + junit + test + + + + org.assertj + assertj-core + test + + + + org.projectlombok + lombok + provided + + + + + + + git + + + !skip.git + + + + + + pl.project13.maven + git-commit-id-plugin + + + + + + flatten + + + revision + + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.0.0 + + + flatten + process-resources + + flatten + + + defaults + true + + resolve + resolve + resolve + + + + + flatten.clean + clean + + clean + + + + + + + + + + diff --git a/modules/spi/publishmq/impl/mq/src/main/java/org/isisaddons/module/publishmq/dom/mq/spi/InteractionExecutionRepositoryMq.java b/modules/spi/publishmq/impl/mq/src/main/java/org/isisaddons/module/publishmq/dom/mq/spi/InteractionExecutionRepositoryMq.java new file mode 100644 index 000000000..706520189 --- /dev/null +++ b/modules/spi/publishmq/impl/mq/src/main/java/org/isisaddons/module/publishmq/dom/mq/spi/InteractionExecutionRepositoryMq.java @@ -0,0 +1,231 @@ +package org.isisaddons.module.publishmq.dom.mq.spi; + +import java.util.Map; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.DeliveryMode; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.broker.BrokerService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.isis.applib.ApplicationException; +import org.apache.isis.applib.annotation.DomainService; +import org.apache.isis.applib.annotation.NatureOfService; +import org.apache.isis.applib.annotation.Programmatic; +import org.apache.isis.applib.services.iactn.Interaction; +import org.apache.isis.schema.ixn.v1.InteractionDto; +import org.apache.isis.schema.utils.InteractionDtoUtils; +import org.isisaddons.module.publishmq.dom.servicespi.InteractionExecutionRepository; +import org.isisaddons.module.publishmq.dom.servicespi.PublisherServiceUsingActiveMq; +import org.isisaddons.module.publishmq.dom.servicespi.PublisherServiceUsingActiveMqStatusProvider; + +@DomainService( + nature = NatureOfService.DOMAIN, + menuOrder = "" + Integer.MAX_VALUE // after the JDO publishers +) +public class InteractionExecutionRepositoryMq implements InteractionExecutionRepository { + + @Inject + PublisherServiceUsingActiveMqStatusProvider statusProvider; + + private static final Logger LOG = LoggerFactory.getLogger(InteractionExecutionRepositoryMq.class); + + //region > keys + public static final String ROOT = PublisherServiceUsingActiveMq.ROOT; + + public static final String KEY_VM_TRANSPORT_URL = ROOT + "vmTransportUri"; + public static final String KEY_VM_TRANSPORT_URL_DEFAULT = "vm://broker"; + + public static final String KEY_MEMBER_INTERACTIONS_QUEUE = ROOT + "memberInteractionsQueue"; + public static final String KEY_MEMBER_INTERACTIONS_QUEUE_DEFAULT = "memberInteractionsQueue"; + //endregion + + + + //region > fields + + private ConnectionFactory jmsConnectionFactory; + private Connection jmsConnection; + + private static boolean transacted = true; + + private String vmTransportUrl; + String memberInteractionsQueueName; + + private boolean enabled; + + //endregion + + //region > init, shutdown + + @PostConstruct + public void init(Map properties) { + + enabled = statusProvider.isEnabled(); + if(!enabled) { + LOG.warn("JMS publishing NOT enabled"); + return; + } + + vmTransportUrl = properties.getOrDefault(KEY_VM_TRANSPORT_URL, KEY_VM_TRANSPORT_URL_DEFAULT); + memberInteractionsQueueName = properties.getOrDefault(KEY_MEMBER_INTERACTIONS_QUEUE, + KEY_MEMBER_INTERACTIONS_QUEUE_DEFAULT); + + memberInteractionsQueueName = properties.getOrDefault(KEY_MEMBER_INTERACTIONS_QUEUE, + KEY_MEMBER_INTERACTIONS_QUEUE_DEFAULT); + + connect(); + + } + + void connect() { + jmsConnectionFactory = new ActiveMQConnectionFactory(vmTransportUrl); + + try { + jmsConnection = jmsConnectionFactory.createConnection(); + } catch (JMSException e) { + LOG.error("Unable to create connection", e); + } + + if(jmsConnection != null) { + try { + jmsConnection.start(); + } catch (JMSException e) { + LOG.error("Unable to start connection", e); + closeSafely(jmsConnection); + jmsConnection = null; + } + } + } + + @PreDestroy + public void shutdown() { + closeSafely(jmsConnection); + } + + + private static void closeSafely(Connection connection) { + if(connection != null) { + try { + connection.close(); + } catch (JMSException e) { + //ignore + } + } + } + + private static void closeSafely(Session session) { + try { + session.close(); + } catch (JMSException e) { + // ignore + } + } + + private static void stopSafely(final BrokerService broker) { + if(broker==null) { + return; + } + try { + broker.stop(); + } catch (Exception ignore) { + } + } + + //endregion + + + //region > publish (execution) + + @Override + @Programmatic + public void persist(final Interaction.Execution execution) { + + if(jmsConnection == null) { + LOG.warn("No JMS connection; interaction will not be published"); + return; + } + + final InteractionDto interactionDto = InteractionDtoUtils.newInteractionDto(execution); + + sendUsingJms(interactionDto); + } + + private void sendUsingJms(final InteractionDto interactionDto) { + final String xml = InteractionDtoUtils.toXml(interactionDto); + + Session session = null; + try { + + session = jmsConnection.createSession(transacted, Session.SESSION_TRANSACTED); + TextMessage message = session.createTextMessage(xml); + + final String transactionId = interactionDto.getTransactionId(); + final int sequence = interactionDto.getExecution().getSequence(); + final String executionId = transactionId + "." + sequence; + final String memberIdentifier = interactionDto.getExecution().getMemberIdentifier(); + + message.setJMSMessageID(executionId); + message.setJMSType(memberIdentifier); + + if(LOG.isInfoEnabled()) { + LOG.info(String.format( + "Sending JMS message, id:%s; type:%s", + message.getJMSMessageID(), message.getJMSType())); + } + + final Queue queue = session.createQueue(memberInteractionsQueueName); + MessageProducer producer = session.createProducer(queue); + producer.setDeliveryMode(DeliveryMode.PERSISTENT); + producer.send(message); + + session.commit(); + + } catch (JMSException e) { + rollback(session); + throw new ApplicationException("Failed to publish message", e); + } finally { + if(session != null) { + closeSafely(session); + } + } + } + + + private static void rollback(final Session session) { + try { + if (session != null) { + session.rollback(); + } + } catch (JMSException ex) { + // ignore + } + } + //endregion + + + //region > republish + /** + * Private API. + * @param interactionDto + */ + @Programmatic + public void republish(final InteractionDto interactionDto) { + sendUsingJms(interactionDto); + } + + //endregion + + +} diff --git a/modules/spi/publishmq/impl/mq/src/main/java/org/isisaddons/module/publishmq/dom/mq/spi/PublishedObjectsRepositoryMq.java b/modules/spi/publishmq/impl/mq/src/main/java/org/isisaddons/module/publishmq/dom/mq/spi/PublishedObjectsRepositoryMq.java new file mode 100644 index 000000000..675f3a97b --- /dev/null +++ b/modules/spi/publishmq/impl/mq/src/main/java/org/isisaddons/module/publishmq/dom/mq/spi/PublishedObjectsRepositoryMq.java @@ -0,0 +1,23 @@ +package org.isisaddons.module.publishmq.dom.mq.spi; + +import org.apache.isis.applib.annotation.DomainService; +import org.apache.isis.applib.annotation.NatureOfService; +import org.apache.isis.applib.annotation.Programmatic; +import org.apache.isis.applib.services.publish.PublishedObjects; +import org.apache.isis.schema.chg.v1.ChangesDto; +import org.isisaddons.module.publishmq.dom.servicespi.PublishedObjectsRepository; + +@DomainService( + nature = NatureOfService.DOMAIN +) +public class PublishedObjectsRepositoryMq implements PublishedObjectsRepository { + + @Override + @Programmatic + public void persist(final PublishedObjects publishedObjects) { + final ChangesDto changesDto = publishedObjects.getDto(); + // no-op; we currently do not published the ChangesDto onto JMS. + } + + +} diff --git a/modules/spi/publishmq/impl/servicespi/src/test/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMq_init_Test.java b/modules/spi/publishmq/impl/mq/src/test/java/org/isisaddons/module/publishmq/dom/mq/spi/InteractionExecutionRepositoryMq_init_Test.java similarity index 81% rename from modules/spi/publishmq/impl/servicespi/src/test/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMq_init_Test.java rename to modules/spi/publishmq/impl/mq/src/test/java/org/isisaddons/module/publishmq/dom/mq/spi/InteractionExecutionRepositoryMq_init_Test.java index 2aae3e86f..7ae37c06d 100644 --- a/modules/spi/publishmq/impl/servicespi/src/test/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMq_init_Test.java +++ b/modules/spi/publishmq/impl/mq/src/test/java/org/isisaddons/module/publishmq/dom/mq/spi/InteractionExecutionRepositoryMq_init_Test.java @@ -1,4 +1,4 @@ -package org.isisaddons.module.publishmq.dom.servicespi; +package org.isisaddons.module.publishmq.dom.mq.spi; import java.util.Map; @@ -8,17 +8,19 @@ import org.junit.Before; import org.junit.Test; +import org.isisaddons.module.publishmq.dom.servicespi.PublisherServiceUsingActiveMq; + import static com.google.common.collect.ImmutableMap.of; -public class PublisherServiceUsingActiveMq_init_Test { +public class InteractionExecutionRepositoryMq_init_Test { - private PublisherServiceUsingActiveMq target; + private InteractionExecutionRepositoryMq target; Boolean fallThroughToConnect = false; @Before public void setUp() throws Exception { - target = new PublisherServiceUsingActiveMq() { + target = new InteractionExecutionRepositoryMq() { @Override void connect() { fallThroughToConnect = true; } diff --git a/modules/spi/publishmq/impl/pom.xml b/modules/spi/publishmq/impl/pom.xml index a6fb76a65..04c1d59af 100644 --- a/modules/spi/publishmq/impl/pom.xml +++ b/modules/spi/publishmq/impl/pom.xml @@ -33,6 +33,7 @@ servicespi jdo + mq camel statusclient diff --git a/modules/spi/publishmq/impl/servicespi/pom.xml b/modules/spi/publishmq/impl/servicespi/pom.xml index 64bde2955..ac34715f6 100644 --- a/modules/spi/publishmq/impl/servicespi/pom.xml +++ b/modules/spi/publishmq/impl/servicespi/pom.xml @@ -64,10 +64,6 @@ org.apache.isis.core isis-core-schema - - org.apache.activemq - activemq-all - @@ -81,6 +77,12 @@ test + + org.projectlombok + lombok + provided + + diff --git a/modules/spi/publishmq/impl/servicespi/src/main/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMq.java b/modules/spi/publishmq/impl/servicespi/src/main/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMq.java index 419ff01d4..9c9434c34 100644 --- a/modules/spi/publishmq/impl/servicespi/src/main/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMq.java +++ b/modules/spi/publishmq/impl/servicespi/src/main/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMq.java @@ -1,127 +1,60 @@ package org.isisaddons.module.publishmq.dom.servicespi; +import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.DeliveryMode; import javax.jms.JMSException; -import javax.jms.MessageProducer; -import javax.jms.Queue; import javax.jms.Session; -import javax.jms.TextMessage; -import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.broker.BrokerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.isis.applib.ApplicationException; import org.apache.isis.applib.annotation.DomainService; import org.apache.isis.applib.annotation.NatureOfService; import org.apache.isis.applib.annotation.Programmatic; import org.apache.isis.applib.services.iactn.Interaction; import org.apache.isis.applib.services.publish.PublishedObjects; import org.apache.isis.applib.services.publish.PublisherService; -import org.apache.isis.schema.ixn.v1.InteractionDto; -import org.apache.isis.schema.utils.InteractionDtoUtils; @DomainService( nature = NatureOfService.DOMAIN ) -public class PublisherServiceUsingActiveMq implements PublisherService { +public class PublisherServiceUsingActiveMq implements PublisherService, + PublisherServiceUsingActiveMqStatusProvider { private static final Logger LOG = LoggerFactory.getLogger(PublisherServiceUsingActiveMq.class); public static final String ROOT = "isis.services." + PublisherServiceUsingActiveMq.class.getSimpleName() + "."; - - public static final String KEY_VM_TRANSPORT_URL = ROOT + "vmTransportUri"; - public static final String KEY_VM_TRANSPORT_URL_DEFAULT = "vm://broker"; - - public static final String KEY_MEMBER_INTERACTIONS_QUEUE = ROOT + "memberInteractionsQueue"; - public static final String KEY_MEMBER_INTERACTIONS_QUEUE_DEFAULT = "memberInteractionsQueue"; - public static final String KEY_ENABLED = ROOT + "enabled"; public static final String KEY_ENABLED_DEFAULT = "true"; - public static final String KEY_PROPAGATE_EXCEPTION = ROOT + "propagateException"; - public static final String KEY_PROPAGATE_EXCEPTION_DEFAULT = "false"; - - - private ConnectionFactory jmsConnectionFactory; - private Connection jmsConnection; - - private static boolean transacted = true; - - private String vmTransportUrl; - String memberInteractionsQueueName; + @Programmatic + @lombok.Getter private boolean enabled; - private boolean propagateException; + //region > init, shutdown @PostConstruct public void init(Map properties) { enabled = properties.getOrDefault(KEY_ENABLED, KEY_ENABLED_DEFAULT).equalsIgnoreCase("true"); - propagateException = properties.getOrDefault(KEY_PROPAGATE_EXCEPTION, KEY_PROPAGATE_EXCEPTION_DEFAULT).equalsIgnoreCase("true"); - - vmTransportUrl = properties.getOrDefault(KEY_VM_TRANSPORT_URL, KEY_VM_TRANSPORT_URL_DEFAULT); - memberInteractionsQueueName = properties.getOrDefault(KEY_MEMBER_INTERACTIONS_QUEUE, - KEY_MEMBER_INTERACTIONS_QUEUE_DEFAULT); - - memberInteractionsQueueName = properties.getOrDefault(KEY_MEMBER_INTERACTIONS_QUEUE, - KEY_MEMBER_INTERACTIONS_QUEUE_DEFAULT); - if(!enabled) { LOG.warn("Service NOT enabled"); return; } - connect(); - - } - - void connect() { - jmsConnectionFactory = new ActiveMQConnectionFactory(vmTransportUrl); - - try { - jmsConnection = jmsConnectionFactory.createConnection(); - } catch (JMSException e) { - LOG.error("Unable to create connection", e); - } - - if(jmsConnection != null) { - try { - jmsConnection.start(); - } catch (JMSException e) { - LOG.error("Unable to start connection", e); - closeSafely(jmsConnection); - jmsConnection = null; - } - } } @PreDestroy public void shutdown() { - closeSafely(jmsConnection); } - private static void closeSafely(Connection connection) { - if(connection != null) { - try { - connection.close(); - } catch (JMSException e) { - //ignore - } - } - } - private static void closeSafely(Session session) { try { session.close(); @@ -130,133 +63,64 @@ private static void closeSafely(Session session) { } } - private static void stopSafely(final BrokerService broker) { - if(broker==null) { - return; - } - try { - broker.stop(); - } catch (Exception ignore) { - } - } - + //endregion + //region > publish (execution) @Override public void publish(final Interaction.Execution execution) { if(!enabled) { - LOG.info("Service NOT enabled; interaction will not be published"); + LOG.info("Service NOT enabled; interaction will not be persisted/propagated"); return; } - if(jmsConnection == null) { - LOG.warn("No JMS connection; interaction will not be published"); - return; - } - - final InteractionDto interactionDto = InteractionDtoUtils.newInteractionDto(execution); - persist(execution); - - sendUsingJms(interactionDto); - } - - private void sendUsingJms(final InteractionDto interactionDto) { - final String xml = InteractionDtoUtils.toXml(interactionDto); - - Session session = null; - try { - - session = jmsConnection.createSession(transacted, Session.SESSION_TRANSACTED); - final TextMessage message = session.createTextMessage(xml); - - final String transactionId = interactionDto.getTransactionId(); - final int sequence = interactionDto.getExecution().getSequence(); - final String executionId = transactionId + "." + sequence; - final String memberIdentifier = interactionDto.getExecution().getMemberIdentifier(); - - message.setJMSMessageID(executionId); - message.setJMSType(memberIdentifier); - - if(LOG.isInfoEnabled()) { - LOG.info(String.format( - "Sending JMS message, id:%s; type:%s", - message.getJMSMessageID(), message.getJMSType())); - } - - final Queue queue = session.createQueue(memberInteractionsQueueName); - final MessageProducer producer = session.createProducer(queue); - producer.setDeliveryMode(DeliveryMode.PERSISTENT); - producer.send(message); - - session.commit(); - - } catch (final JMSException ex) { - rollback(session); - if(propagateException) { - throw new ApplicationException(String.format( - "Failed to publish message, and aborting (as per '%s' property)", KEY_PROPAGATE_EXCEPTION), - ex); - } else { - LOG.error(String.format( - "Failed to publish message, but continuing (as per '%s' property)", KEY_PROPAGATE_EXCEPTION), - ex); - } - } finally { - if(session != null) { - closeSafely(session); - } - } } private void persist(final Interaction.Execution execution) { - if (interactionExecutionRepository == null) { + if (interactionExecutionRepositories == null) { return; } - interactionExecutionRepository.persist(execution); + interactionExecutionRepositories.forEach(interactionExecutionRepository -> { + interactionExecutionRepository.persist(execution); + }); } - private static void rollback(final Session session) { - try { - if (session != null) { - session.rollback(); - } - } catch (JMSException ex) { - // ignore - } - } + //endregion + //region > publish (published objects) @Override public void publish(final PublishedObjects publishedObjects) { + + if(!enabled) { + LOG.info("Service NOT enabled; publishedObjects will not be persisted/propagated"); + return; + } persist(publishedObjects); } private void persist(final PublishedObjects publishedObjects) { - if(publishedObjectsRepository == null) { + if(publishedObjectsRepositories == null) { return; } - publishedObjectsRepository.persist(publishedObjects); + publishedObjectsRepositories.forEach(publishedObjectsRepository -> { + publishedObjectsRepository.persist(publishedObjects); + }); } - - /** - * Private API. - * @param interactionDto - */ - @Programmatic - public void republish(final InteractionDto interactionDto) { - sendUsingJms(interactionDto); - } + //endregion + //region > injected services @Inject - PublishedObjectsRepository publishedObjectsRepository; + List publishedObjectsRepositories; @Inject - InteractionExecutionRepository interactionExecutionRepository; + List interactionExecutionRepositories; + //endregion } diff --git a/modules/spi/publishmq/impl/servicespi/src/main/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMqStatusProvider.java b/modules/spi/publishmq/impl/servicespi/src/main/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMqStatusProvider.java new file mode 100644 index 000000000..2da3e8ec8 --- /dev/null +++ b/modules/spi/publishmq/impl/servicespi/src/main/java/org/isisaddons/module/publishmq/dom/servicespi/PublisherServiceUsingActiveMqStatusProvider.java @@ -0,0 +1,14 @@ +package org.isisaddons.module.publishmq.dom.servicespi; + +import org.apache.isis.applib.annotation.Programmatic; + +/** + * Implemented by {@link PublisherServiceUsingActiveMq} itself, simply so can be injected into other SPI services + * (implementations of {@link InteractionExecutionRepository} and {@link PublishedObjectsRepository}) so that they + * enquire as to whether they should be enabled or not. + */ +public interface PublisherServiceUsingActiveMqStatusProvider { + + @Programmatic + boolean isEnabled(); +} diff --git a/modules/spi/publishmq/integtests/pom.xml b/modules/spi/publishmq/integtests/pom.xml index fe5eab162..02e2fa4b7 100644 --- a/modules/spi/publishmq/integtests/pom.xml +++ b/modules/spi/publishmq/integtests/pom.xml @@ -112,6 +112,12 @@ test + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + test + + org.isisaddons.module.publishmq isis-module-publishmq-dom-camel diff --git a/modules/spi/security/fixture/pom.xml b/modules/spi/security/fixture/pom.xml index 26745d54e..df4c5b163 100644 --- a/modules/spi/security/fixture/pom.xml +++ b/modules/spi/security/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/spi/security/integtests/pom.xml b/modules/spi/security/integtests/pom.xml index 03c00ea72..23245f7b5 100644 --- a/modules/spi/security/integtests/pom.xml +++ b/modules/spi/security/integtests/pom.xml @@ -112,6 +112,12 @@ test + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + test + + org.isisaddons.module.publishmq isis-module-publishmq-dom-camel diff --git a/modules/spi/sessionlogger/integtests/pom.xml b/modules/spi/sessionlogger/integtests/pom.xml index 047d2486c..3d9213829 100644 --- a/modules/spi/sessionlogger/integtests/pom.xml +++ b/modules/spi/sessionlogger/integtests/pom.xml @@ -112,6 +112,12 @@ test + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + test + + org.isisaddons.module.publishmq isis-module-publishmq-dom-camel diff --git a/modules/wkt/pdfjs/fixture/pom.xml b/modules/wkt/pdfjs/fixture/pom.xml index 7371f90e2..22473d4ff 100644 --- a/modules/wkt/pdfjs/fixture/pom.xml +++ b/modules/wkt/pdfjs/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/modules/wkt/wickedcharts/fixture/pom.xml b/modules/wkt/wickedcharts/fixture/pom.xml index 157fd6a31..5f8518684 100644 --- a/modules/wkt/wickedcharts/fixture/pom.xml +++ b/modules/wkt/wickedcharts/fixture/pom.xml @@ -173,6 +173,11 @@ TODO: to reinstate, think that FixturesManifest needs some attention. isis-module-publishmq-dom-jdo + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.security isis-module-security-dom diff --git a/webapp/appdefn/pom.xml b/webapp/appdefn/pom.xml index 142c2dc34..e88c0364a 100644 --- a/webapp/appdefn/pom.xml +++ b/webapp/appdefn/pom.xml @@ -254,10 +254,17 @@ Execution default of goal org.apache.isis.tool:isis-maven-plugin:1.16.2:swagger org.isisaddons.module.publishmq isis-module-publishmq-dom-jdo + + + org.isisaddons.module.publishmq + isis-module-publishmq-dom-mq + + org.isisaddons.module.publishmq isis-module-publishmq-dom-servicespi + org.isisaddons.module.publishmq isis-module-publishmq-fixtures diff --git a/webapp/appdefn/src/main/java/org/incode/platformapp/appdefn/PlatformAppAppDefnModule.java b/webapp/appdefn/src/main/java/org/incode/platformapp/appdefn/PlatformAppAppDefnModule.java index f18e9f458..4aaab2004 100644 --- a/webapp/appdefn/src/main/java/org/incode/platformapp/appdefn/PlatformAppAppDefnModule.java +++ b/webapp/appdefn/src/main/java/org/incode/platformapp/appdefn/PlatformAppAppDefnModule.java @@ -29,7 +29,6 @@ import org.isisaddons.module.poly.PolyModule; import org.isisaddons.module.poly.fixture.PolyFixturesModule; import org.isisaddons.module.publishmq.dom.jdo.PublishMqSpiJdoModule; -import org.isisaddons.module.publishmq.dom.servicespi.PublishMqSpiServicesModule; import org.isisaddons.module.publishmq.fixture.PublishMqFixturesModule; import org.isisaddons.module.quartz.dom.QuartzModule; import org.isisaddons.module.security.SecurityModule;