4.9 Perspectives

4.9.1 Highlights

  • Web Services products usually come with specific product architecture. For example, the UDDI Service Registry must run on a specific RDBMS vendor product. These Web Services vendors do not usually provide a framework or architecture methodology for defining, customizing, and implementing enterprise architecture solutions using a combination of Web Services products.

  • A structured Web Services architecture framework not only provides a structured methodology to define Web Services components , but also helps select appropriate tools for meeting different Quality of Services ("ilities") during the development and deployment life cycle.

  • Web Services design patterns can be accumulated as you gain experience from deployment. It is useful to maintain a catalog of customized Web Services within the enterprise for future reuse.

4.9.2 Best Practices and Pitfalls

Best Practices

Keep a high-level session variable for each XML-RPC Web Services call to track who is making the call and when. This will help track the security session and Web Services performance monitoring.

Always do stress testing in different time periods before deploying Web Services.

Pitfalls

Use fine-grained Web Services that attempt to expose all APIs as Web Services.

Use the same deployment architecture and support strategy for public and private UDDI registries.

High availability for Web Services is achieved by simply clustering all hardware machines.

Always use one Web Service to embrace multiple back-end sources across different machines (difficult to troubleshoot and isolate the problem sources).

4.9.3 Paper and Pencil

Objective

To use the SOAP local message provider with JAXM to send an XML message.

Exercise

Using the JAXM concept in the chapter Web Services Overview, you are to write a servlet to send an XML message (in fact, this is a Foreign Exchange option message using fpML). The XML message is shown in Figure 4-27 for reference.

Figure 4-27 Foreign Exchange Option Message in XML
 <?xml version="1.0" encoding = "UTF-8" ?> <!DOCTYPE trade   [     <! DTD declarations omitted  -->   ]> <trade>   <tradeHeader>     <partyTradeIdentifier>       <partyReference href="#XYZ"/>     </partyTradeIdentifier>     <partyTradeIdentifier>       <partyReference href="#ABC"/>     </partyTradeIdentifier>     <tradeDate>2002-01-15</tradeDate>    </tradeHeader>    <fxSimpleOption>       <productType>Nondeliverable Option</productType>       <buyerPartyReference href="#XYZ"/>       <sellerPartyReference href="#ABC"/>       <expiryDateTime>          <expiryDate>2002-04-09</expiryDate>          <hourMinuteTime>1000</hourMinuteTime>          <businessCenter>USNY</businessCenter>       </expiryDateTime>       <exerciseStyle>European</exerciseStyle>    </fxSimpleOption>    <party id = "XYZ">       <partyId>CHASUS33</partyId>       <partyName>XYZ BUYER BANK</partyName>    </party>    <party id = "ABCN">       <partyId>ABCANL2A</partyId>       <partyName>ABC Seller Bank</partyName>    </party> </trade> <! end of DTDs --> 

The source files ReceivingServlet.java and SendingServlet. java are located on the accompanying CD-ROM in the Chapter 4 labs subdirectory. They are also presented as follows for reference.

Step 1. Write the SendingServlet.java

The sender client SendingServlet.java creates a connection to the message factory. It uses standard JAXP to construct the SOAP header and body. The SOAP message contains the XML message as shown in Figure 4-28.

Figure 4-28 SendingServlet.java Sends an XML Message in SOAP Messaging With JAXM
[View full width]
 package mySimple.sender; import java.net.*; import java.io.*; import java.util.*; import javax.servlet.http.*; import javax.servlet.*; import javax.xml.soap.*; import javax.activation.*; // import javax.naming.*; import org.apache.commons.logging.*; public class SendingServlet extends HttpServlet {     static Log     logger = LogFactory.getFactory().getInstance("Samples/mySimple");     String to = null;     String data = null;     ServletContext servletContext;     // Connection to send messages.     private SOAPConnection con;     public void init(ServletConfig servletConfig) throws ServletException {         super.init(servletConfig);         servletContext = servletConfig.getServletContext();         try {         SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();             con = scf.createConnection();         } catch(Exception e) {             logger.error("Unable to open a SOAPConnection", e);         }         InputStream in         = servletContext.getResourceAsStream("/WEB-INF/address.properties");         if (in != null) {             Properties props = new Properties();             try {                 props.load(in);                 to = props.getProperty("to");                 data = props.getProperty("data");             } catch (IOException ex) {                 // Ignore             }         }     }     public void doGet(HttpServletRequest req, HttpServletResponse resp)     throws ServletException {         String retval ="<html><H1>FX Option Order Receipt</H1><body><H4>";         try {             // Create a message factory.             MessageFactory mf = MessageFactory.newInstance();             // Create a message from the message factory.             SOAPMessage message = mf.createMessage();             //  SOAP message body             SOAPPart soapPart = message.getSOAPPart();             SOAPEnvelope envelope = soapPart.getEnvelope();             javax.xml.soap.Name name = envelope.createName("trade" , "fx", "http://www.nextfrontiers.com/fxOption/");             SOAPBody body = envelope.getBody();             SOAPBodyElement trade = body.addBodyElement(name);             SOAPHeader header = envelope.getHeader();             SOAPHeaderElement headerElement = header.addHeaderElement(name);             // create tradeHeader             Name childName = envelope.createName("tradeHeader");             SOAPElement tradeHeader = trade.addChildElement(childName);             childName = envelope.createName("partyTradeIdentifier");             SOAPElement partyTradeIdentifier = tradeHeader.addChildElement(childName);             childName = envelope.createName("partyReference");             SOAPElement partyReference = partyTradeIdentifier.addChildElement(childName);             childName = envelope.createName("href");             partyReference.addAttribute(childName, "#XYZ");             Name childName2 = envelope.createName("partyTradeIdentifier");             SOAPElement partyTradeIdentifier2 = tradeHeader.addChildElement(childName2);             childName2 = envelope.createName("partyReference");             SOAPElement partyReference2 = partyTradeIdentifier2.addChildElement(childName2);             childName2 = envelope.createName("href");             partyReference2.addAttribute(childName2, "#ABC");             // create fxSimpleOption             Name childName3 = envelope.createName("fxSimpleOption");             SOAPElement fxSimpleOption = trade.addChildElement(childName3);             childName3 = envelope.createName("productType");             SOAPElement productType = fxSimpleOption.addChildElement(childName3);             productType.addTextNode("Nondeliveable options");             childName3 = envelope.createName("buyerPartyReference");             SOAPElement buyerPartyReference = fxSimpleOption.addChildElement(childName3);             childName3 = envelope.createName("href"); buyerPartyReference.addAttribute(childName3, "#XYZ");             childName3 = envelope.createName("sellerPartyReference");             SOAPElement sellerPartyReference = fxSimpleOption.addChildElement(childName3);             childName3 = envelope.createName("href"); sellerPartyReference.addAttribute(childName3, "#ABC");             childName3 = envelope.createName("expiryDateTime");             SOAPElement expiryDateTime = fxSimpleOption.addChildElement(childName3);             childName3 = envelope.createName("expiryDate");             SOAPElement expiryDate = expiryDateTime.addChildElement(childName3);             expiryDate.addTextNode("2002-04-09");             childName3 = envelope.createName("hourMinuteTime");             SOAPElement hourMinuteTime = expiryDateTime.addChildElement(childName3);             hourMinuteTime.addTextNode("1000");             childName3 = envelope.createName("businessCenter");             SOAPElement businessCenter = expiryDateTime.addChildElement(childName3);             businessCenter.addTextNode("USNY");             childName3 = envelope.createName("exerciseStyle");             SOAPElement exerciseStyle = fxSimpleOption.addChildElement(childName3);             exerciseStyle.addTextNode("European");             // create party information             Name childName4 = envelope.createName("party");             SOAPElement party = trade.addChildElement(childName4);             childName4 = envelope.createName("id");             party.addAttribute(childName4, "XYZ");             childName4 = envelope.createName("partyId");             SOAPElement partyId = party.addChildElement(childName4);             partyId.addTextNode("CHASUS33");             childName4 = envelope.createName("partyName");             SOAPElement partyName = party.addChildElement(childName4);             partyName.addTextNode("XYZ BUYER BANK");             Name childName5 = envelope.createName("party");             SOAPElement party2 = trade.addChildElement(childName5);             childName5 = envelope.createName("id");             party2.addAttribute(childName5, "ABCN");             childName5 = envelope.createName("partyId");             SOAPElement partyId2 = party2.addChildElement(childName5);             partyId2.addTextNode("ABCANL2A");             childName5 = envelope.createName("partyName");             SOAPElement partyName2 = party2.addChildElement(childName5);             partyName2.addTextNode("ABC Seller Bank");             StringBuffer urlSB=new StringBuffer();             urlSB.append(req.getScheme()).append ("://").append(req.getServerName());             urlSB.append(":").append(req.getServerPort()).append(req.getContextPath());             String reqBase=urlSB.toString();             if(data==null) {                 data=reqBase + "/index.html";   // this sets the URL for accessing this graphics/ccc.gif web service             }             // Want to set an attachment from the following url.             //Get context             URL url = new URL(data); // URL to access this web service             AttachmentPart ap = message.create AttachmentPart(new DataHandler(url));             ap.setContentType("text/html");             // Add the attachment part to the message.             // You can attach an EDI (UN/EDIFACT or ANSI X12) message, image or digital graphics/ccc.gif signature             message.addAttachmentPart(ap);             // Create an endpoint for the recipient of the message.             if(to==null) {                 to=reqBase + "/receiver";             }             URL urlEndpoint = new URL(to);             System.err.println("Sending message to URL: "+urlEndpoint);             System.err.println("Sent message is logged in \"sent.msg\"");             retval += " Sent message (check \"sent.msg\") and ";             FileOutputStream sentFile = new FileOutputStream("sent.msg");             message.writeTo(sentFile);             sentFile.close();             // Send the message to the provider using the connection.             SOAPMessage reply = con.call(message, urlEndpoint);             if (reply != null) {                 FileOutputStream replyFile = new FileOutputStream("reply.msg");                 reply.writeTo(replyFile);                 replyFile.close();                 System.err.println("Reply logged in \"reply.msg\"");                 retval += " received reply (check \"reply.msg\"). </H4> </body></html>";             } else {                 System.err.println("No reply");                 retval += " no reply was received. </H4> </html>";             }         } catch(Throwable e) {             e.printStackTrace();             logger.error("Error in constructing or sending message "             +e.getMessage());             retval += " There was an error " +             "in constructing or sending message. </H4> </html>";         }         try {             OutputStream os = resp.getOutputStream();             os.write(retval.getBytes());             os.flush();             os.close();         } catch (IOException e) {             e.printStackTrace();             logger.error("Error in outputting servlet response "             + e.getMessage());         }     } } 
The recipient client ReceivingServlet.java creates a connection to the Message Factory class. The underlying messaging still uses SOAP messaging via JAXM. The source code is shown in Figure 4-29.

Figure 4-29 ReceivingServlet.java Receives an XML Message Using JAXM
 package mySimple.receiver; import javax.xml.soap.*; import javax.xml.messaging.*; import javax.servlet.*; import javax.servlet.http.*; import javax.xml.transform.*; import javax.naming.*; import org.apache.commons.logging.*; public class ReceivingServlet     extends JAXMServlet     implements ReqRespListener {     static MessageFactory fac = null;     static {         try {             fac = MessageFactory.newInstance();         } catch (Exception ex) {             ex.printStackTrace();         }     };     static Log         logger = LogFactory.getFactory().getInstance("Samples/mySimple");     public void init(ServletConfig servletConfig) throws ServletException {         super.init(servletConfig);         // Not much there to do here.     }     // This is the application code for handling the message.. Once the     // message is received the application can retrieve the soap part, the     // attachment part if there are any, or any other information from the     // message.     public SOAPMessage onMessage(SOAPMessage message) {         System.out.println("On message called in receiving servlet");         try {             System.out.println("Here's the message: ");             message.writeTo(System.out);             SOAPMessage msg = fac.createMessage();             SOAPEnvelope env = msg.getSOAPPart().getEnvelope();             env.getBody()                 .addChildElement(env.createName("Response"))                 .addTextNode("This is a response");             return msg;         } catch(Exception e) {             logger.error("Error in processing or replying to a message", e);             return null;         }     } } 
Step 2. Write the build.xml File

An ANT build script ( build.xml ) is created to compile the Java source codes (servlets) and deploy the servlets in war files under the Web Container. It reads in a property file jaxm.properties to set the variables and paths. The build.xml file can be found under /opt/mySimple/build.xml.

Step 3. Compile Source Codes

To compile the source codes (the project name inside the build file is called mySimple), you may execute the following commands at a command prompt (Windows platform) or a Unix terminal (Unix platform). Figure 4-30 shows the script and the result when executed on a Windows machine.

Figure 4-30 Compile mySimple Source Codes
 D:\opt\mySimple>  ant  Buildfile: build.xml set.available: check.jaxm: check.saaj: check.appname: check.servlet: checks: build.dir.webapps: build.dir.local: init:      [[echo]]  Building mySimple to /opt/temp prepare.build: prepare: compile:     [[javac]] Compiling 2 source files to \opt\temp\mySimple\WEB-INF\classes main: BUILD SUCCESSFUL Total time: 11 seconds 
Step 4. Deploy as war Files

To deploy the compiled servlets (the project name inside the build file is called mySimple), you may execute the following commands at a command prompt (Windows platform) or a Unix terminal (Unix platform). Figure 4-31 shows the script and the result when executed on a Windows machine.

The war file created is placed under D:\opt\temp\war\mySimple.war. This needs to be copied to the webapps directory of your Web Container (for example, D:\Dev\WSDP\webapps).

Figure 4-31 Deploy mySimple Servlets
 D:\opt\mySimple>  ant war  Buildfile: build.xml set.available: check.jaxm: check.saaj: check.appname: check.servlet: checks: build.dir.webapps: build.dir.local: init:      [[echo]]  Building mySimple to /opt/temp prepare.build: prepare: compile:     [[javac]] Compiling 2 source files to \opt\temp\mySimple\WEB-INF\classes main: war:       [[jar]] Building jar: D:\opt\temp\war\mySimple.war BUILD SUCCESSFUL Total time: 6 seconds 
Step 5. Test Run

The Tomcat engine needs to be started. On a Windows machine, you may start the Tomcat server by clicking Start Java Web Services Developer Pack 1_0_01 Start Tomcat on the desktop. On Unix, you may start by issuing the command ./startup.sh from your Java Web Services Developer Pack installation location (for example, /opt/jwsdp/bin ).

From a Web browser, issue the URL http://localhost:8080/mySimple/index.html . You should see the screens shown in Figures 4-32 and 4-33.

Figure 4-32. User Interface to Send XML Message Using JAXM

graphics/04fig24.gif

Figure 4-33. Confirming SOAP Message Sent

graphics/04fig25.gif

4.9.4 References

Sun ONE Architecture and SunTone Architecture Methodology

Sun ONE Architecture Guide. http://wwws.sun.com/software/ sunone /docs/arch/index.html

Sun ONE Architecture Implementation ”Zefer. http://dcb.sun.com/practices/devnotebook/webserv_refarch.jsp

SunTone Architecture Methodology. http://www.sun.com/service/sunps/jdc/suntoneam_wp_5.24.pdf

Unified Process/Rational Unified Process

Enterprise Unified Process. http://www.enterpriseunifiedprocess. info .

Rational. Rational Unified Process (CD-ROM media). Version 2001.03.00. Rationale, 2001.

Web Services Architecture

Judith M. Myerson. "Web Services Architectures." Tech, 2001.

Ueli Wahili, Mark Tomlinson, Olaf Zimmermann, Wouter Deruyck, and Denise Hendriks. "Web Services Wizardry with WebSphere Studio Application Developer." IBM Red Books, October 2001.

Web Services Design Patterns and Best Practices

Francis Geysermans and Jeff Miller. " Implementing Design Patterns with Web Services. " IBM developerWorks Live! 2002 Conference.

Tim Hilgenberg and John A. Hansen. " Building a Highly Robust, Secure Web Services Architecture to Process Four Million Transactions per Day. " IBM developerWorks Live! 2002 Conference.

Raghu Varadan. " Patterns for eBusiness ”Design Guidelines for Web Services. " IBM developerWorks Live! 2002 Conference.

Others

Alur Deepak, John Crupi, and Dan Malks. Core J2EE Patterns . Prentice Hall, 2001.



J2EE Platform Web Services
J2EE Platform Web Services
ISBN: 0131014021
EAN: 2147483647
Year: 2002
Pages: 127
Authors: Ray Lai

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net