I wanted to check Anomalous events in a window of say 3 days. I have a following drools code which outputs all events and not restricting to just 3 days. Same problem happens even if I put 1 day instead of 3. I do fireAllRules after each insert.
If use window:length(3) it works perfectly but not by time. Is there anything wrong I am doing?
Also, I have another question #expires annotation, does it work on my custom timestamp or from the time an event/fact inserted into working memory?
Have put simplified unit test at https://github.com/mtekp/droolsExperiments/tree/main/testdrools
I am using drools:7.43.1.Final.
My kmodule.xml
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="TestEventsC" packages="test.events.continuous" eventProcessingMode="stream">
<ksession name="TestDroolEventsContinous" clockType="realtime"/>
</kbase>
</kmodule>
The drool rule
package test.events.continuous
declare AnomalyCount
#role(event)
#timestamp(anomalyDate)
#expires(3d)
end
rule "insert anomaly count"
dialect "java"
when
$aei: AnomalyEventInsert()
not AnomalyCount(anomalyDate == $aei.ts)
then
insert(new AnomalyCount($aei.getTs(), 1));
delete($aei);
end
rule "increment count"
dialect "java"
when
$aei: AnomalyEventInsert()
$ac: AnomalyCount(anomalyDate == $aei.ts)
then
modify($ac) { setAnomalyCount($ac.getAnomalyCount() + 1)};
delete($aei);
end
rule "Check continuous 3 days"
dialect "java"
when
$anomalies : List() from accumulate(AnomalyCount($dt : anomalyDate) over window:time(3d);collectList( $dt ))
then
System.out.println("anomalies: "+ $anomalies);
end
AnomalyCount.java
import org.kie.api.definition.type.Role;
import java.util.Date;
#org.kie.api.definition.type.Role(Role.Type.EVENT)
#org.kie.api.definition.type.Timestamp("anomalyDate")
//#org.kie.api.definition.type.Expires("1d")
public class AnomalyCount {
public AnomalyCount(Date anomalyDate, int anomalyCount) {
this.anomalyDate = anomalyDate;
this.anomalyCount = anomalyCount;
}
public Date getAnomalyDate() {
return anomalyDate;
}
public void setAnomalyDate(Date anomalyDate) {
this.anomalyDate = anomalyDate;
}
public int getAnomalyCount() {
return anomalyCount;
}
public void setAnomalyCount(int anomalyCount) {
this.anomalyCount = anomalyCount;
}
#Override
public String toString() {
return "AnomalyCount{" +
"anomalyDate=" + anomalyDate +
", anomalyCount=" + anomalyCount +
'}';
}
private Date anomalyDate;
private int anomalyCount = 0;
}
AnomalyEventInsert.java
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Date;
public class AnomalyEventInsert extends AnomalyEvent {
public AnomalyEventInsert(LocalDate ts, long sequenceCount, long value) {
this.ts = Date.from(ts.atStartOfDay().toInstant( ZoneOffset.UTC));
this.value = value;
this.sequenceCount = sequenceCount;
}
public AnomalyEvent toAnomalyEvent() {
return new AnomalyEvent(ts, sequenceCount, value);
}
#Override
public String toString() {
return "AnomalyEventInsert{" +
"ts=" + ts +
", sequenceCount=" + sequenceCount +
", value=" + value +
'}';
}
}
When I insert data for 6th,7th,8th,9th I get all four instead of last 3 when the window moves.
found output
anomalies: [Tue Oct 06 05:30:00 IST 2020, Wed Oct 07 05:30:00 IST 2020, Thu Oct 08 05:30:00 IST 2020, Fri Oct 09 05:30:00 IST 2020]
instead of
anomalies: [Wed Oct 07 05:30:00 IST 2020, Thu Oct 08 05:30:00 IST 2020, Fri Oct 09 05:30:00 IST 2020]
Related
This is an auto forwarded email.
I'm trying to verify the bh field as per rfc5322.
But the sha256 hash value received is not matching this value.
The message body is: for forwarded mail
Any suggestions to validate the bh= field correctly?
I have included some sample header field data. Please do explain (relaxed) canonical procedure too
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1516798995;
s=jan2017; d=headsup.co.in; i=sender#headsup.co.in;
h=Date:From:To:Message-Id:Subject:MIME-Version:Content-Type; l=627;
bh=ODw8icD/S+4UGcXgR4ocNpxXDh4PolWtd1IUXjh0AUs=;
b=G2vTZ+uQ+krw49l+4aMnaeZjUvAJXPPRA8bvOhs3XZNbd2Ng+odB/F5PI3tRpdhr
C0CJA5KPv4VncP2V1PjNdkgKLjs1eTzLSaqmPjhhQDc8mWQRT0rzcPP3V9v6BeXF987
54Zns/QWtR+RbSacFXvUjyBEOlaWUVAmaVcqw5S8=
//Message: for forwarded mail
//Example Data
Date: Wed, 24 Jan 2018 18:33:08 +0530
From: sender <sender#headsup.co.in>
To: "receiver" <receiver#gmail.com>
Message-Id: <1612843d10d.d305604a24030.1212846966506749871#headsup.co.in>
Subject: Test Arc Seal
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_Part_76205_1329960269.1516798988558"
X-Priority: Medium
//Cannonicalization code (relaxed)
package canonicalization;
import java.io.IOException;
public class Canonicalization {
public String canonicalizeHeader(String name, String value) {
name = name.trim().toLowerCase();
value = value.replaceAll("\\s+", " ").trim();
return name + ":" + value;
}
public String canonicalizeBody(String body) {
if (body == null || "".equals(body)) {
return "\r\n";
}
body = body.replaceAll("[ \\t\\x0B\\f]+", " ");
body = body.replaceAll(" \r\n", "\r\n");
// The body must end with \r\n
if (!body.endsWith("\r\n")) {
return body + "\r\n";
}
// Remove trailing empty lines ...
while (body.endsWith("\r\n\r\n")) {
body = body.substring(0, body.length() - 2);
}
return body;
}
public static void main(String[] args) {
Canonicalization obj=new Canonicalization();
System.out.println(obj.canonicalizeHeader("Date"," Wed, 24 Jan 2018 18:33:08 +0530"));
System.out.println(obj.canonicalizeHeader("From"," sender <sender#headsup.co.in>"));
System.out.println(obj.canonicalizeHeader("To"," \"receiver\" <receiver#gmail.com>"));
System.out.println(obj.canonicalizeBody("for forwarded mail"));
}
}
You don't provide any code to illustrate how you are attempting to verify the body hash, but most likely you are incorrectly canonicalizing the input fed to the hashing function.
The code works fine for emails sent in plaintext format (Content-Type: text/plain;)
But by default, emails are sent by Rich Text Format (Content-Type: multipart/alternative;), hence the body hashes did not match
I am using Ionic 2 with Meteor/Mongo.
I am trying to sort a Cursor, but find it just keeps the original order which the items were inserted.
model
interface Chat {
_id?: string;
memberIds?: string[];
title?: string;
subTitle?: string;
picture?: string;
lastMessage?: Message;
lastMessageCreatedAt?: Date;
receiverComp?: Tracker.Computation;
lastMessageComp?: Tracker.Computation;
}
ts
private sortLocalChats(): void {
this.localChatCursor = this.localChatCollection.find({}, { sort: { lastMessageCreatedAt: -1 } });
this.localChatCursor.forEach((chat: Chat) => {
console.log(chat.title+' '+chat.lastMessageCreatedAt);
});
console.log('==> loaded sorted local chats: ' + this.localChatCollection.find().count());
output
Ashton Marais Thu Oct 06 2016 16:50:36 GMT+0800 (CST)
Ashton Marais Wed Oct 12 2016 21:20:18 GMT+0800 (CST)
ghjghj ghjghg Wed Oct 05 2016 23:37:49 GMT+0800 (CST)
Brett Simpson Thu Oct 06 2016 23:52:05 GMT+0800 (CST)
==> loaded sorted local chats: 4
I would have expected this to be sorted by lastMessageCreatedAt.
Any help appreciated.
To get sorted results you probably need to call fetch() first. So in the above example this works:
this.localChatCursor.fetch().forEach(...);
I was trying to produce some messages and put into topic, and then getch the same from console consumer.
Code used :
import java.util.Date;
import java.util.Properties;
import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
public class SimpleProducer {
private static Producer<String,String> producer;
public SimpleProducer() {
Properties props = new Properties();
// Set the broker list for requesting metadata to find the lead broker
props.put("metadata.broker.list","172.22.96.56:9092,172.22.96.56:9093,172.22.96.56:9094");
//This specifies the serializer class for keys
props.put("serializer.class", "kafka.serializer.StringEncoder");
// 1 means the producer receives an acknowledgment once the lead replica
// has received the data. This option provides better durability as the
// client waits until the server acknowledges the request as successful.
props.put("request.required.acks", "1");
ProducerConfig config = new ProducerConfig(props);
producer = new Producer<String, String>(config);
}
public static void main(String[] args) {
int argsCount = args.length;
if (argsCount == 0 || argsCount == 1)
throw new IllegalArgumentException(
"Please provide topic name and Message count as arguments");
String topic = (String) args[0];
String count = (String) args[1];
int messageCount = Integer.parseInt(count);
System.out.println("Topic Name - " + topic);
System.out.println("Message Count - " + messageCount);
SimpleProducer simpleProducer = new SimpleProducer();
simpleProducer.publishMessage(topic, messageCount);
}
private void publishMessage(String topic, int messageCount) {
for (int mCount = 0; mCount < messageCount; mCount++) {
String runtime = new Date().toString();
String msg = "Message Publishing Time - " + runtime;
System.out.println(msg);
// Creates a KeyedMessage instance
KeyedMessage<String, String> data =
new KeyedMessage<String, String>(topic, msg);
// Publish the message
producer.send(data);
}
// Close producer connection with broker.
producer.close();
}
}
OUTPUT:
Topic Name - test
Message Count - 10
log4j:WARN No appenders could be found for logger
(kafka.utils.VerifiableProperties).
log4j:WARN Please initialize the log4j system properly.
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
Message Publishing Time - Tue Feb 16 02:00:56 IST 2016
from command line i supply the name of the topic as "kafkatopic" and count of the messages "10". The program runs fine without ant exception but when i try to see the messages from console, they do not appear. The topic is created.
bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic kafkatopic --from-beginning
Can you plaease help as what went wrong!!
Two things I would like to point out:
1) You don't specify --zookeeper here - you should you --bootstrap-server argument.
2) You should see what the server.properties file say about listeners and advertised.listener. You should correctly point them to the brokers.
I hope this helps.
Is there a way to retrieve data stored as page metadata (Page Properties) stored in a separate JCR node via the QueryBuilder API?
Example:
The search results should include the data under ~/article-1/jcr:content/thumbnail. However, the only results I am getting are data under the ~article-1/jcr:content/content (a parsys included on the template).
An example query:
http://localhost:4502/bin/querybuilder.json?p.hits=full&path=/content/path/to/articles
Results in (snippet):
{
"jcr:path":"/content/path/to/articles/article-1",
"jcr:createdBy":"admin",
"jcr:created":"Tue Dec 03 2013 16:26:51 GMT-0500",
"jcr:primaryType":"cq:Page"
},
{
"jcr:path":"/content/path/to/articles/article-1/jcr:content",
"sling:resourceType":"myapp/components/global/page/productdetail",
"jcr:lockIsDeep":true,
"jcr:uuid":"4ddebe08-82e1-44e9-9197-4241dca65bdf",
"jcr:title":"Article 1",
"jcr:mixinTypes":[
"mix:lockable",
"mix:versionable"
],
"jcr:created":"Tue Dec 03 2013 16:26:51 GMT-0500",
"jcr:baseVersion":"24cabbda-1e56-4d37-bfba-d0d52aba1c00",
"cq:lastReplicationAction":"Activate",
"jcr:isCheckedOut":true,
"cq:template":"/apps/myapp/templates/global/productdetail",
"cq:lastModifiedBy":"admin",
"jcr:primaryType":"cq:PageContent",
"jcr:predecessors":[
"24cabbda-1e56-4d37-bfba-d0d52aba1c00"
],
"cq:tags":[
"mysite:mytag"
],
"jcr:createdBy":"admin",
"jcr:versionHistory":"9dcd41d4-2e10-4d52-b0c0-1ea20e102e68",
"cq:lastReplicatedBy":"admin",
"cq:lastModified":"Mon Dec 09 2013 17:57:59 GMT-0500",
"cq:lastReplicated":"Mon Dec 16 2013 11:42:54 GMT-0500",
"jcr:lockOwner":"admin"
}
Search configuration is the out-of-the-box default.
EDIT: Data is returning in JSON, however, is not accessable in the API:
Result:
{
"success":true,
"results":2,
"total":2,
"offset":0,
"hits":[
{
"jcr:path":"/content/path/to/articles/article-a",
"jcr:createdBy":"admin",
"jcr:created":"Tue Dec 03 2013 16:27:01 GMT-0500",
"jcr:primaryType":"cq:Page",
"jcr:content":{
"sling:resourceType":"path/to/components/global/page/productdetail",
"_comment":"// ***SNIP*** //",
"thumbnail":{
"jcr:lastModifiedBy":"admin",
"imageRotate":"0",
"jcr:lastModified":"Wed Dec 04 2013 12:10:47 GMT-0500",
"jcr:primaryType":"nt:unstructured"
}
}
},
{
"jcr:path":"/content/path/to/articles/article-1",
"jcr:createdBy":"admin",
"jcr:created":"Tue Dec 03 2013 16:26:51 GMT-0500",
"jcr:primaryType":"cq:Page",
"jcr:content":{
"sling:resourceType":"path/to/components/global/page/productdetail",
"_comment":"// ***SNIP*** //",
"thumbnail":{
"jcr:lastModifiedBy":"admin",
"imageRotate":"0",
"fileReference":"/content/dam/path/to/IBMDemo/apparel/women/wsh005_shoes/WSH005_0533_is_main.jpg",
"jcr:lastModified":"Mon Dec 09 2013 17:57:58 GMT-0500",
"jcr:primaryType":"nt:unstructured"
}
}
}
]
}
Implementation code:
searchCriteria.put("path", path);
searchCriteria.put("type", "cq:Page");
searchCriteria.put("p.offset", offset.toString());
searchCriteria.put("p.limit", limit.toString());
searchCriteria.put("p.hits", "full");
searchCriteria.put("p.properties", "thumbnail");
searchCriteria.put("p.nodedepth", "2");
PredicateGroup predicateGroup = PredicateGroup.create(searchCriteria);
Query query = queryBuilder.createQuery(predicateGroup, session);
SearchResult result = query.getResult();
for (Hit hit : result.getHits()) {
try {
ValueMap properties = hit.getProperties();
VFSearchResult res = new VFSearchResult();
res.setUrl(hit.getPath());
res.setImageUrl((String)properties.get("thumbnail"));
res.setTags((String[])properties.get("cq:tags"));
res.setTeaserText((String)properties.get("teaserText"));
res.setTitle((String)properties.get("jcr:title"));
searchResults.add(res);
} catch (RepositoryException rex) {
logger.debug(String.format("could not retrieve node properties: %1s", rex));
}
}
After setting the path in the query, then set one or more property filters, such as in this example:
type=cq:Page
path=/content/path/to/articles
property=jcr:content/thumbnail
property.operation=exists
p.hits=selective
p.properties=jcr:content/thumbnail someSpecificThumbnailPropertyToRetrieve
p.limit=100000
You can set those on /libs/cq/search/content/querydebug.html and then also use that to get the JSON URL for the same query.
Check this out for some other examples: http://dev.day.com/docs/en/cq/5-5/dam/customizing_and_extendingcq5dam/query_builder.html
You could use CURL to retrieve node properties in the HTML/ JSON/ XML format. All you have to do is install download CURL and run your curl commands from your terminal from the same directory as the curl's .exe file.
HTML example:
C:\Users\****\Desktop>curl -u username:password http://localhost:4502/content/geometrixx-media/en/gadgets/leaps-in-ai.html
JSON example:
**C:\Users\****\Desktop>**curl -u username:password http://localhost:4502/content/geometrixx-media/en/gadgets/leaps-in-ai.html.tidy.infinity.json
Note: infinity in the above query ensures you get every property of every node under your specified path recursively
I encountered a problem when parsing email with mime4j.
The email has an attachment, and I use MimeStreamParser to parse it.
The parser does not call startMultipart method at all. Instead, it only calls body method once, and the BodyDescriptor is "text/plain".
I do not know the root of this problem, the email format or my program?
Here is my test program:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.james.mime4j.*;
import org.apache.james.mime4j.dom.BinaryBody;
import org.apache.james.mime4j.dom.Body;
import org.apache.james.mime4j.dom.Entity;
import org.apache.james.mime4j.dom.Header;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.dom.MessageBuilder;
import org.apache.james.mime4j.dom.Multipart;
import org.apache.james.mime4j.dom.TextBody;
import org.apache.james.mime4j.dom.address.Mailbox;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.dom.field.AddressListField;
import org.apache.james.mime4j.dom.field.ContentTypeField;
import org.apache.james.mime4j.dom.field.DateTimeField;
import org.apache.james.mime4j.dom.field.UnstructuredField;
import org.apache.james.mime4j.field.address.AddressFormatter;
import org.apache.james.mime4j.message.BodyPart;
import org.apache.james.mime4j.message.MessageImpl;
import org.apache.james.mime4j.message.DefaultMessageBuilder;
import org.apache.james.mime4j.message.SimpleContentHandler;
import org.apache.james.mime4j.parser.ContentHandler;
import org.apache.james.mime4j.parser.MimeStreamParser;
import org.apache.james.mime4j.stream.BodyDescriptor;
import org.apache.james.mime4j.stream.Field;
import org.apache.james.mime4j.stream.MimeConfig;
public class TestClass extends SimpleContentHandler{
public static void main(String[] args) throws MimeException, IOException {
ContentHandler handler = new TestClass();
MimeConfig config = new MimeConfig();
MimeStreamParser parser = new MimeStreamParser(config);
parser.setContentHandler(handler);
InputStream instream = new FileInputStream("mail/testuser1");
try {
parser.parse(instream);
} finally {
instream.close();
}
}
#Override
public void headers(Header arg0) {
// TODO Auto-generated method stub
System.out.println("headers args: "+arg0);
}
#Override
public void body(BodyDescriptor bd, InputStream is) {
// TODO Auto-generated method stub
System.out.println("body descriptor: "+bd);
}
public void startMessage(){
System.out.println("startMessage");
}
public void endMessage(){
System.out.println("endMessage");
}
public void startBodyPart(){
System.out.println("startBodyPart");
}
public void endBodyPart() {
System.out.println("endBodyPart");
}
public void preamble(InputStream is){
System.out.println("preamble");
}
public void epilogue(InputStream is) {
System.out.println("epilogue");
}
public void startMultipart(BodyDescriptor bd){
System.out.println("startMultipart");
}
public void endMultipart() {
System.out.println("endMultipart");
}
public void raw(InputStream is) {
System.out.println("raw");
}
}
Here is a part of my email file:
From MAILER_DAEMON Wed Aug 21 19:24:53 2013
Date: Wed, 21 Aug 2013 19:24:53 +0800
From: Mail System Internal Data <MAILER-DAEMON#mail.abc.com>
Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
Message-ID: <1377084293#mail.abc.com>
X-IMAP: 1377072167 0000000003
Status: RO
This text is part of the internal format of your mail folder, and is not
a real message. It is created automatically by the mail system software.
If deleted, important folder data will be lost, and it will be re-created
with the data reset to initial values.
From testuser2#abc.com Sat Aug 24 10:53:42 2013
Return-Path: <testuser2#abc.com>
X-Original-To: testuser1#abc.com
Delivered-To: testuser1#abc.com
Received: from shupc (unknown [192.168.75.130])
by mail.abc.com (Postfix) with SMTP id C0F5B1EFBC3
for <testuser1#abc.com>; Sat, 24 Aug 2013 10:53:42 +0800 (CST)
Message-ID: <7F1C30C9CB284CA594D01CBE210257D3#shupc>
From: "john" <testuser2#abc.com>
To: "smith" <testuser1#abc.com>
Subject: aaa
Date: Sat, 24 Aug 2013 10:53:42 +0800
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_NextPart_000_000B_01CEA0B8.32903020"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2900.5512
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5512
X-UID: 3
Status: O
Content-Length: 386430
This is a multi-part message in MIME format.
------=_NextPart_000_000B_01CEA0B8.32903020
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_000C_01CEA0B8.32903020"
------=_NextPart_001_000C_01CEA0B8.32903020
Content-Type: text/plain;
charset="gb2312"
Content-Transfer-Encoding: base64
dGVzdCBhYSBiYiBjYw==
------=_NextPart_001_000C_01CEA0B8.32903020
Content-Type: text/html;
charset="gb2312"
Content-Transfer-Encoding: base64
PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgaHR0cC1lcXVpdj1Db250ZW50LVR5cGUgY29udGVu
dD0idGV4dC9odG1sOyBjaGFyc2V0PWdiMjMxMiI+DQo8TUVUQSBjb250ZW50PSJNU0hUTUwgNi4w
MC4yOTAwLjU1MTIiIG5hbWU9R0VORVJBVE9SPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+DQo8
Qk9EWSBiZ0NvbG9yPSNmZmZmZmY+DQo8RElWPjxGT05UIHNpemU9Mj50ZXN0IGFhIGJiIGNjPC9G
T05UPjwvRElWPjwvQk9EWT48L0hUTUw+DQo=
------=_NextPart_001_000C_01CEA0B8.32903020--
------=_NextPart_000_000B_01CEA0B8.32903020
Content-Type: application/octet-stream;
name="10112716229607.doc"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="10112716229607.doc"
0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAAFAAAAKAIAAAAAAAAA
EAAAKgIAAAEAAAD+////AAAAACMCAAAkAgAAJQIAACYCAAAnAgAA////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////s
pcEAcWAJBAAA8FK/AAAAAAAAEAAAAAAABgAArJ0CAA4AYmpianFQcVAAAAAAAAAAAAAAAAAAAAAA
AAAECBYAOBIDABM6AQATOgEA1gwBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//w8AAAAA
AAAAAAD//w8AAAAAAAAAAAD//w
The problem is with the sample email which not multipart. It contains, as inline text, a multipart email.
Remove the first headers ("FROM MAILER") and then make sure all lines following after Content-Type are indented (eg charset and boundary) by at least one whitespace character as required by the spec (RFC822 or later) or remove the linefeed. See example:
Change from :
Content-Type: multipart/mixed;
boundary="----=_NextPart_000_000B_01CEA0B8.32903020"
to either:
Content-Type: multipart/mixed;
boundary="----=_NextPart_000_000B_01CEA0B8.32903020"
or:
Content-Type: multipart/mixed; boundary="----=_NextPart_000_000B_01CEA0B8.32903020"
Alternatively, try a different message.
Use the following library based on mime4j:
email-mime-parser
The provided sample code takes care of email parsing and the resulting 'email' object provides convenience method for the solution of your problem :
ContentHandler contentHandler = new CustomContentHandler();
MimeConfig mime4jParserConfig = new MimeConfig();
BodyDescriptorBuilder bodyDescriptorBuilder = new DefaultBodyDescriptorBuilder();
MimeStreamParser mime4jParser = new MimeStreamParser(mime4jParserConfig,DecodeMonitor.SILENT,bodyDescriptorBuilder);
mime4jParser.setContentDecoding(true);
mime4jParser.setContentHandler(contentHandler);
InputStream mailIn = 'Provide email mime stream here';
mime4jParser.parse(mailIn);
Email email = ((CustomContentHandler) contentHandler).getEmail();