Web services are technology neutral web based components or applications that use XML-based open standards to enable interoperability in integration. Java introduced Java API for XML Web Services (JAX-WS) for creating web services. JAX-WS API is part of the Java EE platform and supports annotations. It simplifies the development of web service providers and web service clients.
Our goal is to locally design, develop and test a web service and finally deploy it to the AWS Elastic Beanstalk. We will develop a simple web service with top-down approach meaning we will design our web service interface first and then implement it using JAX-WS. To generate Java classes from XML schemas and WSDL, we will use Apache CXF framework. We will also follow best practices while designing and developing our web service.
Let’s design generic XML schemas and a simple, generic, WS-I compliant WSDL. A good practice is to design business objects and messages that envelope business object in web service operations, separately and in different namespaces.
First, we create a library project (general project in Eclipse IDE) and design two business schemas and three messages for our operation:
Now, we can design a web service interface (WSDL) with a single “doSomething” operation with an input, output and business fault. Best practice is to use envelope messages for input, output and fault. In our case we use three messages – request, response and fault message defined above.
To ensure true interoperability and be compliant with WS-I we should follow best practices and use document/literal SOAP binding. You can read about WSDL styles here.
Now we can start with top-down development of our web service. To enable this, we must configure our environment. We use:
In Eclipse we generate a new Dynamic Web Project with configured Apache CXF and Tomcat 7.0 runtime (make sure your web service runtime is also set to Tomcat 7.0 and Apache CXF). Note we use jdk 1.6.
We add a new top-down web service, select our WSDL from the library project and let Apache CXF and wsdl2java to generate JAX-WS stubs and JAXB Java classes we can use in the implementation.
If we take a look at the generated classes we can see they are annotated with JAXB and JAX-WS annotations. We can implement our service in the MyServiceImpl.java class. In the interface we can cleary see the JAX-WS annotations.
The service endpoint is defined in the copied WSDL in the WebContent/wsdl foler. In our case the service looks like this:
To test it we deploy it locally on the Tomcat 7.0 server and use SoapUI to test it.
Now we are ready to deploy our web service on the AWS Elastic Beanstalk that automatically handles the deployment, capacity provisioning, load balancing, auto-scaling and application health monitoring. It supports Apache Tomcat 6 and 7, Microsoft IIS 7.5 and 8, PHP 5.3, Phyton, Ruby 1.8.7 and 1.9.3.
To deploy our application on the AWS Elastic Beanstalk from Eclipse we need the AWS Toolkit for Eclipse. When we configure our AWS credentials (access key ID and secret key are accessible in the AWS portal) in the AWS toolkit, we add a new Server > Amazon Web Services > AWS Elastic Beanstalk for Tomcat 7.0. We choose the region (in our case – Ireland) and configure our application and environment.
Next, we can deploy the application with specific key pair, enable SSL, assign CNAME to the server, set the application health check URL and assign the email address for notifications. In our case, we will leave all fields empty. Then we add the project on the server, start it and wait (in our case it took about 8 minutes).
After the deployment we can take a look at our AWS Managemen Conolse > Elastic Beanstalk. Here we can manage our AWS Elastic Beanstalk applications.
Our application is hosted in the AWS S3 bucket in the same region as the AWS Elastic Beanstalk application.
WSDL of our web service is located on:
Finally, we can test the web service, running on AWS Elastic Beanstalk using SoapUI.
You can download the sample here.
HPEL or High Performance Extensible Logging is a new feature of IBM WebSphere Application Server version 8.0. It provides efficient logging and tracing utilities for storing and accessing log, trace, system.err and system.out data. It is an alternative to java.util.logging logger that was used as a logging utility on WAS.
HPEL stores and processes log and trace records in a binary form which is the main reason for its efficiency. As you can see in the figure below (source IBM Publib), primarily HPEL engine forwards streams into two repositories (log and trace). Text format is also supported but should be disabled when performance is a key concern.
If we want to use HPEL we must firstly enable it and secondly configure it.
In this post we continue with BO deserialization of a remote XML file over HTTP. In the previous part (if you haven’t read the first part, I strongly suggest you do so) we have statically set the HTTP endpoint (binding on HTTP Import) to the XML file on the HTTP server (http://localhost:8080/NewCustomer.xml). Since this approach is not useful we will illustrate how to use a mediation component to dynamically set the XML file endpoint. If we briefly take a look at our getCustomer operation we can see it has an input field (string) through which we will set the XML file location (endpoint):
It has a HTTP Header Setter and a Trace mediation primitives. HTTP Header Setter mediation primitive can be used for changing, copying, adding and deleting HTTP headers. In our case we will dynamically override the endpoint with value provided by the input message. We must add a new HTTP Header Element and set it like this:
- Mode: Create
- Header Name: DynamicOverrideURL
- XPath Value (we read a value from input message): body/getCustomer/input
If we take a look at HTTPHeader we can see the DynamicOverrideURL element which contains our endpoint url (http://localhost:8080/NewCustomer.xml) that we propagated through input string.
Our team gained new competences at IBM’s Impact 2011 conference! Matej Hertiš was recognized as IBM Certified Solution Advisor for Cloud Computing and Martin Potočnik was recognized as IBM Certified SOA Associate.
Let’s say you need to convert data from a remote XML file (located on a remote server) into business object. In our scenario we have a Customer business object (schema) and CustomerInterface which are defined like this:
Input parameter will be used in part 2 and will define XML file URL. In this part XML file URL will be statically configured. Output is a Customer business object that we need in our service or process.
So how to deserialize data form a remote XML file into a business object over HTTP?
The most elegant solution is to use HTTP Import component (HTTP binding overview can be found here):
- Make sure remote XML file is accessible and valid.
- Create a HTTP Import Service with an interface (more info).
- In the properties window of HTTP Import component we must define:
- Endpoint URL (XML file URL in our case)
- HTTP version and method
- Default data format handler – we will use UTF8XMLDataHandler (more info). It converts UTF-8 encoded XML data into business object and vice versa.
- In the Method Bindings section you can also set: data serialization data handlers (for input and output), HTTP Header (character set, media type, etc.), HTTP Proxy, Security and Performance (read timeout and number of retries). In our case we will leave the default settings.
When endpoint URL and proper data handlers (UTF8XMLDataHanler in our case) are configured, we can test our component. Content of the input message is irrelevant since endpoint URL is statically configured. Let’s see the result:
We have successfully deserialized a Customer business object from a remote XML file. In part 2, we will include mediation component that will allow us to dynamically set endpoint URL for the XML file.