Title: Simple Use Case - OFBiz sends message to ESME
### Simple Description
John Smith, Sales Chief of ACME, changes the credit level of a customer
"Big Pipe". Once the change has been made in OFBiz, the ECA
associated with this event sends a message to Apache ESME where other sales
staff can see that the status for the customer has changed.
In this initial use case, there is no ESME client embedded in the OfBiz UI
but rather the user UI is that of the Stax environment or other connected
clients.
### Technical Details
#### Overview
*Required Environment*
* Apache ESME Server ([http://esmecloudserverapache.dickhirsch.staxapps.net/](http://esmecloudserverapache.dickhirsch.staxapps.net/)
)
* OFBiz Server ([https://demo.ofbiz.org](https://demo.ofbiz.org)
)
*Required users*
* OFBiz
** John Smith - Sales Chief
* Apache ESME (All members of Apache ESME Pool "BigPipe")
** Ralph Butler - Sales Staff
** Amy Davidson - Sales Staff
** John Smith - Sales Chief
** OFBiz Back-end
#### Technical Details: OFBiz
1. ECA that responds to changes on customer object
1. One generic service "sendEsmeMessage" that sends ESME messages. This
service should be configurable with such things as token (needed to use
Apache ESME's APIs) and server URL. Initially, this could probably use
existing HTTP Services to make a HTTP Post call to the Apache ESME API
method "send_msg" with the extra parameter "token". You could also
hard-code the server name and token for an initial test.
1. One specific service that calls the generic service and formats the
message.
#### Iteration Sugestions
1. *Iteration 1*: SendESMEMessage is called directly from the ECA. Send
Apache ESME service has a hardcoded Stax URL with a hardcoded taken, server
URL and message.
1. *Iteration 2*: A dynamic message that contains event details is sent to
SendESMEMessage
1. *Iteration 3*: A specific service is created that calls with generic
service with a message to send as a parameter
1. *Iteration 4: * The details for the Apache ESME Call (Server URL,
Token, etc) are made configurable via a UI.
## Implementation Details: Facility
*eecas.xml*
*location*:
ofbiz-trunk-current\ofbiz-trunk\applications\product\entitydef\eecas.xml
Added following excerpt
*services_facility.xml*
*location*:
ofbiz-trunk-current\ofbiz-trunk\applications\product\servicedef\services_facility.xml
Added following excerpt:
This is the java code that is necessary to send the message.
*Location*:
ofbiz-trunk-current\ofbiz-trunk\applications\product\src\org\ofbiz\product\test\
ESMEServices.java
To build the new component:
ofbiz-trunk-current\ofbiz-trunk\applications\product> *ant*
package org.ofbiz.product.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.io.*;
import java.net.*;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import javolution.util.FastList;
import javolution.util.FastMap;
import javolution.util.FastSet;
import org.ofbiz.base.util.DateRange;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.TimeDuration;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityConditionList;
import org.ofbiz.entity.condition.EntityExpr;
import org.ofbiz.entity.condition.EntityJoinOperator;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.util.EntityListIterator;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.security.Security;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.service.calendar.TemporalExpression;
import org.ofbiz.service.calendar.TemporalExpressionWorker;
public class ESMEServices {
public static final String module = ESMEServices.class.getName();
public static Map sendMessage(DispatchContext ctx,
Map context) {
String
twitterUrl="http://localhost:8081/twitter/statuses/update.xml";
Map result = FastMap.newInstance();
try {
Delegator delegator = ctx.getDelegator();
GenericValue userLogin = (GenericValue)
context.get("userLogin");
String userLoginId = (String)userLogin.get("userLoginId");
String externalAuthId = (String)userLogin.get("externalAuthId");
String facilityName = (String)context.get("facilityName");
String squareFootage = (String)context.get("squareFootage");
String description = (String)context.get("description");
String user = userLoginId;
String password = externalAuthId;
OutputStreamWriter ostreamwriter;
String statusmsg="A new facility '" + facilityName + "' with " +
squareFootage + "square feet was created." + description;
URL url = new URL(twitterUrl);
HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " +
Base64.encode((user+":"+password).getBytes()));
String encStatus = "status="+URLEncoder.encode(statusmsg,
"UTF-8");
ostreamwriter = new OutputStreamWriter(conn.getOutputStream());
ostreamwriter.write(encStatus); //--> Magic Magic :)
ostreamwriter.flush();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_CREATED || responseCode
== HttpURLConnection.HTTP_OK) {
result = ServiceUtil.returnSuccess();
} else {
result = ServiceUtil.returnFailure();
}
}
catch (Exception e) {
e.printStackTrace();
result = ServiceUtil.returnFailure();
}
return ServiceUtil.returnSuccess();
}
}
## Implementation Details: Example
### services.xml
Location: _servicedef_ directory
Send Message to ESME
### eecas.xml
Location: _entitydef_ directory
### ESMEServices.java
Location: _src_ directory
package org.ofbiz.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.io.*;
import java.net.*;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import javolution.util.FastList;
import javolution.util.FastMap;
import javolution.util.FastSet;
import org.ofbiz.base.util.DateRange;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.TimeDuration;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityConditionList;
import org.ofbiz.entity.condition.EntityExpr;
import org.ofbiz.entity.condition.EntityJoinOperator;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.util.EntityListIterator;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.security.Security;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.service.calendar.TemporalExpression;
import org.ofbiz.service.calendar.TemporalExpressionWorker;
public class ESMEServices {
public static final String module = ESMEServices.class.getName();
public static Map sendMessage(DispatchContext ctx, Map context) {
String
twitterUrl="http://localhost:8081/twitter/statuses/update.xml";
Map result = FastMap.newInstance();
try {
Delegator delegator = ctx.getDelegator();
String exampleId = (String)context.get("exampleId");
String user = "test1";
String password = "5XCQ2CQRYWFZDHYP3Y23HZ3ZOLFBZYGC";
OutputStreamWriter ostreamwriter;
String statusmsg="Test" + exampleId;
int i=2;
URL url = new URL(twitterUrl);
HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " +
Base64.encode((user+":"+password).getBytes()));
String encStatus = "status="+URLEncoder.encode(statusmsg,
"UTF-8");
ostreamwriter = new OutputStreamWriter(conn.getOutputStream());
ostreamwriter.write(encStatus); //--> Magic Magic
ostreamwriter.flush();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_CREATED || responseCode
== HttpURLConnection.HTTP_OK) {
result = ServiceUtil.returnSuccess();
} else {
result = ServiceUtil.returnFailure();
}
}
catch (Exception e) {
result = ServiceUtil.returnFailure();
}
return ServiceUtil.returnSuccess();
}
public static String toString(InputStream inputStream) throws
IOException {
String string;
StringBuilder outputBuilder = new StringBuilder();
if (inputStream != null) {
BufferedReader reader = new BufferedReader(new
InputStreamReader(inputStream));
while (null != (string = reader.readLine())) {
outputBuilder.append(string).append('\n');
}
}
return outputBuilder.toString();
}
}