Author: jaz
Date: Thu May 7 21:29:06 2009
New Revision: 772780
URL: http://svn.apache.org/viewvc?rev=772780&view=rev
Log:
implemented service to process bounced emails and update the
communication event status
Added:
ofbiz/trunk/applications/party/servicedef/mcas.xml
Modified:
ofbiz/trunk/applications/party/ofbiz-component.xml
ofbiz/trunk/applications/party/servicedef/services.xml
ofbiz/trunk/applications/party/src/org/ofbiz/party/communication/
CommunicationEventServices.java
Modified: ofbiz/trunk/applications/party/ofbiz-component.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/ofbiz-component.xml?rev=772780&r1=772779&r2=772780&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- ofbiz/trunk/applications/party/ofbiz-component.xml (original)
+++ ofbiz/trunk/applications/party/ofbiz-component.xml Thu May 7
21:29:06 2009
@@ -34,7 +34,8 @@
<service-resource type="model" loader="main"
location="servicedef/services.xml"/>
<service-resource type="model" loader="main"
location="servicedef/services_view.xml"/>
<service-resource type="eca" loader="main" location="servicedef/
secas.xml"/>
-
+ <service-resource type="mca" loader="main"
location="servicedef/mcas.xml"/>
+
<test-suite loader="main" location="testdef/PartyTests.xml"/>
<webapp name="party"
Added: ofbiz/trunk/applications/party/servicedef/mcas.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/mcas.xml?rev=772780&view=auto
=
=
=
=
=
=
=
=
=
=====================================================================
--- ofbiz/trunk/applications/party/servicedef/mcas.xml (added)
+++ ofbiz/trunk/applications/party/servicedef/mcas.xml Thu May 7
21:29:06 2009
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<service-mca xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/service-mca.xsd
">
+
+ <mca mail-rule-name="processBouncedMessage">
+ <action service="processBouncedMessage" mode="sync"/>
+ </mca>
+
+</service-mca>
Modified: ofbiz/trunk/applications/party/servicedef/services.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/services.xml?rev=772780&r1=772779&r2=772780&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- ofbiz/trunk/applications/party/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/party/servicedef/services.xml Thu May
7 21:29:06 2009
@@ -93,7 +93,10 @@
<service name="updatePerson" engine="java" default-entity-
name="Person"
location="org.ofbiz.party.party.PartyServices"
invoke="updatePerson" auth="true">
<description>Update a Person</description>
- <permission-service service-
name="partyGroupPermissionCheck" main-action="UPDATE"/>
+ <required-permissions join-type="AND">
+ <check-permission permission="update:party:${partyId}"/>
+ </required-permissions>
+ <!-- <permission-service service-
name="partyGroupPermissionCheck" main-action="UPDATE"/> -->
<auto-attributes mode="IN" include="pk" optional="true"><!--
if no partyId specified will use userLogin.partyId --></auto-
attributes>
<auto-attributes mode="IN" include="nonpk" optional="true"/>
<attribute name="preferredCurrencyUomId" type="String"
mode="IN" optional="true"/>
@@ -1167,4 +1170,10 @@
<attribute name="contactMechId" type="String" mode="IN"
optional="true"/>
<attribute name="contactMechId" type="String" mode="OUT"
optional="false"/>
</service>
+
+ <!-- bounced message processing -->
+ <service name="processBouncedMessage" engine="java"
+
location="org.ofbiz.party.communication.CommunicationEventServices"
invoke="processBouncedMessage">
+ <implements service="mailProcessInterface"/>
+ </service>
</services>
Modified: ofbiz/trunk/applications/party/src/org/ofbiz/party/
communication/CommunicationEventServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/communication/CommunicationEventServices.java?rev=772780&r1=772779&r2=772780&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- ofbiz/trunk/applications/party/src/org/ofbiz/party/
communication/CommunicationEventServices.java (original)
+++ ofbiz/trunk/applications/party/src/org/ofbiz/party/
communication/CommunicationEventServices.java Thu May 7 21:29:06
2009
@@ -31,8 +31,12 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.mail.Address;
+import javax.mail.BodyPart;
+import javax.mail.Header;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
@@ -946,4 +950,115 @@
}
return attachmentCount;
}
+
+ /*
+ * Service to process incoming email and look for a bounce
message. If the email is indeed a bounce message
+ * the CommunicationEvent will be updated with the proper
COM_BOUNCED status.
+ */
+ public static Map<String,Object>
processBouncedMessage(DispatchContext dctx, Map<String, ? extends
Object> context) {
+ Debug.logInfo("Running process bounced message check...",
module);
+ MimeMessageWrapper wrapper = (MimeMessageWrapper)
context.get("messageWrapper");
+ MimeMessage message = wrapper.getMessage();
+
+ LocalDispatcher dispatcher = dctx.getDispatcher();
+ GenericDelegator delegator = dctx.getDelegator();
+
+ try {
+ Object content = message.getContent();
+ if (content instanceof Multipart) {
+ Multipart mp = (Multipart) content;
+ int parts = mp.getCount();
+
+ if (parts >= 3) { // it must have all three parts
in order to process correctly
+
+ // get the second part (delivery report)
+ BodyPart part2 = mp.getBodyPart(1); // index 1
should be the second part
+ String contentType = part2.getContentType();
+ if (contentType != null && "message/delivery-
status".equalsIgnoreCase(contentType)) {
+ Debug.logInfo("Delivery status report part
found; processing...", module);
+
+ // message is only available as an input
stream; read the stream
+ InputStream insPart2 = (InputStream)
part2.getInputStream();
+ int part2Size = part2.getSize();
+ byte[] part2Bytes = new byte[part2Size];
+ insPart2.read(part2Bytes, 0, part2Size);
+ String part2Text = new String(part2Bytes);
+
+ // find the "Action" element and obtain
its value (looking for "failed")
+ Pattern p2 = Pattern.compile("^Action: (.*)
$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
+ Matcher m2 = p2.matcher(part2Text);
+ String action = null;
+ if (m2.find()) {
+ action = m2.group(1);
+ }
+
+ if (action != null &&
"failed".equalsIgnoreCase(action)) {
+ // message bounced -- get the original
message
+ BodyPart part3 = mp.getBodyPart(2); //
index 2 should be the third part
+
+ // read part 3 message
+ InputStream insPart3 = (InputStream)
part3.getInputStream();
+ int part3Size = part3.getSize();
+ byte[] part3Bytes = new byte[part3Size];
+ insPart3.read(part3Bytes, 0, part3Size);
+ String part3Text = new
String(part3Bytes);
+
+ // find the "Message-Id" element and
obtain its value (looking for "failed")
+ Pattern p3 = Pattern.compile("^Message-
Id: (.*)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
+ Matcher m3 = p3.matcher(part3Text);
+ String messageId = null;
+ if (m3.find()) {
+ messageId = m3.group(1);
+ }
+
+ // find the matching communication event
+ if (messageId != null) {
+ List<GenericValue> values;
+ try {
+ values =
delegator.findByAnd("CommunicationEvent",
UtilMisc.toMap("messageId", messageId));
+ } catch (GenericEntityException e) {
+ Debug.logError(e, module);
+ return
ServiceUtil.returnError(e.getMessage());
+ }
+ if (values != null &&
values.size() > 0) {
+ // there should be only one;
unique key
+ GenericValue value =
values.get(0);
+
+ // update the communication
event status
+ Map<String,Object> updateCtx =
FastMap.newInstance();
+
updateCtx.put("communicationEventId",
value.getString("communicationEventId"));
+ updateCtx.put("statusId",
"COM_BOUNCED");
+ updateCtx.put("userLogin",
context.get("userLogin"));
+ Map<String,Object> result;
+ try {
+ result =
dispatcher.runSync("updateCommunicationEvent", updateCtx);
+ } catch
(GenericServiceException e) {
+ Debug.logError(e, module);
+ return
ServiceUtil.returnError(e.getMessage());
+ }
+ if
(ServiceUtil.isError(result)) {
+ return
ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
+ }
+ } else {
+ if (Debug.infoOn()) {
+ Debug.logInfo("Unable to
find communication event with the matching messageId : " +
messageId, module);
+ }
+ }
+ } else {
+ Debug.logWarning("No message ID
attached to part", module);
+ }
+ }
+ }
+ }
+ }
+ } catch (MessagingException e) {
+ Debug.logError(e, module);
+ return ServiceUtil.returnError(e.getMessage());
+ } catch (IOException e) {
+ Debug.logError(e, module);
+ return ServiceUtil.returnError(e.getMessage());
+ }
+
+ return ServiceUtil.returnSuccess();
+ }
}