Spring Integration: Imap, continuous remote service polling caused by attribute mail-filter-expression in imap-idle-channel-adapter - email

I implemented a imap idle mail receiver with spring integration mail 4.2.6.
When, in the configuration of the receiver in the tag
<mail:imap-idle-channel-adapter mail-filter-expression="something" ... >
i use the attribute "mail-filter-expression" this causes continuous ( about every second) polling of the remote mail service with this repeated message:
10:29:21 INFO o.s.i.mail.ImapMailReceiver - attempting to receive mail from folder [INBOX]
If i remove the attribute "mail-filter-expression" this continuos polling disappears.
I don't know if this is the desired behavior of the framework.
My idea is to limit this comtinuos polling of the remote service, in fact i'm using the imap-idle-channel-adapter
this is my configuration of the receiver:
<mail:imap-idle-channel-adapter
id="mailAdapterMailInAccettazione"
store-uri="imaps://...the url of the remote service
channel="emailsInAccettazioneDaLeggere"
auto-startup="true"
should-delete-messages="false"
should-mark-messages-as-read="false"
java-mail-properties="javaMailProperties"
mail-filter-expression="subject matches '(?i).*somenthing: .*'" >
<mail:transactional synchronization-factory="syncFactoryAccettazione"/>
</mail:imap-idle-channel-adapter>
I want to cofigure the receiver in idle mode but using the mail-filter-expression attribute because i want to read only some emails.
UPDATE : after further investigation i discovered that the remote mail service doesn't support RECENT and USER flag:
This email server does not support RECENT or USER flags
So this is what was happening:
mail-filter-expression caused messages to get filtered, but no message was flagged as RECENT = false. This caused
continuous attempts to read the messages as all messages always appeared "
new"
.
I re implemented the flow not using the mail-filter-expression but filtering messages in subsequent channels

Related

Is there a way to access ActiveMQ Artemis System Logs (enabled by Broker plugin) from a .NET Client

I have enabled message delivery logs on our Artemis instances using broker plugins according to this page. To draw some analytics by mapping end to end message delivery and receipt timings between publisher -> artemis server -> subscriber, I'm trying to see if the contents of the message that are being logged to artemis log file (To be specific Message ID) can be accessed by the publishing and subscribing .NET applications we have. Below are logs from the artemis.log file for a message with MessageId indicating various events.
20:50:24,552 INFO
[org.apache.activemq.artemis.core.server.plugin.impl] AMQ841010:
routed message with ID: 2231685496, result: OK
20:50:24,552 INFO
[org.apache.activemq.artemis.core.server.plugin.impl] AMQ841009: sent
message with ID: 2231685496, session name:
9d9c035b-176e-11ea-ab75-020ff9805db8, session connectionID: 68a7ec34,
result: OK
20:50:24,553 INFO
[org.apache.activemq.artemis.core.server.plugin.impl] AMQ841012:
delivered message with message ID: 2231685496, to consumer on address:
News.Source.T, queue: f0586137-5ad3-4c77-b2c7-5b68daad672c, consumer
sessionID: fcbcd194-3295-11ea-a2c0-0a89c5c4c02a, consumerID: 0
20:50:24,554 INFO
[org.apache.activemq.artemis.core.server.plugin.impl] AMQ841014:
acknowledged message ID: 2231685496, messageRef sessionID:
fcbcd194-3295-11ea-a2c0-0a89c5c4c02a, with messageRef consumerID: 0,
messageRef QueueName: f0586137-5ad3-4c77-b2c7-5b68daad672c, with
ackReason: NORMAL
We are using AMQPNetLite for this and haven't found anything that can help us tie these messages sent and received to the logs that are being written to the artemis.log file. I've been looking to understand if there is a way to get a hold of the MessageId from these logs on the publisher application. Any pointers on this topic are much appreciated.
Messaging clients can't get data from the broker's log files since that data is just in a text-based log and not actually in the message broker itself. However, you could use something like the NotificationActiveMQServerPlugin which, instead of logging this information, will actually send messages with this information to the management notification address. Clients can create subscriptions on the management notification address and receive the messages and then take action based on that information. The notification messages may not contain all the information you need, but you can easily extend this class to create your own plugin which includes all the information you need.

Spring integration: mail:outbound-channel-adapter suceed or failed

Using spring integration, how to know if a mail is sent succefully or failed, because I should handle the result.
My code:
<mail:outbound-channel-adapter channel="outboundMailChannel"
mail-sender="mailSender" >
</mail:outbound-channel-adapter>
If the send fails, the adapter will throw an exception which you can handle on the error-channel of whatever's upstream of the adapter. Or, you can use a ExpressionEvaluatingMessageHandlerAdvice to take different actions based on success or failure.

Moqui - Connecting to an IMAP server over an SSL connection?

I am trying to poll an email server in Moqui 1.5.4. I am using org.moqui.impl.EmailServices.poll#EmailServer from the 'tools' application.
The email server is set up as follows:
<moqui.basic.email.EmailServer emailServerId="testEmail" mailUsername="test.account#xxxxxxx.ie" mailPassword="xxxxxxxx" smtpHost="" smtpPort="" smtpSsl="" storeHost="Webmail8.xxxxxxxxxxx.ie" storePort="993" storeProtocol="imap" storeDelete="N" />
All entries, passwords have been tested on Outlook and connect no problem to the server.
I get a javax.mail.AuthenticationFailedException.
Additional Information:
In initial tests I received the following error message, so I removed the 'static' modifier from the indicated line in the code. (I was not sure yet if it was an issue or if I may be doing something wrong.)
--- 98330 [ndlerThread[15]] WARN moqui.impl.context.TransactionFacadeImpl
Transaction rollback. The rollback was originally caused by: startup failed:
classpath_//org/moqui/impl/pollEmailServer_groovy: 28: Modifier 'static' not allowed here.
# line 28, column 1.
final static Logger logger = LoggerFactory.getLogger("org.moqui.impl.pollEmailServer")
Some things I tried to see if I could resolve the problem include:
setting storeProtocol="imaps"
including the smtp details in the EmailServer entry (note I only need to poll, not send mail).
adding the following line to pollEmailServer.groovy (having looked at the com.sun.mail.imap package).
sessionProperties.put("mail.imap.ssl.enable", true)
Full Authentication failed error message is:
Error running service [org.moqui.impl.EmailServices.poll#EmailServer] (Throwable)
javax.mail.AuthenticationFailedException
at javax.mail.Service.connect(Service.java:306)
at javax.mail.Service.connect(Service.java:156)
at javax.mail.Service.connect(Service.java:105)
at pollEmailServer_groovy.run(pollEmailServer_groovy:47)
at org.moqui.impl.context.runner.GroovyScriptRunner.run(GroovyScriptRunner.groovy:50)
at org.moqui.impl.context.ResourceFacadeImpl.script(ResourceFacadeImpl.groovy:337)
at org.moqui.impl.service.runner.ScriptServiceRunner.runService(ScriptServiceRunner.groovy:49)
at org.moqui.impl.service.ServiceCallSyncImpl.callSingle(ServiceCallSyncImpl.groovy:260)
at org.moqui.impl.service.ServiceCallSyncImpl.call(ServiceCallSyncImpl.groovy:137)
at ServiceRun_xml_transition_run_actions.run(ServiceRun_xml_transition_run_actions:10)
at org.moqui.impl.actions.XmlAction.run(XmlAction.groovy:99)
at org.moqui.impl.screen.ScreenDefinition$TransitionItem.run(ScreenDefinition.groovy:659)
at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:223)
at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:217)
at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:217)
at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:217)
at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:217)
at org.moqui.impl.screen.ScreenRenderImpl.internalRender(ScreenRenderImpl.groovy:301)
at org.moqui.impl.screen.ScreenRenderImpl.render(ScreenRenderImpl.groovy:164)
at org.moqui.impl.webapp.MoquiServlet.doScreenRequest(MoquiServlet.groovy:71)
at org.moqui.impl.webapp.MoquiServlet.doPost(MoquiServlet.groovy:37)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at net.winstone.core.ServletCotion.execute(ServletConfiguration.java:270)
at net.winstone.core.SimpleRequestDispatcher.forward(SimpleRequestDispatcher.java:290)
at net.winstone.core.listener.RequestHandlerThread.processRequest(RequestHandlerThread.java:212)
at net.winstone.core.listener.RequestHandlerThread.run(RequestHandlerThread.java:143)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at net.winstone.util.BoundedExecutorService$1.run(BoundedExecutorService.java:81)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Addendum: Processing the messages once polled with Email ECA Rules.
I can see when I turn on logger info in EmailEcaRule.groovy that the condition in my Email ECA keeps evaluating to 'false'. But it shouldn't be?
======== EMECA Process Received Email conditionPassed? false My condition: TestEmail fields:
(Note that I inserted "My condition: ${fields.subject}" into the logger info to double check my condition expression was as it should be.)
My emeca is:
<emecas xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/email-eca-1.5.xsd">
<emeca rule-name="Process Received Email">
<condition><expression>fields.subject == 'TestEmail'</expression></condition>
<actions>
<service-call name="org.moqui.impl.EmailServices.save#EcaEmailMessage" />
</actions>
</emeca>
</emecas>
I have tested and re-tested this. I don't know why it is evaluating to false. Please let me know if any additional information is required.
Still no luck in solving this. I must be doing something stupid. I commented out if (conditionPassed) {} in the EmailEcaRule.groovy to bypass my condition in the Email ECA rule and just run the action, but now it gets hung up with a "Cannot invoke method get() on null object" error in org.moqui.impl.EmailServices.save#EcaEmailMessage, presumably on headers.get('message-id'). But I can see in the log information that the message Id is in the headers information, and successfully converted to lower case.
There were a few issues with this. First is that Moqui was using an old version of JavaMail (now updated to 1.5.4). Another was how the password was passed through, and more generally there was lots of room for improvement in how the script for poll#EmailServer service was using the JavaMail API.
There are various changes in place as of commit #bf0f872. I was able to connect successfully using storeProtocol=imaps, storePort=993, etc.
To answer your question: without these code changes I don't think connection via SSL would be possible. In other words, this ended up being more of a bug report than a question.

Handling connection failures in apache-camel

I am writing an apache-camel RabbitMQ consumer. I would like to react somehow to connection problems (i.e. try to reconnect). Is it possible to configure apache-camel to automatically reconnect?
If not, how can I find out that a connection to the queue was interrupted? I've done the following test:
start the queue (and some producer)
start my consumer (it was getting messages as expected)
stop the queue (the messages stopped arriving, as expected, but no exception was thrown)
start the queue (no new messages were received)
I am using camel in Scala (via akka-camel), but a Java solution would be probably also OK
You can pass in the flag automaticRecoveryEnabled=true to the URI, Camel will reconnect if the connection is lost.
For automatic RabbitMQ resource recovery (Connections/Channels/Consumers/Queues/Exchanages/Bindings) when failures occur, check out Lyra (which I authored). Example usage:
Config config = new Config()
.withRecoveryPolicy(new RecoveryPolicy()
.withMaxAttempts(20)
.withInterval(Duration.seconds(1))
.withMaxDuration(Duration.minutes(5)));
ConnectionOptions options = new ConnectionOptions().withHost("localhost");
Connection connection = Connections.create(options, config);
The rest of the API is just the amqp-client API, except your resources are automatically recovered when failures occur.
I'm not sure about camel-rabbitmq specifically, but hopefully there's a way you can swap in your own resource creation via Lyra.
Current camel-rabbitmq just create a connection and the channel when the consumer or producer is started. So it don't have a chance to catch the connection exception :(.

Atmosphere Jersey - Server messages

Is it possible to let the server send messages to all connected clients without waiting for any action from them? Let me explain it :-) I've been reading the docs/examples and I have found nothing that satifies my needs: the flow is always the same; a client connects (e.g: a GET call to a Rest API), the connection is suspendend and until a new API call is received (e.g.: a POST call) the server simply waits (or at least this is what I have understood). My use case is pretty different: I want the server to send some "notifications" once new data become available. This would be my use case (pretty simplifed):
Client A connects to server
Connection is suspended since no new data is available at the moment
The server gets notified new data is available from an external
source and broadcasts it to client A
Go to step 2
What I have achieved so far is getting the connection successfully established. The next step is to solve this server issue. I must say this technology is completely new to me so it is possible I misunderstood how something works. If that's the case, let me know!
This is my stack:
Spring 3.2.0 RELEASE
Jersey 1.8
Atmosphere Jersey 1.0.13
Tomcat 7.0.40
Thank you all in advance!
UPDATE: After following this I get this warning, which I have no idea how to get rid of:
2013-06-04 09:40:36,284 WARN [org.atmosphere.cpr.AtmosphereFramework] - Failed using comet support: org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket, error: Tomcat failed to detect this is a Comet application because context.xml is missing or the Http11NioProtocol Connector is not enabled.
If that's not the case, you can also remove META-INF/context.xml and WEB-INF/lib/atmosphere-compat-tomcat.jar Is the Nio or Apr Connector enabled?
2013-06-04 09:40:36,285 WARN [org.atmosphere.cpr.AtmosphereFramework] - Using org.atmosphere.container.Tomcat7BIOSupportWithWebSocket
I followed the app structure commented here, so this should not be a problem. I have noticed that by changing the transport to "websocket" instead of "long-polling" shows no errors. The server finally sends data tough :)
I followed your link and modified the code a little.
When you are in the step 3 "The server gets notified new data is available from an external source and broadcasts it to client A", you have to write a line like this:
BroadcasterFactory.getDefault().lookup("/*").broadcast(response);
At first I used the TextMessage received from my ActiveMQ Queue but I get this error, so I used a Jackson class as an object response and everything worked fine.
SEVERE: A message body writer for Java class org.apache.activemq.command.ActiveMQTextMessage, and Java type class org.apache.activemq.command.ActiveMQTextMessage, and MIME media type application/json was not found
jun 03, 2014 11:32:21 AM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: The registered message body writers compatible with the MIME media type are:
application/json (JSONJAXBElementProvider, JSONArrayProvider, JSONObjectProvider, JSONRootElementProvider, JSONListElementProvider, ...)