You are on page 1of 16

EBMX HTTP/S

Client Development Guide

May 20, 2008


Version 2.1
Revision A
Table of contents
INTRODUCTION ...........................................................................................................................................................1
OVERVIEW .................................................................................................................................................................1
EBMX HTTP/S Architecture..................................................................................................................................2
Usage Example ......................................................................................................................................................2
JAVA CLIENT ESSENTIALS..................................................................................................................................3
Establishing URL connections...............................................................................................................................3
Maintaining HTTP sessions...................................................................................................................................3
Making HTTP requests ..........................................................................................................................................4
Making HTTP/S requests.......................................................................................................................................5
Closing the URL Connections ...............................................................................................................................5
EBMX HTTP/S ‘API’................................................................................................................................................6
EBMX_LOGIN_Request (EBMX UserId, EBMX Password).................................................................................6
EBMX_LIST_Request (params).............................................................................................................................7
EBMX_DOWNLOAD_Request(EBMX TrkIds) .....................................................................................................9
EBMX_SUBMIT_Request(ReceiverID, FileType, FileContents).........................................................................11
EBMX_SUBMIT_Request(ReceiverID, FileType, FileContents) with Zip Input File..........................................13
INTRODUCTION
Chrysler’s e-Business Messaging Exchange (EBMX) provides an environment
that allows the passage of business documents between Chrysler and their
trading partners. The types of documents that this environment can support
include EDI and XML, as well as proprietary data formats.

This purpose of this document is to describe the technical details behind


developing a client interface to Chrysler’s EBMX environment using the
proprietary HTTP/S interface.

OVERVIEW
The EBMX HTTP/S interface to the EBMX allows trading partners to securely
deliver/access information to/from the EBMX through a client-side application.
This interface is explored in this document as a potential application
programming interface, called the EBMX HTTP/S API. This API uses the
HTTP/S protocol, over which a supplier can login to the EBMX environment,
and upload/retrieve documents to/from the EBMX. This information is
presented in this manner as it is presumed that accessing the EBMX HTTP/S will
be part of a larger application.

The EBMX HTTP/S API is an example of a “pull” based delivery mechanism,


relative to the supplier, for accessing information. This type of transport
mechanism requires the supplier to poll the EBMX environment for transactions
that are “Mailboxed”. To retrieve these documents, the supplier issues requests
to the EBMX system, EBMX then returns the requested documents. Delivery of
information is a “push” based delivery mechanism, relative to the supplier. This
type of transport mechanism requires the supplier to upload files to the EBMX
environment and to “submit” them – i.e. register them for processing by EBMX.

1
EBMX HTTP/S Architecture

INTERNET
Trading Partners
Reverse Proxy

Firewall

EBMX

In order to access the EBMX, a trading partner is required to have an account on


the EBMX system. Once in the EBMX environment, the trading partner will be
required to execute a supplier specific login to the EBMX environment. After
logging into the EBMX, the user can then issue a number of commands to view a
list of and/or retrieve available documents, as well as upload a document into
the EBMX environment.

Usage Example
This example describes the steps required to upload two files to the EBMX
environment and retrieve any documents currently available for the given
supplier. Note that the EBMX_LOGIN_Request, EBMX_DOWNLOAD_Request,
EBMX_DOWNLOAD_CONFIRMATION_Request, and
EBMX_SUBMIT_Request used in this example are discussed further in the EBMX
HTTP/S ‘API’ section later in this document. They are addressed here to
provide a general description of the functionality required.
1. The client application must provide a valid EBMX userid and password
by executing the EBMX_LOGIN_Request.
2. Next, the client can download documents by executing the
EBMX_DOWNLOAD_Request. Once the download request is complete,
proceed with a confirmation,
EBMX_DOWNLOAD_CONFIMTION_Request, of the documents
actually received.
3. To upload a file, the client side application would use the
EBMX_SUBMIT_Request that will allow the upload and submission of a
single document into the EBMX.

2
4. To upload a Zip file, the client side application would use the
EBMX_SUBMIT_Request that will allow the upload and submission of a
single zipped document into the EBMX.

JAVA CLIENT ESSENTIALS


A Java Servlet running on a web server supports the EBMX HTTP/S API. To
communicate with these Java Servlets, use standard HTTP/S requests. Each
request has a specific meaning and causes a specific action on the server side.
Upon completion of the request, your application will receive a standard
HTTP/S response. This section describes the basic functions your program will
be required to handle in order to communicate with the EBMX environment.
These include establishing a connection, maintaining sessions, making requests
and closing the connection.

Establishing URL connections

Commentary: Since HTTP is a stateless protocol, each call to the EBMX Servlet is
independent. Thus, you will have to create a new URLConnection for each
call/request. Web browsers behave in a similar fashion: they send a request,
obtain a response and that is the end of that particular connection.

Sample Syntax:
// open the connection
url = new URL(pUrlAddress);
urlConn = (HttpsURLConnection)url.openConnection();
// set the connection properties.
urlConn.setDoInput (true);
urlConn.setDoOutput (true);
urlConn.setUseCaches (false);
urlConn.setRequestMethod("POST");
urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

Maintaining HTTP sessions

Commentary: The Web Server maintains a single session across your multiple
requests by embedding the session ID in the HTTP request. If developing your
own interface, make sure that the session ID is in each request. Subsequent
requests use this ID; therefore, if it is not present, future request will fail. Web
browsers maintain sessions by encoding the sessionID in each request “URL” or
with the help of cookies.

3
Sample Syntax:
String sessionCookie;
// If this is not the first call, a session must
// already have been established. Therefore, continue
// in that session.
if (sessionCookie != null) {
urlConn.setRequestProperty("Cookie",sessionCookie);
}
// this is the first attempt, so obtain the
// session cookie for future use.
else {
String setCookie = urlConn.getHeaderField("Set-Cookie");
System.out.println("setCookie is " + setCookie);
StringTokenizer st = new StringTokenizer(setCookie,";");
sessionCookie = st.nextToken();
}

Making HTTP requests

Commentary: Either the GET or the POST action types can be used to make
requests. In the GET option, the URL string has the parameters concatenated to
the end and thus is viewable on interception unless encoded. In addition, a GET
string is limited to 255 characters. In the POST option, the values of parameters
are not viewable and there is no size limitation. Though the server can handle
both types of requests, the POST option type of request is strongly encouraged.

Sample Syntax:

// construct the poststring with the user's entry.


String poststring = URLEncoder.encode("function") + "=" +
URLEncoder.encode("login") + "&" + URLEncoder.encode("username") + "=" +
URLEncoder.encode(username) + "&" + URLEncoder.encode("password") + "=" +
URLEncoder.encode(password);
try {
// open the connection & post request to url then close connection
openURLConn(null);
httpRequestStream = new DataOutputStream(urlConn.getOutputStream());
httpRequestStream.writeBytes(poststring);
httpRequestStream.flush();
httpRequestStream.close();
// write output to STDOUT
httpResponseStream = new BufferedInputStream(urlConn.getInputStream());
int c;
byte[] buffer = new byte[1024];
while ((c = httpResponseStream.read(buffer)) != -1) {
pOutputStream.write(buffer,0,c);
}
httpResponseStream.close();
closeURLConn();
} catch (Exception e) {
e.printStackTrace();
}

4
Making HTTP/S requests

Commentary: HTTP/S requests require that the security properties be on. The
basic concept is that the client code should know that it has to deal with security
aspects such as accepting the server certificate and providing it’s own certificate
if needed. This is the role of the X509 Trust Manager implementation.

Sample Syntax:

// make sure SSL can be handled


System.setProperty("java.protocol.handler.pkgs",
“com.sun.net.ssl.internal.www.protocol");
java.security.Security.addProvider(new
com.sun.net.ssl.internal.ssl.Provider());
// create a SSL factory that will trust all server certificates
try {
javax.net.ssl.SSLSocket sock = null;
X509TrustManager tm = new MyX509TrustManager();
KeyManager[] km = null;
TrustManager[]tma = {tm};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(km,tma,new java.security.SecureRandom());
SSLSocketFactory sf1 = sc.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sf1);
} catch(Exception e) {
e.printStackTrace();
}

Closing the URL Connections

Commentary: Once a response is obtained for a request, the URL Connection


can be closed to free up any resources.

Sample Syntax:

try {
urlConn.disconnect();
System.out.println("connection closed");
} catch (Exception e) {

5
EBMX HTTP/S ‘API’
This section describes each function required to communicate with Chrysler’s
EBMX HTTP/S mailbox. The sections are presented as an ‘API’, with the
presumption that they are part of a larger application. While no API exists in the
traditional sense (i.e. you must create this), these are suggested API interfaces
which are analogs of the required functionality. These correspond to the Usage
Example described earlier in the document. Each section describes the suggested
API name, its arguments, notes, a commentary, the request/response and sample
Java code.

EBMX_LOGIN_Request (EBMX UserId, EBMX Password)

username: The EBMX defined user id for this supplier.


password: The EBMX defined password for this supplier.

NOTE: The login must be the first request performed, prior to any others. In
order to send any of the remaining requests, it is required that a successful
response be returned. A successful response contains the character string
“Success! MemberType is 0”; any other response will invalidate all subsequent
requests.

Commentary: The Java client must construct a POST string based on a valid
EBMX username and password and open a URL Connection for it. If the request
contains a valid username and password, the return will contain a success string;
otherwise, the response will contain a failure string. Note that the “function”
parameter must always have the value “login” when attempting a login request.
After completion of this request, all other API requests will use the username
specified.

Request: The POST string to login to the EBMX is:

String poststring = URLEncoder.encode(“function”) + “=” +


URLEncoder.encode(“login”) + “&” + URLEncode.encode(“username”) + “=” +
URLEncoder.encode(ur_name) + “&” + URLEncoder(“password”) + “=” +
URLEncoder.encode(ur_passwd);

Response:
Success! MemberType is 0
Failure!

6
Sample Syntax:

private void callEbmxLogin() {


try {
String postString = URLEncoder.encode("function") + "=" +
URLEncoder.encode("login") + "&" + URLEncoder.encode("username") + "=" +
URLEncoder.encode(username) + "&" + URLEncoder.encode("password") + "=" +
URLEncoder.encode(password);
// open a connection
openURLConn(null);
// post request to url
postRequest(postString);
// write output to Sdtout
outputResponse(System.out,null);
// close connection
closeURLConn();
} catch (Exception e) {
e.printStackTrace();
}
}

EBMX_LIST_Request (params)

params: selection criteria for documents to display

The params may be a combination of:


newdocsonly(true/false): can be used to narrow search to docs that have never
been downloaded.
doctype: An EBMX supplied filetype.
begindate(MM/dd/yyyy): documents that were created after this date.
enddate(MM/dd/yyyy): documents that were created before this date.

Commentary: This request provides a method of listing information on the


documents that are available for a given supplier. Documents can be listed by
the following criteria: filetype, date range, new documents (i.e. documents that
have not been downloaded), and all documents. NOTE: Document removal is
performed by the system regularly, based on the type and nature of the
document. Therefore, historical information will not be available through this
system.

Request: The POST string required to list documents for a given filetype is:
String postString = URLEncoder.encode("function") + "=" +
URLEncoder.encode("listfiles") + "&" + URLEncoder.encode("doctype") + "=" +
URLEncoder.encode(doctype);

7
Request: The POST string required to list documents for a given date range is:

String postString = URLEncoder.encode("function") + "=" +


URLEncoder.encode("listfiles") + "&" + URLEncoder.encode("begindate") + "=" +
URLEncoder.encode(begindate) + "&" + URLEncoder.encode("enddate") + "=" +
URLEncoder.encode(enddate);

Request: The POST string required to list only new documents of a specific
filetype is:

String postString = URLEncoder.encode("function") + "=" +


URLEncoder.encode("listfiles") + "&" + URLEncoder.encode("newdocsonly") + "=" +
URLEncoder.encode(“true”) + "&" + URLEncoder.encode("doctype") + "=" +
URLEncoder.encode(doctype);

Request: The POST string required to list all documents is:


String postString = URLEncoder.encode("function") + "=" +
URLEncoder.encode("listfiles");

Response: The response will consist of an html page with the following fields
provided: EBMX Tracking Id, Sender ID, ReceiverID, FileType, FileName,
CreationDt, NumOfTimesDownloaded, lastDownloadedDt and fileSize for each
item in the database.

Sample Syntax:

private void callListFiles() {


try {
// prompt for optional parameters
System.out.println("these are optional parameters:");
String newdocsonly = readEntry("newdocsonly(true/false):");
String doctype = readEntry("doctype:");
String begindate = readEntry("begindate(MM/dd/yyyy):");
String enddate = readEntry("enddate(MM/dd/yyyy):");
// construct the poststring with the user's entry.
String postString = URLEncoder.encode("function") + "=” +
URLEncoder.encode("listfiles");
if (newdocsonly != null)
postString = postString + "&" +
URLEncoder.encode("newdocsonly") + "=" + URLEncoder.encode(newdocsonly);
if (doctype != null)
postString = postString + "&" + URLEncoder.encode("doctype") +
"=" + URLEncoder.encode(doctype);
if (begindate != null)
postString = postString + "&" + URLEncoder.encode("begindate")
+ "=" + URLEncoder.encode(begindate);
if (enddate != null)
postString = postString + "&" + URLEncoder.encode("enddate") +
"=" + URLEncoder.encode(enddate);
// open a connection
openURLConn(null);
// post request to url

8
postRequest(postString);
// write output to System.out and also write to a temporary string
StringBuffer dnldList = new StringBuffer();
outputResponse(System.out,dnldList);
closeURLConn();
} catch (Exception e) {
e.printStackTrace();
}
}

EBMX_DOWNLOAD_Request(EBMX TrkIds)

EBMX TrkIds : A comma separated list of tracking ids must be sent to specify
which files/documents should be downloaded.

Commentary: The list of tracking IDs is typically derived from the list returned
from EBMX_LIST_Request above. Only those tracking IDs requested for
download will be downloaded, regardless of any prior calls to
EBMX_LIST_Request. In other words, you must explicitly describe the tracking
IDs to download. The download process builds a zip file with a unique name
that contains the requested documents is returned. A control file with the unique
name zipfilename_control_file.txt is contained in the zip file. This control file
will list out the EBMX Tracking Ids, filenames and filesizes of each of the
documents in the zipped file. If the file ceases to exist on the server because of the
purging process, the control_file will reflect that information (trackingid purged
0). The client application is responsible for verifying that all documents listed in
the control file are valid. Once verifying the download file, the client must send
the EBMX Download Confirmation Request (see below) to confirm the successful
receipt of the documents. If there is no confirmation sent after the download, the
documents are not marked as downloaded. Therefore, the next
EBMX_LIST_Request, with the newdocsonly parameter set to Y, will contain
these documents.

Request: The POST string required to retrieve a selected group of documents is:

String postString = URLEncoder.encode("function") + "=" +


URLEncoder.encode("downloadfiles") + "&" + URLEncoder.encode("filelist") + "="
+ URLEncoder.encode(filelist);

Response: A zipped file of new documents and a control file named


zipfilename_control_file.txt. The format of this file will consist of the following:

TrackingID \t filename \t fileSize\n


where “\t” is a tab character and “\n” is a newline character.

9
Sample Syntax:

private void callFileDownload() {


try {
String filelist = readEntry("You want to download(x,y,z,...):");
// construct the poststring with the user's entry.
String postString = URLEncoder.encode("function") + "=" +
URLEncoder.encode("downloadfiles") + "&" + URLEncoder.encode("filelist") + "="
+ URLEncoder.encode(filelist);
// open a connection.
openURLConn(null);
// post request to url.
postRequest(postString);
// obtain name of the downloaded file, create file on disk
// and write output(download file contents) to that file
String contentDisp = urlConn.getHeaderField("Content-Disposition");
String attachedFileName =
contentDisp.substring(contentDisp.indexOf("=")+1);
FileOutputStream fos = new FileOutputStream(downloadDirPath +
attachedFileName);
outputResponse(fos,null);
} catch (Exception e) {
e.printStackTrace();
}
}

EBMX_DOWNLOAD_CONFIRMATION_Request(EBMX TrkIds)

EBMX TrkIds: A comma seperated list of EBMX Tracking Ids representing the
documents to be confirmed as delivered to the supplier.

Commentary: The client application must verify the receipt of files downloaded
as the result of a EBMX_DOWNLOAD_Request. This is provided to allow the
supplier to keep track of what has/has not been downloaded. It is the
responsibility of the client to ensure all documents requested for downloaded
were correctly downloaded. Each file successfully downloaded should be put
into a comma-separated list of the corresponding EBMX Tracking IDs and sent as
a confirmation request. NOTE: The client is not required to confirm the delivery
of all of the documents retrieved. However, it is highly encouraged that this is
done to keep track of when documents were downloaded and to preserve proper
functioning of newdocsonly selection criteria for the EBMX_LIST_Request. In
otherwords, if documents are never confirmed, they will be repeatedly listed as a
‘new document’.

Request: The POST string for confirm will be

String postString = URLEncoder.encode("function") + "=" +


URLEncoder.encode("confirmdownload") + "&" + URLEncoder.encode("filelist") +
"=" + URLEncoder.encode(filelist);

10
Response:
Success! Download confirmed.
Failure!

Sample Syntax:

private void callConfirmDownload() {


try {
// prompt for a confirmation list of tracking ids.
String filelist = readEntry("You want to confirm(x,y,z,...):");
// construct the poststring with the user's entry.
String postString = URLEncoder.encode("function") + "=" +
URLEncoder.encode("confirmdownload") + "&" + URLEncoder.encode("filelist") +
"=" + URLEncoder.encode(filelist);
// open a connection.
openURLConn(null);
// post request to url
postRequest(postString);
// write output to System.out
outputResponse(System.out,null);
// close the connection
closeURLConn();
System.out.println("called confirmdownload");
}
catch (Exception e) {
e.printStackTrace();
}
}

EBMX_SUBMIT_Request(ReceiverID, FileType, FileContents)

ReceiverId: The EBMX supplied receiver id for the document.


FileType: The EBMX supplied filetype for the document.
FileContents: The contents of the file to be submitted.

Commentary: The EBMX_SUBMIT_Request allows the uploading and


submission of a single file to the EBMX. In order to upload multiple files to the
EBMX, you must make multiple EBMX_SUBMIT_Requests. Due to the possible
time-out of the HTTP request, it is not possible to support a single upload
request that supports the uploading of multiple files into the EBMX.

The file name portion of the file path should contain a valid file name. Valid file
names consist of upper and lower case alphabetic characters, numbers,
underscores, and periods. No embedded spaces are allowed. No special
characters are allowed. File name length should be no more than 100 characters.

Note: The partnership in question should have been configured to make use of
this functionality before this can produce the desired results.

11
Request: This request is executed as an HTTP POST string. However, it is quite
different from the POST strings described above. Read the example below to see
how one is constructed.

Response:
Success! The tracking id is xxxx.
Failure!
[HTTP_ERROR_TYPE BAD REQUEST] Not Multipart request.
[HTTP_ERROR_TYPE BAD REQUEST] Boundary problem.
[HTTP_ERROR_TYPE BAD REQUEST] Max file size allowed is xxxx.

Sample Syntax:

private void callFileSubmit() {


try {
// define a MIME separator that will be used to seperate the three
// parts of the request, namely the "RequestID","FileType"
parameters
// and the file contents.
String sep = "-----------------------------7d0d117230764";
// prompt user for a reciever id, filetype and filepath.
String ReceiverId = readEntry("ReceiverId:");
String FileType = readEntry("FileType:");
String FilePath = readEntry("FilePath:");
// copy the contents of the file to a byte array
// NOTE: int cast assumes no file exceeds ~2GB
File f = new File(FilePath);
int filelength = (int)f.length();
byte[] tempByteArray = new byte[filelength];
FileInputStream fis = new FileInputStream(f);
fis.read(tempByteArray);
fis.close();
// Construct POST header and name/value pairs
// NOTE: receiverId is expected first, filetype seconds and
filecontents last.
String postHeader = "\r\n\r\n--" + sep + "\r\n" +
"Content-Disposition: form-data; name=\"ReceiverId\"\r\n\r\n" +
ReceiverId +
"\r\n--" + sep + "\r\n" +
"Content-Disposition: form-data; name=\"FileType\" \r\n\r\n" +
FileType +
"\r\n--" + sep + "\r\n" +
"Content-Disposition: form-data; name=\"filename\"; filename=\"" +
FilePath
+ "\"\r\n" +
"Content-Type: text/plain\r\n\r\n";
// construct the end of the request
String postEnd = "\r\n--" + sep + "--\r\n\r\n";
// open a connection.
openURLConn(urlAddress + "?function=submitfile");
// set required properties
urlConn.setRequestProperty("Content-Type", "multipart/form-data;
boundary=" + sep);
urlConn.setRequestProperty("Content-Length", ""+
postHeader.length());

12
// post the request to url
// NOTE: assumption is that session has already been started.
httpRequestStream = new
DataOutputStream(urlConn.getOutputStream());
httpRequestStream.writeBytes(postHeader);
httpRequestStream.write(tempByteArray);
httpRequestStream.writeBytes(postEnd);
httpRequestStream.flush();
httpRequestStream.close();
// write output to System.out
outputResponse(System.out,null);
// close the connection
closeURLConn();
System.out.println("called filesubmit");
}
catch (Exception e) {
e.printStackTrace();
}
}

EBMX_SUBMIT_Request(ReceiverID, FileType, FileContents) with


Zip Input File

ReceiverId: The EBMX supplied receiver id for the document.


FileType: The EBMX supplied filetype for the document.
FileContents: The zipped contents of the file to be submitted.

Commentary: Current limitations of the Internet proxy at Chrysler are limiting


the size of the upload file. We have incorporated into the MIME envelope the
ability for the client software to submit a compressed (i.e. zipped) file to the
EBMX Message Switch.

By setting the content type as application/x-zip-compressed it will trigger the


submit process to uncompress the file before handing the file to EBMX. Current
limitations still exist in that the zip file must only contain one (1) file and the file
size cannot be larger that 2.5 meg.

The file name portion of the file path, as well as the file name within the zip file,
should contain a valid file name. Valid file names consist of upper and lower
case alphabetic characters, numbers, underscores, and periods. No embedded
spaces are allowed. No special characters are allowed. File name length should
be no more than 100 characters.

Note: The partnership in question should have been configured to make use of
this functionality before this can produce the desired results.

Request: This request is executed as an HTTP POST string.

13
Response:
Success! The tracking id is xxxx.
Failure!
Zip file contains more than one file.
[HTTP_ERROR_TYPE BAD REQUEST] Not Multipart request.
[HTTP_ERROR_TYPE BAD REQUEST] Boundary problem.
[HTTP_ERROR_TYPE BAD REQUEST] Max file size allowed is xxxx.

Sample Syntax:

private void callFileSubmit() {


try {
// define a MIME separator that will be used to seperate the three
// parts of the request, namely the "RequestID","FileType" parameters
// and the file contents.
String sep = "-----------------------------7d0d117230764";
// prompt user for a reciever id, filetype and filepath.
String ReceiverId = readEntry("ReceiverId:");
String FileType = readEntry("FileType:");
String FilePath = readEntry("FilePath:");
// copy the contents of the file to a byte array
// NOTE: int cast assumes no file exceeds ~2GB
File f = new File(FilePath);
int filelength = (int)f.length();
byte[] tempByteArray = new byte[filelength];
FileInputStream fis = new FileInputStream(f);
fis.read(tempByteArray);
fis.close();
// Construct POST header and name/value pairs
// NOTE: receiverId is expected first, filetype seconds and
filecontents last.
String postHeader = "\r\n\r\n--" + sep + "\r\n" +
"Content-Disposition: form-data; name=\"ReceiverId\"\r\n\r\n" +
ReceiverId +
"\r\n--" + sep + "\r\n" +
"Content-Disposition: form-data; name=\"FileType\" \r\n\r\n" + FileType
+
"\r\n--" + sep + "\r\n" +
"Content-Disposition: form-data; name=\"filename\"; filename=\"" +
FilePath
+ "\"\r\n" +
"Content-Type: application/x-zip-compressed\r\n\r\n";
// construct the end of the request
String postEnd = "\r\n--" + sep + "--\r\n\r\n";
// open a connection.
openURLConn(urlAddress + "?function=submitfile");
// set required properties
urlConn.setRequestProperty("Content-Type", "multipart/form-data;
boundary=" + sep);
urlConn.setRequestProperty("Content-Length", ""+ postHeader.length());
:
:
:
}

14

You might also like