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
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
 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
 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:optmySimple>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	empmySimpleWEB-INFclasses

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 empwarmySimple.war. This needs to be copied to the webapps directory of your Web Container (for example, D:DevWSDPwebapps).

Figure 4-31. Deploy mySimple Servlets
D:optmySimple>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	empmySimpleWEB-INFclasses

main:

war:
      [[jar]] Building jar: D:opt	empwarmySimple.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


Figure 4-33. Confirming SOAP Message Sent


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

164

Web Services Architecture and Best Practices 164 Figure 4 33 Confirming SOAP Message Sent References Bibliography Sun ONE Architecture and SunTone Architecture Methodology [ch04biblio01div01entry01] Sun ONE Architecture Guide http //wwws sun com/software/sunone/ docs/arch/index html [ch04biblio01div01entry02] Sun ONE Architecture Implementation--Zefer http //dcb sun com/ practices/devnotebook/webserv_refarch jsp [ch04biblio01div01entry03] 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.

165

Web Services Architecture and Best Practices 165 Unified Process/Rational Unified Process [ch04biblio01div02entry01] Enterprise Unified Process http //www enterpriseunifiedprocess info [ch04biblio01div02entry02] Rational Rational Unified Process CD ROM media Version 2001 03 00 Rationale 2001 Web Services Architecture [ch04biblio01div03entry01] Judith M Myerson "Web Services Architectures " Tech 2001 [ch04biblio01div03entry02] Ueli Wahili Mark Tomlinson Olaf Zimmermann Wouter Deruyck and Denise Hendriks "Web Services Wizardry with WebSphere Studio Application Devel oper " IBM Red Books October 2001 Web Services Design Patterns and Best Practices [ch04biblio01div04entry01] Francis Geysermans and Jeff Miller " Implementing Design Patterns with Web Services " IBM developerWorks Live! 2002 Conference [ch04biblio01div04entry02] Tim Hilgenberg and John A Hansen " Building a Highly Robust Secure Web Services Architecture to Process Four Million Transactions per Day " IBM developer Works Live! 2002 Conference [ch04biblio01div04entry03] 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.

166

Web Services Architecture and Best Practices 166 Others [ch04biblio01div05entry01] Alur Deepak John Crupi and Dan Malks Core J2EE Patterns Prentice Hall 2001

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.244.216