You are on page 1of 59

Advanced Web Service Development in Oracle WebLogic Server

Pyounguk Cho
Principal Product Manager

Mark Prichard
Senior Principal Product Manager

Bethune Qin
Development Manager






Hands-on Lab: WebLogic Web Services

This Hands-On Lab will cover the essentials of developing and deploying web
service applications using Oracle WebLogic Server 10.3.4. In this lab, you will
make use of a preconfigured WebLogic Server domain that includes a single
managed server, which is also the Admin server for the domain. You will learn
How to create web services from Java classes
How to create web services from WSDL
How to create web service clients
How to use MTOM for SOAP attachments
How to add JAX-WS handlers
How to enable web service security
How to enable identity propagation using SAML
How to create database web services
How to create transactional web services
How to create reliable web services

WLS Web Services - Overview
WebLogic Web Services are implemented according to the Web Services for
Java EE 1.2 specification (http://www.jcp.org/en/jsr/detail?id=109), which defines
the standard Java EE runtime architecture for implementing Web Services in
Java. The specification also describes a standard Java EE Web Service
packaging format, deployment model, and runtime services, all of which are
implemented by WebLogic Web Services.

This programming model takes advantage of the new JDK 5.0 metadata
annotations feature (described at
http://java.sun.com/developer/technicalArticles/releases/j2se15/) in which you
create an annotated Java file and then use Ant tasks to compile the file into a
Java class and generate all the associated artifacts. The Java Web Service
(JWS) annotated file is the core of your Web Service. It contains the Java code
that determines how your Web Service behaves. A JWS file is an ordinary Java
class file that uses annotations to specify the shape and characteristics of the
Web Service. The JWS annotations you can use in a JWS file include the
standard ones defined by the Web Services Metadata for the Java Platform
specification (http://www.jcp.org/en/jsr/detail?id=181) as well as a set of other
standard or WebLogic-specific annotations, depending on the type of Web
Service you are creating.

The following Oracle IDE tools are available to build Web services:

Hands-on Lab: Web Services development and
deployment with Oracle WebLogic Server 11g

Oracle JDeveloperOracle's full-featured Java IDE can be used for end-
to-end development of Web services. Developers can build Java classes
or EJBs, expose them as Web Services, automatically deploy them to an
instance of Oracle WebLogic Server, and immediately test the running
Web Service. Alternatively, JDeveloper can be used to drive the creation
of Web Services from WSDL descriptions. JDeveloper also is Ant-aware.
You can use this tool to build and run Ant scripts for assembling the client
and for assembling and deploying the service.
Oracle Enterprise Pack for Eclipse (OEPE)Provides a collection of plug-
ins to the Eclipse IDE platform that facilitate development of WebLogic
Web services. OEPE provides various development features for WebLogic
Web Services including creating web services from Java or from WSDL
and generating client proxy artifacts from WSDL.

Lab #1 Lab Introduction and first Web Service

This section describes the structure of the lab materials. <LabHome> directory
has two subfolders. <LabHome>\resources directory has various files required in
different labs. All the projects are located under <LabWorkspace> directory as
given in the table below. Each lab has two projects, one for exercise and the
other for solution.

Table 1 Lab components
Name Value
MiddlewareHome /labs/wls1034
WebLogicHome <MiddlewareHome>/wlserver_10.3
LabDomain <WebLogicHome>/domains/wlsWebServiceLab
OEPEHome <MiddlewareHome>/oepe_11gR1PS3/eclipse
LabHome /home/oracle/labs/WS_labs
LabWorkspace <LabHome>/WLS_OEPE_WS
Exercise Project HelloWS (to be created as a part of lab exercise)
Solution Project HelloWS_solution
Package Name com.library.ws

Later labs build web services that support book searching, and the parameter
values below are valid.
users :
o billiards
o slick
o tfoolery
o clist
o wtell
o itel

book titles :
o A brief history of time
o A briefer history of time
o The Stand
o Twilight
o Harry Potter and the Chamber of Secrets


Overview Tasks
1
Start Eclipse with OEPE
2
Browse the lab WorkSpace and Projects
3
Start the WLS server in <LabDomain>
4
Create the first JAX-WS web service application
5
Deploy and test the service

Detailed Instructions
Start WebLogic server outside OEPE
1.1 Using the desktop icon, start the WebLogic server in <LabDomain>

1.2 Validate the server comes up without any error messages
1.3 Shutdown the server by entering Ctrl + c

Start Eclipse with OEPE
1.4 Using the desktop icon start Eclipse.

1.5 If prompted to choose a workspace, select <LabWorkspace>.

Create a new Project
1.12 In the Package Explorer or Project Explorer tab, right click and choose New > Project

1.13 In the New Project dialog, select WebLogic Web Services and Web Service Project
and choose Next. WebLogic Web Service Project is nothing but a Dynamic Web Project
with WebLogic Web Service related project facets pre-configured.

1.14 In the New Web Services Project enter the project name, as specified in the table Table
1 . If 11g R1 PS3 entry does not show up in the Target Runtime and Configuration
dropdown list, click New Runtime button.


1.15 In the New Server Runtime Environment dialog select Oracle WebLogic Server
11gR1PS3 and click Next.


1.16 Enter the <WebLogicHome> from Table 1 or using the Browse button browse to
WebLogic Home directory and JDK directory, then click Finish.


1.17 Click Finish to the New Web Service Project.
If presented with the Open Associated Perspective dialog choose Yes.
Note: You could have created a run-time via the project properties.
Start WebLogic server inside OEPE
1.18 In the Server tab, double-click on the instance
1.19 Validate the details in Overview panel. The associated domain name should match
<LabDomain>
1.20 In the Server tab, right click and choose Start.
1.21 In the Console tab, check if there is no error messages. The last line should be :
<Aug 18, 2010 9:25:28 AM PDT> <Notice> <WebLogicServer> <BEA-000360>
<Server started in RUNNING mode>
1.22 In the Server tab, check if the status says :
[Started, Synchronized]
1.23 In the Server tab, right click and choose Stop
Add a Java class
1.24 In Project Explorer, select the newly added project and navigate to the src package.


1.25 Select the src package, right click and choose New > Package.
Enter the package name from Table 1 and click Finish.

1.26 Select the newly added package, right click and choose New > WLS Web Service.
Enter the package name (com.library.ws) and class name (HelloWS) and click Finish.

Modify the generated class
1.27 Modify the generated hello method such that is resembles the one shown below:

public String sayHello(String s) {
String result = hello;
if ( s == null || s.isEmpty()) {
return result + unknown!;
}

return result + + s;
}
1.28 The completed class should resemble:
package com.library.ws;
import javax.jws.*;
@WebService
public class HelloWS {
@WebMethod
public String sayHello( String s) {
String result = hello;
if (s == null || s.isEmpty()) {
return result + unknown;
}
return result + + s;
}
}

If you copy /paste from the PDF file, the quotation may not covert correctly and may need
to be re-typed in order to avoid a build error.
1.29
Use the save ( ) button to save your work.

Test the web service
1.30 In the HelloWS.java editor pane, click anywhere (to select the pane), right click and
choose Run As > Run on Server.

1.31 In the Run on Server dialog select the existing server, if required, and choose Finish.
Note: The application will then be deployed to the running server and the WebLogic Test
Client tab shown.

1.32 Enter some text into the string arg0 dialog and click the sayHello button.
1.33 The tab will show the result of executing the web service.
Note: you may need to scroll the window to see the entire result.

1.34 Select the Server tab, select the server, right click and choose Stop.
1.35 In the Project Explorer tab, select the HelloWS project, right click and choose Close
Project.


Lab #2 Creating JAX-WS Web Service from Java

WebLogic Server, JAX-WS 2.0 and Eclipse with the OEPE plug-in make it extremely
easy to create, deploy and manage web services. During this practice we will create a
simple Web Service, deploy it to an instance of WebLogic Server and test that web
service.
At the end of this practice, you should be able to:
Create an annotation based Web Service
Deploy an application into WebLogic Server from Eclipse
Test the new Web Service within Eclipse

Table 2 Lesson2 Web Service Design Information
Element Value
Exercise Project BottomUP
Solution Project BottomUp_solution
Package Prefix com.library.ws


Overview Tasks
1
Start Eclipse with OEPE
2
Add a java class
3
Modify the generated class
4
Test the web service

Detailed Instructions
Start Eclipse with OEPE
2.1 Using the desktop icon start Eclipse if it is not running yet

2.2 If prompted to choose a workspace, select <LabWorkspace>.
Insure the Use this as the default checkbox is set and click OK.

Open a project, import a java archive
2.3 In the Package Explorer tab, select the BottomUp folder
2.4 Select the project root, navigate to WebContent>WEB-INF>lib.

2.5
2.6
2.7
2.8 Verify that the lib folder has support.jar. If not, we recommend you drag and drop the jar
file into this folder from the file system and do not use the Import command. The
support.jar file is in the <LabHome>/resources directory.
Modify BQResult to add arg-less constructor and missing setter methods
2.9 Navigate to the BQResult.java method and double click to open the class.
2.10 Right before the BQResult( String_) method verify the existence of a constructor which
takes no arguments. The constructor should resemble:

public BQResult() {
init();
}
2.11 Add missing setter methods. Eclipse provides a short cut for adding setter methods on a
java class. Anywhere in the class right click and


2.12 Click the Select Setters button, and then click OK.


Otherwise enter the following setter methods:
public void setBook(Book book) { this.book = book; }
public void setUserName(String userName) {this.userName =
userName; }
public void setUId(int id) { this.uId = id; }
public void setError(String error) { this.error = error;
}
2.13 Save your work.

Web Service Enable the Book Query class
2.14 Navigate to the BookQuery.java
Note: That Eclipse with OEPE does not have a property editor and annotations must be
added and maintained by hand. You can get annotation completion in source by using
the normal control + space method.
2.15 Locate the class definition and decorate the class as a WebService, specifying the
service name and target name space as follows:

@WebService (serviceName ="BookQueryService",
targetNamespace="http://www.library.com/" )

Once you have @WebService annotation for your class, you can use WebLogic Web
Service Annotation panel to set values for any properties. Any changes will be
synchronized with the source code.

2.16 Locate the getBookDetails method.
Decorate the method using the the @WebMethod, ensure you provide the correct
method name.

@WebMethod (operationName = "BookQuery")
2.17 Decorate the method using the WebResult annotation, remember to specify an
appropriate result name. You annotation should resemble:

@WebResult(name = "BookResult")
2.18 Verify that each of the parameters has been decorated with the WebParam annotation.
The annotations will resemble:

public BQResult getBookDetails (
@WebParam(name="UserName")String uName,
@WebParam(name="Title")String title,
@WebParam(name="Isbn")String ISBN)
Test an annotated POJO based web service
2.19 In the Project Explorer pane, select the BookQuery.java file, right click and chose Run
As > Run on Server.
Note: If prompted save all sources.


2.20 In the Run on Server dialog, select the previously added server and click Finish.
If you were successful the WebLogic Test Client will be displayed.
2.21 Enter appropriate values from the design section and test the newly added BookQuery.
Note the name of the parameters, and operation. Do they match what you expected?

2.22 Examine the result, does the query contain the result name you expected?


Lab #3 Creating JAX-WS Web Service from WSDL

The Oracle Enterprise Pack for Eclipse (OEPE) provides a set of functionality for
generating Web Services from existing WSDL, producing skeleton implementations
based on JAX-WS 2.x. In these practices we will explore this functionality and use it to
create web service definitions based on existing WSDL contracts.

In many cases we must extend existing classes to expose their functionality as Web
Services. In such cases OEPE makes excellent use of the JAX-WS 2.x annotations to
expose existing Java functions as web services, yet maintains control over namespaces,
parameters, method and service names.
The aim of this practice set is to make you comfortable creating Web Services from
WSDL based contracts.

In this practice set you will become comfortable:
Creating web services from existing WSDL
Specifying complex Web Service return types
Specifying the characteristics of Web Services via annotations

Table 3 Lesson3 Web Service Design Information
Element Value
Exercise Project TopDown
Solution Project TopDown_solution
Package Prefix com.library.ws



Overview Instructions
1
Start Eclipse with OEPE
2
Generate a web service from WSDL
3
Complete the implementation of a generated web service
4
Test a generated web service

Detailed Instructions
Start Eclipse with OEPE
3.1 Using the desktop icon start Eclipse.

3.2 Select the Server Tab, select the Oracle WebLogic Server instance, right click and
choose Start.
Note: If you have started WLS using the desktop shortcut, you need not start it again.


Open a project, import a java archive
3.3 In the Package Explorer tab, select the TopDown folder.

3.4 Select the project root, navigate to WebContent>WEB-INF>lib.

3.5
3.6
3.7 Verify that the lib folder has support.jar. If not, we recommend you drag and drop the jar
file into this folder from the file system and do not use the Import command. The
support.jar file is in the <LabHome>/resources directory.

Generate a web service from WSDL
3.8 On Project Explorer navigate to BottomUp\WSDL
3.9 Select the libraryCheckoutService.wsdl, right click and choose WebLogic Web
Services > Generate Web Service.
3.10 In the generate menu, specify Java package as defined in the design table, and click
Finish.

Complete the implementation of a generated web service
3.11 If you were successful then a new java baseline implementation will be generated in the
specified package. In addition, a jar file(libraryCheckoutService_wsdl.jar) should be
created under Java Resources>lib>Web App Libraries. This file includes all the JAX-
WS artifacts out of the WSDL file.

3.12 The java class (libraryCheckoutService_libraryCheckoutPortImpl.java)should
open in an editor.
3.13 Navigate to the exists method. Note that is shows a return of 0.
Note: When adding code you can use [ctrl] + shift + O or click the quick fix icon ( ) to
correct or add required imports.
Modify the method to
A. Instantiate a new instance of a QuerySupport object as describe in the design
table section.
B. Use the exists method to determine if the book exists and if so return the books
id.
C. Return -1 on any error.

Your code should look like:
public int exists (String name) {
if ( name == null || name.length() == 0)
return -1;
QuerySupport qs = new QuerySupport();

Book b = qs.exists(name);
if ( b == null)
return -1;

return b.getId();
}
3.14 Navigate to the checkout method, note that it too shows a return code of 0.
Modify the method to
A. Instantiate a new instance of a UserSupport as describe in the design table
section. Use this object to validate the username entered, returning -1 if unknown.
B .Instantiate an instance of ReservationSupport as describe in the design table
section. Use this object to validate the book id entered, returning -2 on error.
C. Return the resulting reservation id.

When complete your code should look like:

public int checkout(int bookId, String username) {
if ( bookId < 1 || username == null || username.length() == 0
) {
return -1;
}

UserSupport us = new UserSupport();
User u = us.find(username);
if ( u == null) {
return -2;
}

ReservationSupport rs = new ReservationSupport();
int rId = rs.reserve(bookId, u.getId());
if (rId < 1)
return -2;

return rId;

}
Test a generated Web Service
3.15 In Project Explorer select the newly generated class libraryCheckoutServer.. in the
com.library.ws package.
3.16 Right click and choose Run As > Run on Server

3.17 In the Run On Server dialog, select Oracle WebLogic Server and click Finish.
The application will be deployed to the server and the WebLogic Test Client will be
displayed.


3.18 In the exists selection, enter a portion of a name from the design section, for example
brief. And press the appropriate button, in this example the exists button.

3.19 Example the result, what id was returned for the book?
Hint: In the design, the books are listed in ID order starting at 1.
3.20 Use the re-invoke button to return to the client operations page. Enter the book id and one
of the provided user names. Exercise the check out operation. What checkout id is
returned for the operation?


Lab #4 Creating a JAX-WS Client from WSDL

Web services are of limited use without client applications. Clients come in a variety of
forms, can be written in a variety of ways, and can be written in a variety of languages.

In these practices we will explore accessing existing web services using tooling to
generate all the client side classes required to connect to and interact with web services.

In this practice set you will become comfortable:
Configuring a command line environment
Generating a set of client end point classes
Using a client class to access a web service



Table 4 Lesson 4Web Service Design Information
Element Value
Exercise Project SynchClient
Solution Project SynchClient_solution
Package Prefix com.library.ws.client, com.library.ws.servlet



Overview Tasks
1
Identify the target WSDL
2
Create a client jar
3
Complete & test a JEE client
4
Complete & test a JSE client

Detailed Instructions
Start WebLogic Server
4.1 If not already running start WebLogic Server using the desktop shortcut
.
Test an annotated POJO based web service
4.2 In the Project Explorer pane, navigate to BottomUp_solution project & select the
BookQuery.java file, right click and chose Run As > Run on Server.




4.3 In the Run on Server dialog, select the previously added server and click Finish.
If you were successful the WebLogic Test Client will be displayed.
4.4 Enter appropriate values from the design section and test the newly added BookQuery.
Note the name of the parameters, and operation. Do they match what you expected?

4.5 Examine the result.


Generate a web service proxy from WSDL
4.6 On Project Explorer navigate to SynchClient project , and go to SynchClient\WSDL
4.7 Select the BookQueryService.wsdl, right click and choose WebLogic Web Services >
Generate Web Service Client.
4.8 Accept the default values, and click Finish.

4.9 Validate BookQueryService.wsdl.jar has been added in Java
Resources\Libraries\Web App Libraries & WebContent\WEB-INF\lib) folder
Complete a JEE client
4.10 Navigate to the main method in src>com.library.ws.servlet>
BookQueryServiceClientServlet.java
Note: this class has been partially completed for you.
4.11 Update the main method to:
a) Inject a BookQueryService instance via @WebServiceRef annotation
b) Use the BookQueryService instance to obtain a BookQuery via the
BookQueryPort.
c) Use the BookQuery instance to make a query for user wtell using title brief.
d) Use the printBookQuery convenience method to print the returned BqResult
object.

The code should look like:
public class BookQueryServiceClientServlet extends HttpServlet
{

private static final long serialVersionUID = 1L;

private static final String CONTENT_TYPE = "text/html;
charset=windows-1252";

@WebServiceRef
private BookQueryService bqs;
/**
* @see HttpServlet#HttpServlet()
*/
public BookQueryServiceClientServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request,
HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub

BookQuery bqp = bqs.getBookQueryPort();

BqResult bqr = bqp.bookQuery("wtell","brief", null);
String responseMsg;

if ( bqr == null ) {
responseMsg = "Got null from bookQuery!";
} else {
responseMsg= printBookQuery(bqr);
}

response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>WS_ClientServlet</title></head>");
out.println("<body>");
out.println("<p>response : " + responseMsg + ".</p>");
out.println("</body></html>");
out.close();

}

..
}

Run the JEE client
4.12 Select the Servlet class in the Project Navigation Panel, right click and choose Run As >
Run On Server.
4.13 Examine the webpage output from the application.

Complete a JSE client
4.14 Navigate to the main method in src>com.library.ws.client>
BookQueryServiceClientClient.java
Note: this class has been partially completed for you.
4.15 Update the main method to:
e) Create a BookQueryService instance
f) Use the BookQueryService instance to obtain a BookQuery via the
BookQueryPort.
g) Use the BookQuery instance to make a query for user wtell using title brief.
h) Use the printBookQuery convenience method to print the returned BqResult
object.

The code should look like:
public class BookQueryServiceClient {
public static void main(String[] args) {

BookQueryService bqs = new
BookQueryService(Thread.currentThread().getContextClassLoader().getRe
source("META-INF/wsdls/BookQueryService.wsdl"), new
QName("http://www.library.com/", "BookQueryService"));

BookQuery bqp = bqs.getBookQueryPort();

BqResult bqr = bqp.bookQuery("wtell","brief", null);
if ( bqr == null ) {
System.out.println("Got null from bookQuery!");
} else {
System.out.println("Got " + printBookQuery(bqr));
}
}

}
Run the JSE client
4.16 Select the main method, right click and choose Run As > Java Application.
4.17 Examine the console tab for the output from the client application. Youll
NoClassDefFoundError.
4.18 Select the main method, right click and choose Run As > Run configurations.
4.19 Select Classpath tab between JRE and Source
4.20 Select WebLogic Systems Libraries under Bootstrap Entries, and click Remove
button (This is required in the current OEPE version when a JSE client is created in a
WLS Web Service project). Then click Apply, and then close the Run Configurations
dialog.
4.21 Select the main method, right click and choose Run As > Java Application.
4.22 Examine the console tab for the output from the client application.
4.23 Close the project.



Lab #5 Adding JAX-WS Handlers

Handlers provide a very useful service, allowing pre and post processing of Web Services
requests without changing the underlying web service itself. Handlers can be written for
services, acting either on the payload of the service, the message and its headers or both.
Additionally handlers can be written for web services clients, providing many of the same
services and benefits.

The aim of this practice set is reinforce the use of writing and configuring handlers.

In this practice set you will:
Write a logical web service handler, which wraps web service methods
invocations
Define a handler chain to include the new handler
Update a web service to specify a handler using the @HandlerChain
annotation


Table 5 Lesson 5Web Service Design Information
Element Value
Exercise Project Handlers
Solution Project Handlers_solution
Package Prefix com.library.ws

Overview Tasks
1 Create a new logical handler which implements
javax.xml.ws.handler.LogicalHandler<LogicalMessageContext>.
2
Complete the handleMessage class
3
Configure the handler chain using an XML file for the web service
4
Modify a web service to specific the handler chain.
5
Test a web service that uses a handler chain.


Detailed Instructions
Create a new logical handler which implements
javax.xml.ws.handler.LogicalHandler<LogicalMessageContext>.
5.1 Using Eclipse open the Handlers project
5.2 In Application Navigator select the com.library.ws package in right click and choose
New > Class.

5.3 Create a new Java class named HWLogicalHandler.
5.4 For ease of development, replace the contents of the newly created class using the
provided code snippet below.

. . .

public class HWLogicalHandler implements
LogicalHandler<LogicalMessageContext> {

public boolean handleMessage(LogicalMessageContext messageContext) {
}

public boolean handleFault(LogicalMessageContext messageContext) {
System.out.println("HWLogicalHandler.handleFault called. with
'"+messageContext+"'.\n");

return true;
}

public void close(MessageContext messageContext) {
System.out.println("HWLogicalHandler.close called. with
'"+messageContext+"'.\n");
}

. . .
}

Make sure to organize imports via control + shift + O, and choose the
ws.handler.MessageContext.
5.5 Click Save icon. You can ignore the build error This method must return a result of type
Boolean.

Complete the handleMessage class
5.6 Modify the handleMessage method to use the provided printTime method to signal the
start of handling a message.

Your code should resemble:
printTime(handleMessage: );
5.7 Add code directly below the printTime call to determine whether the call was inbound or
outbound. Use the messageContext.get() method with a message context of
MESSAGE_OUTBOUND_PROPERTY to determine the direction of the call. Note that this call
returns a Boolean. Print the direction of the call.

Your code should resemble:
Boolean outboundProperty =
(Boolean)messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
System.out.println("\nOutbound message:");

} else {
System.out.println("\nInbound message:");
}
5.8 Add code to print the message payload. Note that the printSource method has been
provided for you, which takes as input instance of a Source object. You can obtain this
object using code similar to:
LogicalMessage lm =messageContext.getMessage();
Source payload = lm.getPayload();

Your code should resemble:
LogicalMessage lm =messageContext.getMessage();
Source payload = lm.getPayload();

printSource(payload);
5.9 The completed code should look like below :

package com.library.ws;


import java.util.Set;
import java.util.Collections;

import javax.xml.namespace.QName;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.LogicalMessage;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class HWLogicalHandler implements
LogicalHandler<LogicalMessageContext> {
public Set<QName> getHeaders() {
System.out.println("HWLogicalHandler.getHeanders called.\n");
return Collections.emptySet();
}

public boolean handleMessage(LogicalMessageContext
messageContext) {
System.out.println("HWLogicalHandler.handleMessage called.
with '"+messageContext+"'.\n");


Boolean outboundProperty =

(Boolean)messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)
;
if (outboundProperty.booleanValue()) {
System.out.println("\nOutbound message:");
} else {
System.out.println("\nInbound message:");

}

LogicalMessage lm =messageContext.getMessage();
Source payload = lm.getPayload();

printSource(payload);

System.out.println("** Response: " +
messageContext.getMessage().toString());
return true;
}

public boolean handleFault(LogicalMessageContext messageContext)
{
System.out.println("HWLogicalHandler.handleFault called. with
'"+messageContext+"'.\n");

return true;
}

public void close(MessageContext messageContext) {
System.out.println("HWLogicalHandler.close called. with
'"+messageContext+"'.\n");
}

private void printSource(Source payload) {
System.out.println("Payload of message = '"+payload+"'");

if (!(payload instanceof DOMSource)) return;
DOMSource ds = (DOMSource)payload;
printNode(0,ds.getNode() );

}
private void printNode(int depth,Node node) {
if ( node == null) return;

for ( int j = 0; j < depth; j++) System.out.print("\t");
System.out.println("" + node);
NodeList children = node.getChildNodes();
if ( children == null ) return;
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
printNode(depth+1,child);
}
}
}

Configure the handler chain using an XML file for the web service
5.10 In the com.library.ws package, create a new XML file named handler-chain.xml by:
a. Selecting the com.library.ws package
b. Right click and choose New > Other
c. from the new Dialog select XML > XML.
d. Complete the wizard to specific the name handler-chain.xml


5.11 Your handle chain should resemble:

<?xml version="1.0" encoding="UTF-8" ?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-class>com.library.ws.HWLogicalHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
Ensure that the class name matches the one you created.
Modify a web service to specific the handler chain
5.12 Open the HelloWS web service.
5.13 Decorate the class with a HandlerChain annotation specifying the handler-chain.xml
file from the prior section.
The annotation should resemble:
@HandlerChain(file="handler-chain.xml")
public class HellowWS
5.14 Optionally decorate the BookQuery web service using the same handler chain.
Test a web service that uses a handler chain.
5.15 In Project Explorer, select the HelloWS web service, right click and choose Run As >
Run on Server.
5.16 In the WebLogic Test client tab. enter your name for the parameter and press sayHello.
5.17 Examine the Console tab.
Does it resemble that shown below.
Inbound message:
Payload of message = 'javax.xml.transform.dom.DOMSource@1e428b2'
[#document: null]
[sayHello: null]
[#text:

]
[arg0: null]
[#text: Oracle]
[#text:
]
** Response: com.sun.xml.ws.handler.LogicalMessageImpl@2bec39
HWLogicalHandler.handleMessage called. with
'com.sun.xml.ws.handler.LogicalMessageContextImpl@1d03ef'.


Outbound message:
Payload of message = 'javax.xml.transform.dom.DOMSource@e37fa6'
[#document: null]
[ns2:sayHelloResponse: null]
[return: null]
[#text: hello Oracle]
** Response: com.sun.xml.ws.handler.LogicalMessageImpl@1d18b8b

5.18 If you decorated the BookQuery service repeat the process using wtell as the user and
brief.
5.19 Examine the Console tab for output.


Lab #6 Handling attachments using MTOM

Transmission of binary data has historically been challenging in SOA, which is XML-
based. MIME(Multipurpose Internet Mail Extension) and DIME (Direct Internet Message
Encapsulation) where often used to overcome this problem. The Message Transmission
Optimization Method, or MTOM and XML-binary Optimized Packaging (XOP) are
available today to support efficient transmission of binary data when using web services

The aim of this practice set is reinforce the use of enabling web services and web service
clients to efficiently transfer binary data using MTOM and XOP.

In this practice set you will:
Enable an existing Web Service to support MTOM
Extend an existing web service java client to use MTOM


Table 6 Lesson6 Web Service Design Information
Element Value
Exercise Project MTOMSrvice, MTOMClient
Solution Project MTOMService_solution, MTOMClient_solution
Package Prefix com.library.ws

Overview Tasks
1
Examine Web Service operations via the Property Inspector
2
Decorate an existing web service for MTOM
3
Update an existing client to use an MTOM enabled web service
4
Test a web service client that uses MTOM.

Detailed Instructions
Examine the MTOM service project
6.1 Using Eclipse open the MTOMService application
6.2 Using the Project Explorer navigate to the com.library.ws.BookQuery.java class.
Decorate an existing web service to support MTOM
6.3 If not already open, open the BookQuery.java class and find the start of the class.
6.4 Add the @MTOM annotation with threshold 128.

Your code should look like:
@MTOM(threshold=128)
Public class BookQuery

Enable MTOM in a JEE client
6.5 In the MTOM Client project, navigate to the main method in
src>com.library.ws.servlet> BookQueryServiceClientServlet.java
Note: this class has been partially completed for you, which means you should ingore
complier errors about requiring a public no-argument constructor,
6.6 Find the line
BookQuery bqp = bqs.getBookQueryPort();
And change it to:
BookQuery bqp = bqs.getBookQueryPort(new MTOMFeature());

Verify that this import statement is present:import
javax.xml.ws.soap.MTOMFeature;

6.7 Directly below
byte[] data = getStoredArtifact("brief.txt");
Add
try {
String storeName = bqp.storeRelatedArtifact(data,
"brief2.txt");
System.out.println("Data stored as:" + storeName);
} catch (Exception e) {
System.out.println("Unexpected exception" +
e.getMessage());
}
6.8 Below the newly added code, retrieve the stored file using code similar to:
String artifact = bqp.returnArtifact("brief2.txt");
System.out.println("artifact:" + artifact);
Run the JEE client
6.9 Select the Servlet class in the Project Navigation Panel, right click and choose Run As >
Run On Server. You may need to deploy the MTOM Solution project if you get a 404
error.
6.10 Examine the console tab for the output from the application.
Enable MTOM in a JSE client
6.11 Navigate to the main method in src>com.library.ws.client>
BookQueryServiceClient.java
Note: this class has been partially completed for you.
6.12 Find the line
BookQuery bqp = bqs.getBookQueryPort();
And change it to:

BookQuery bqp = bqs.getBookQueryPort(new MTOMFeature());

Note you will also need to add the import
import javax.xml.ws.soap.MTOMFeature;

6.13 Directly below
byte[] data = getStoredArtifact("brief.txt");
Add
try {
String storeName = bqp.storeRelatedArtifact(data,
"brief2.txt");
System.out.println("Data stored as:" + storeName);
} catch (Exception e) {
System.out.println("Unexpected exception" +
e.getMessage());
}
6.14 Below the newly added code, retrieve the stored file using code similar to:
String artifact = bqp.returnArtifact("brief2.txt");
System.out.println("artifact:" + artifact);

Then replace references to " D:/docs/webservicePM...
with /home/oracle/labs/WS_Labs/labHome/resources/
in BookQuery.java and BookQueryServiceClient.java

Run the JSE client
6.15 In the servers tab, double click the entry for the WebLogic Server. In the resulting
property sheet, check the option to Ignore compilation errors when deploying and slick
save. Then select the main method, right click and choose Run As > Java Application.
6.16 Examine the console tab for the output from the client application. Youll
NoClassDefFoundError.
6.17 Select the main method, right click and choose Run As > Run configurations.
6.18 Select Classpath tab between JRE and Source
6.19 Select WebLogic Systems Libraries under Bootstrap Entries, and click Remove
button (This is required in the current OEPE version when a JSE client is created in a
WLS Web Service project). Then click apply, and then close the Run Configurations
dialog.
6.20 Select the main method, right click and choose Run As > Java Application.
6.21 Examine the console tab for the output from the client application.
6.22 Close the project. In the servers tab, right click on the server and undeploy all projects
from the server.




Lab #8 Creating RESTful Web Services

While SOAP-based web services are more popular in enterprise applications,
RESTful web services are frequently used for AJAX-based Web 2.0 applications.
REST is in general lighter and faster in terms of performance.

JAX-WS does not support programming models for creating RESTful web
services out of POJO. Instead, youll need to use Provider API.

Alternatively, you can use JAX-RS API for serious RESTful web service
development. Jersey(JAX-RS Reference Implementation)-based REST web
service applications can be deployed to WLS.

In this lab, youll be using JAX-WS API not JAX-RS API.

Table 8 Lesson8 Web Service Design Information
Element Value
Exercise Project REST (to be created)
Solution Project REST_solution
Package Prefix com.ws.rest


Overview Tasks
1
Start a new Eclipse project
2
Create the RESTful JAX-WS web service application
3
Deploy and test the service

Detailed Instructions
Start WebLogic server outside OEPE
8.1 Using the desktop icon, start the WebLogic server in <LabDomain>

8.2 Validate the server comes up without any error messages
8.3 Shutdown the server by entering Ctrl + c

Start Eclipse with OEPE
8.4 Using the desktop icon start Eclipse.

8.5 If prompted to choose a workspace, select <LabWorkspace>.

Create a new Project
8.6 In the Package Explorer tab, right click and choose New > Project


8.7 In the New Project dialog, select WebLogic Web Services and Web Service Project
and choose Next.

8.8 In the New Web Services Project enter the project name as specified in the table 8 and
click New next to the Target Runtime dropdown.

8.9 In the New Server Runtime Environment dialog select Oracle WebLogic Server
11gR1 and click Next.


8.10 Enter the <WebLogicHome> from table 8 or using the Browse button browse to
WebLogic Home directory, then click Finish.

8.11 Click Finish to the New Web Service Project.
If presented with the Open Associated Perspective dialog choose Yes.
Note: You could have created a run-time via the project properties.
Add a Java class
8.12 In Project Explorer, select the newly added project and navigate to the src package.

8.13 Select the src package, right click and choose New > Package.
Enter the package name from Table 1 and click Finish.

8.14 Select the newly added package, right click and choose New > WLS Web Service.
Enter the package name (com.ws.rest) and class name (HelloRest) and click Finish.

Modify the generated class
8.15 Import all the classes and interfaces required:

import java.io.ByteArrayInputStream;
import java.util.StringTokenizer;

import javax.annotation.Resource;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPException;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.BindingType;.
8.16 Decorate the generated class definition with @WebServiceProvider and @Bindingtype
annotations, replacing the default generated @webservice annotation. The class also
needs to implement Provider<Source> interface:


@WebServiceProvider(
targetNamespace="http://example.org",
serviceName = "HelloRestService")
@BindingType(value = HTTPBinding.HTTP_BINDING)
public class HelloRest implements Provider<Source> {
.
8.17 Inject the WebServiceContext object via @Resource annotation :
@Resource(type=Object.class)
protected WebServiceContext wsContext;

8.18 Implement the invoke() method to check the queryString and generate the response
message:
public Source invoke(Source source) {
try {
MessageContext messageContext =
wsContext.getMessageContext();
String query =

(String)messageContext.get(MessageContext.QUERY_STRING);
if (query != null && query.contains("name=")) {
return createSource(query);
} else {

System.err.println("Query String = "+query);
throw new HTTPException(404);
}
} catch(Exception e) {
e.printStackTrace();
throw new HTTPException(500);
}
}
8.19 Add the createSource() helper method that parses and creates xml messages:
private Source createSource(String str) throws Exception {
StringTokenizer st = new StringTokenizer(str, "=&/");
st.nextToken();
String name = st.nextToken();
String body = "<ns:HelloRest
xmlns:ns=\"http://example.org\"><greeting>"
+"hello " + name +"</greeting>"+ "</ns:HelloRest>";
return new StreamSource(new
ByteArrayInputStream(body.getBytes()));
}
8.20 Upon completion, the class should look like :
package com.ws.rest;

import java.io.ByteArrayInputStream;
import java.util.StringTokenizer;

import javax.annotation.Resource;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPException;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.BindingType;

/**
* Example request url:
http://localhost:7001/REST/HelloRestService?name=oracle
*/
@WebServiceProvider(
targetNamespace="http://example.org",
serviceName = "HelloRestService")
@BindingType(value = HTTPBinding.HTTP_BINDING)
public class HelloRest implements Provider<Source> {

@Resource(type=Object.class)
protected WebServiceContext wsContext;

public Source invoke(Source source) {
try {
MessageContext messageContext =
wsContext.getMessageContext();
String query =

(String)messageContext.get(MessageContext.QUERY_STRING);
if (query != null && query.contains("name=")) {
return createSource(query);
} else {

System.err.println("Query String = "+query);
throw new HTTPException(404);
}
} catch(Exception e) {
e.printStackTrace();
throw new HTTPException(500);
}
}
private Source createSource(String str) throws Exception {
StringTokenizer st = new StringTokenizer(str, "=&/");
st.nextToken();
String name = st.nextToken();
String body = "<ns:HelloRest
xmlns:ns=\"http://example.org\"><greeting>"
+"hello " + name +"</greeting>"+ "</ns:HelloRest>";
return new StreamSource(new
ByteArrayInputStream(body.getBytes()));
}
}

8.21
Use the save ( ) button to save your work.


Test the web service
8.22 In the HelloRest.java editor pane, click anywhere (to select the pane), right click and
choose Run As > Run on Server.
8.23 In the Run on Server dialog select the existing server, if required, and choose Finish.


8.24 You will see error messages on the console tab. It has to do wit the UTC(Universal
Testing Client) not supporting RESTful web services, and it can be ignored.
8.25 Open a web browser, and enter the following URL for testing :

http://localhost:7001/REST/HelloRestService?name=oracle

8.26 Validate the response message.
8.27 Optionally, deploy the NearbyCity.java in the solution project (REST_solution) and test it
from the browser:

http://localhost:7001/REST_solution/NearbyCityService?lat=32&long=-122



Lab #9 Transactional JAX-WS Web Services

WebLogic Web services enable interoperability with other external transaction
processing systems through the support of the following specifications:
Web Services Atomic Transaction (WS-AtomicTransaction) Versions 1.0, 1.1,
and 1.2: http://docs.oasis-open.org/ws-tx/wstx-wsat-1.2-spec-cs-
01/wstx-wsat-1.2-spec-cs-01.html
Web Services Coordination (WS-Coordination) Versions 1.0, 1.1, and 1.2:
http://docs.oasis-open.org/ws-tx/wstx-wscoor-1.2-spec-cs-01/wstx-
wscoor-1.2-spec-cs-01.html
These specifications define an extensible framework for coordinating distributed
activities among a set of participants. The coordinator, shown in the following figure, is
the central component, managing the transactional state (coordination context) and
enabling Web services and clients to register as participants.



The following figure shows two instances of WebLogic Server interacting within the
context of a Web services atomic transaction. For simplicity, two WebLogic Web service
applications are shown.



Please note the following:
Using the local JTA transaction manager, a transaction can be imported to or
exported from the local JTA environment as a subordinate transaction, all within
the context of a Web service request.
Creation and management of the coordination context is handled by the local JTA
transaction manager.
All transaction integrity management and recovery processing is done by the local
JTA transaction manager.
To enable Web services atomic transactions on a Web service:
When starting from Java (bottom-up), add the
@weblogic.wsee.wstx.wsat.Transactional annotation to the Web service
endpoint implementation class or method. For more information, see Using the
@Transactional Annotation in Your JWS File.
When starting from WSDL (top-down), use wsdlc to generate a Web service
from an existing WSDL file. In this case, The WS-AtomicTransaction policy
assertions that are advertised in the WSDL are carried forward and are included in

the WSDL file for the new Web service generated by wsdlc. See Enabling Web
Services Atomic Transactions Starting From WSDL.
At deployment time, enable and configure Web services atomic transactions at the
Web service endpoint or method level using the WebLogic Server Administration
Console. For more information, see Configuring Web Services Atomic
Transactions Using the Administration Console.

In this practice set you will:
Create and deploy a transactional JAX-WS application using @Transactional
annotation
Build a client application that executes global transaction processing across local
transaction and a WS-AT enabled web service proxy to invoke a remote
transaction web service


Table 9 Lesson9 Web Service Design Information
Element Value
Exercise Project WSATervice, WSATClient
Solution Project WSATService_solution, WSATClient_solution
Package Prefix examples.webservices.jaxws.wsat.service,
examples.webservices.jaxws.wsat.client


Overview Instructions
1
Update an existing web service to specify transactionality
2
Deploy the application and examine WS-AT policies in the WSDL
3
Enable WS-AT in web service client to invoke transactional service
4
Test the client application

Detailed Instructions
Update an existing web service to specify transactionality
9.1 Using Eclipse open the WSATService project. In the servers tab, right click on the
WebLogic Server and undeploy (remove) all projects from the server.
9.2 Navigate to the examples.webservices.jaxws.wsat.service package and open
the WsatBankTransferService class.
9.3 Under @WebService annotation, decorate the WsatBankTransferService class with
an @Transactional annotation marking the class transactional, The annotation should
resemble:
@Transactional(value=Transactional.TransactionFlowType.MANDATORY,

version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10)


public class WsatBankTransferService {
9.4 Browse the source code to understand the business logic. Essentially, it has several
public methods that interact with database tables. They will be exposed as transactional
web service operations.
9.5 Make sure necessary JDBC connection & DataSources are configured. Go to
Service/Data Source page in the Admin Console (username: weblogic, password:
welcome1)



Deploy the application and examine WS-AT policies in the WSDL
9.6 In Project Explorer select the WsatBankTransferService class, right click and Run As
> Run On Server. Select the default server and click Finish.
9.7 In the WebLogic Test Client tab, check out the error message that web service security-
enabled services cannot be tested.
9.8 Click the WSDL URL link on the WLS_UTC. Youll see the WSAT10 policy assertion and
reference.



Enable WS-AT in web service client to invoke transactional service
9.9 Using Eclipse open the WSATClient project
9.10 Navigate to the examples.webservices.jaxws.wsat.client package and open
the WsatBankTransferServlet class. This is the servlet that performs user
commands from WsatBankTransfer.jsp.
9.11 Edit the class to pass TransactionFeature and AddressingFeature when instantiating
JAX-WS port object. Go to getWebService method, and add the code to enable WS-AT
in the proxy as follows.

// Passing the TransactionalFeature to the Client
private WsatBankTransferService getWebService(URL wsdlURL) {
TransactionalFeature feature = new TransactionalFeature();
feature.setFlowType(TransactionFlowType.MANDATORY);
feature.setVersion(Version.WSAT10);
WsatBankTransferService_Service service =
new WsatBankTransferService_Service(wsdlURL,
new QName("http://tempuri.org/",
"WsatBankTransferService"));
return service.getWSHttpBindingIService(new
javax.xml.ws.soap.AddressingFeature(), feature);
}

If you are copy and pasting code from the PDF, watch out for line breaks getting removed
and causing compile errors.
9.12 Click Save button.
9.13 Navigate to WsatBankTransfer.jsp under WebContent, and right click and Run As >
Run On Server. Select the default server and click Finish. You should see



Test the client application
9.13 Make sure Derby database is up and running. You should have a separate DOS
command window with following message.

2010-08-13 17:46:32.555 GMT : Security manager installed using the Basic server
security policy.
2010-08-13 17:46:36.755 GMT : Apache Derby Network Server - 10.6.1.0 - (938214)
started and ready to accept connections on port 1527
9.14 This client application has one local transaction and a remote transaction, both of which
update Derby database tables. Transaction context gets propagated to the remote web
service via WS-AT. As pictured below, select create account radio button, enter account
Nos and Amount, and click Submit button. Increment the account numbers by 1 from
the screenshot to avoid a unique constraint violation.


9.15 Select list all account balances radio button, and click Submit button to see the new
accounts and balances


9.16 Select transfer money radio button, enter account Nos and Amount, and click Submit
button Make sure to use valid account numbers and amounts.


9.17 Select list all account balances radio button, and click Submit button to see the
updated accounts and balances

9.18 Close the browser




Lab #10 Reliable JAX-WS Web Services
Web service reliable messaging is a framework that enables an application running on
one application server to reliably invoke a Web service running on another application
server, assuming that both servers implement the WS-ReliableMessaging specification.
Reliable is defined as the ability to guarantee message delivery between the two Web
Services in the presence of software component, system, or network failures.


In this practice set you will:
Create and deploy a reliable JAX-WS application using @Policy annotation
Examine WLS SAF(Store & Forward) configuration required to enable message
buffering, which is required for WS-RM runtime
Build a client application that demonstrates asynchronous WS-RM message
exchange via asynchronous handler framework


Table 10 Lesson10 Web Service Design Information
Element Value
Exercise Project WSRMService, WSRMProxyService, WSRMClient
Solution Project WSRMService_solution, WSRMProxyService_solution,
WSRMClient_solution
Package Prefix wsrm_jaxws.example.service, wsrm_jaxws.example.client,
wsrm_jaxws.example


Overview Instructions
1
Update an existing web service to specify reliability
2
Deploy the application and examine WS-RM policies in the WSDL
3
Enable WS-RM in web service client to invoke reliable service
4
Test the client application

Detailed Instructions

Update an existing web service to specify reliability
10.1 Using Eclipse open the WSRMService project
10.2 Navigate to the wsrm_jaxws.example.service package and open the
ReliableEchoServiceImpl class.
10.3 Under @WebService annotation, decorate the ReliableEchoServiceImpl class
with an @Policy annotation specifying that the class will use a standard policy loaded
from the weblogic.jar, The annotation should resemble:

@WebService(portName = "ReliableEchoPort",
serviceName = "ReliableEchoService",
targetNamespace = "http://wsrm_jaxws.example/"
)

@Policy(uri="policy:Reliability1.0_1.1")
public class ReliableEchoServiceImpl {

10.4 Browse the source code to understand the business logic. Essentially, it has several
public methods that echo input parameters. They will be exposed as reliable web service
operations.
10.5 Make sure necessary SAF & JMS connection are configured. Go to
Services/Messaging/{JMS Servers, Store-and-Forward Agents, JMS modules}
pages in the Admin Console. They are configured automatically when the domain is
expanded with
\wlserver_10.3\common\templates\applications\ wls_webservice_jaxws.jar domain
template.








Deploy the application and examine WS-RM policies in the WSDL
10.6 In Project Explorer select the ReliableEchoServiceImpl class, right click and Run
As > Run On Server. Select the default server and click Finish.
10.7 In the WebLogic Test Client tab, check out the error message that web service reliable
messaging-enabled services cannot be tested.
10.8 Click the WSDL URL link on the WLS_UTC. Youll see the Reliability1.0_1.1 policy
assertion and reference.


Enable WS-RM in web service client to invoke reliable service
10.9 Open the WSRMProxyService project
10.10 Navigate to the wsrm_jaxws.example package and open the ClientServiceImpl
class. This is the JAX-WS web service, which has a proxy client to invoke the service
created above. Reliable proxy is supported only on WebLogic, and thats why we have a
proxy service.
10.11 Edit the class to pass features related to WS-RM when instantiating JAX-WS port object.

Go to initFeatures() method, and add the code to enable WS-RM in the proxy so it looks
like the completed class below. Please, note that the proxy is getting injected via
@WebServiceRef annotation.

@PostConstruct
public void initFeatures() {

String clientId =
"WsrmJaxws_example_Service_Client_AsyncBuffered";

WsrmClientInitFeature rmInitFeature = new
WsrmClientInitFeature(true);
rmInitFeature.setNonBufferedSource(false);
rmInitFeature.setNonBufferedDestination(false);
features.add(rmInitFeature);

Container c =
ContainerResolver.getInstance().getContainer();
ServletContext servletContext =
c.getSPI(ServletContext.class);
AsyncClientTransportFeature asyncFeature =
new AsyncClientTransportFeature(servletContext);
features.add(asyncFeature);

ReliableEchoServiceImplAsyncHandler asyncHandler =new
MyAsyncHandler();
AsyncClientHandlerFeature achf = new
AsyncClientHandlerFeature(asyncHandler);
features.add(achf);


ClientIdentityFeature clientIdFeature = new
ClientIdentityFeature(clientId);
features.add(clientIdFeature);

mPort =
service.getReliableEchoPort((WebServiceFeature[])features.toArray(new
WebServiceFeature[features.size()]));
}
10.12 Click Save button.
10.13 Browse the code to understand how to define and register asynchronous handlers.

private class MyAsyncHandler
implements ReliableEchoServiceImplAsyncHandler {

public void onEchoResponse(Response<EchoResponse>
echoResponseResponse) {


System.out.println("testing...................\n\n\n\n");

// Find our saved/persistent request ID in the
persistent context.
Map<String, Serializable> persistentContext =

(Map<String, Serializable>)echoResponseResponse.

getContext().get(JAXWSProperties.PERSISTENT_CONTEXT);

String requestId =
(String)persistentContext.get("RequestID");

if (requestId == null) {
say("NO RequestID property on
persistentContext for response!!!!");
try {
String response =
echoResponseResponse.get().getReturn();
say("Got uncorrelatable response: " +
response);
} catch (Throwable t) {
say("Got uncorrelatable error: "
+ t.toString());
t.printStackTrace();
}
10.14 Navigate to ClientServiceImpl class, and right click and Run As > Run On
Server. Select the default server and click Finish.

Test the client application
10.15 Open the WSRMClient project
10.16 Navigate to the wsrm_jaxws.example.client package and open the
WsrmJaxwsExampleRequest class. This is a Java SE client, which has a proxy client to
invoke the proxy service created above, which will in turn invoke the target reliable
service. service.
10.17 Right click and Run As > Java Application. You should see response messages as
follows.





10.18 Close the projects
Lab #11 Enabling Identity Propagation with JAX-WS Web Services
Message-level security specifies whether the SOAP messages between a client
application and the Web service invoked by the client should be digitally signed or
encrypted, or both. It also can specify a shared security context between the Web service
and client in the event that they exchange multiple SOAP messages. You can use
message-level security to assure:
Confidentiality, by encrypting message parts
Integrity, by digital signatures
Authentication, by requiring username, X.509, or SAML tokens
The SAML Token Profile 1.1 (http://docs.oasis-open.org/wss/v1.1/wss-v1.1-
spec-os-SAMLTokenProfile.pdf) is part of the core set of WS-Security standards, and
specifies how SAML assertions can be used for Web services security. WebLogic Server
supports SAML Token Profile 1.1, including support for SAML 2.0 and SAML 1.1
assertions. SAML Token Profile 1.1 is backwards compatible with SAML Token Profile
1.0.
Use of SAML tokens works server-to-server. This means that the client application is
running inside of a WebLogic Server instance and then invokes a Web service running in
another WebLogic Server instance using SAML for identity. Because the client
application is itself a Web service, the Web services security runtime takes care of all the
SAML processing. In addition to this server-to-server usage, you can also use SAML
tokens from a standalone client via WS-Trust.
In this practice set you will:
Create and deploy a JAX-WS application using SAML policy for @Policy
annotation
Examine WLS web service security configuration required to enable
authentication, message encryption and signing, which is required for SAML
runtime
Build a client application that demonstrates identity propagation via SAML
Sender Vouches confirmation method (The identity of authenticated user via
username token will be propagated to the target service in the form of SAML
token)

Table 11 Lesson11 Web Service Design Information
Element Value
Exercise Project SAML20SVPartnerService, SAML20SVProxyService,
SAML20SVClient
Solution Project SAML20SVPartnerService_solution,
SAML20SVProxyService_solution, SAML20SVClient_solution
Package Prefix examples.webservices.saml.saml20sv



Overview Instructions
1
Update an existing web service to specify SAML Sender Vouches policy
2
Deploy the application and examine SAML Sender Vouches policies in the WSDL
3
Enable SAML Sender Vouches in web service client to invoke target service
4
Test the client application

Detailed Instructions
Update an existing web service to specify SAML Sender Vouches policy
11.1 Using Eclipse open the SAML20SVPartnerService project
11.2 Navigate to the examples.webservices.saml.saml20sv package and open the
PartnerService class.
11.3 Above the @WebService annotation, decorate the PartnerService class with a
@Policies and @Policy annotation specifying that the class will use standard policies
loaded from the weblogic.jar. Here three policies are used for SAML token
authentication, message integrity(via digital signature), and message protection(via
encryption). The annotation should resemble:

@Policies(
{
@Policy(uri = "policy:Wssp1.2-2007-Saml2.0-SenderVouches-
Wss1.1.xml"),
@Policy(uri = "policy:Wssp1.2-2007-SignBody.xml"),
@Policy(uri = "policy:Wssp1.2-2007-EncryptBody.xml")
}
)
@WebService(serviceName = "PartnerService", name = "IPartner",
targetNamespace = "http://www.oracle.com/2008/12/interop")
public class PartnerService{
11.4 Browse the source code to understand the business logic. Essentially, it has a public
method that echoes input parameters. It will be exposed as reliable web service
operations. Additionally, checkSamlAttributesFromRequestMessage() method illustrates
how to introspect custom SAML attributes set by the sender in the SAML token.
11.5 Make sure necessary web service security and SAML parameters are configured. Go to
wlsWebServiceLab/Web Service Security pages in the Admin Console for domain-
level web service security configuration. Go to Security realm/myrealm/Credential
Mappings/PKI pages for users for credential mapping. Check out Security
realm/myrealm/Providers/Authentication pages for credential mapping configuration.
Go to Security realm/myrealm/Providers/Credential Mapping pages in the Admin
Console for credential mapper configuration. All of these have been pre-configured
through WLST scripts.










Deploy the application and examine SAML Sender Vouches policies in the WSDL
11.6 In Project Explorer select the PartnerService class, right click and Run As > Run
On Server. Select the default server and click Finish.
11.7 In the WebLogic Test Client tab, input a string and click Echo, and then check out the
error message that web service security-enabled services cannot be tested.
11.8 Click the WSDL URL link on the WLS_UTC. Youll see the security policy assertions and
reference.



Enable SAML Sender Vouches in web service client to invoke target service
11.9 Open the SAML20SVProxyService project
11.10 Navigate to the examples.webservices.saml.saml20sv package and open the
ProxyService class. This is the JAX-WS web service, which has a proxy client to
invoke the service created above. SAML proxy (without using WS-Trust) is supported
only on WebLogic, and thats why we have a proxy service.
11.11 Above the @WebService annotation, decorate the ProxyService class with a

@Policies and @Policy annotation specifying that the class will use standard policies
loaded from the weblogic.jar. Here three policies are used for username token
authentication, message integrity(via digital signature), and message protection(via
encryption). The annotation should resemble:

@Policies(
{
@Policy(uri = "policy:Wssp1.2-2007-Wss1.1-UsernameToken-Plain-
EncryptedKey-Basic128.xml"),
@Policy(uri = "policy:Wssp1.2-2007-SignBody.xml"),
@Policy(uri = "policy:Wssp1.2-2007-EncryptBody.xml")
}
)

@WebService(serviceName = "ProxyService", name = "IProxy",
targetNamespace = "http://www.oracle.com/2008/12/interop")
public class ProxyService{
11.12 Click Save button.
11.13 Browse the code to understand how to set the credential providers in the JAX-WS
BindingProvider context.

try{
PartnerService service =
new PartnerService(new URL(partenerWsdlURL),
new
QName("http://www.oracle.com/2008/12/interop", "PartnerService"));

IPartner port = service.getIPartnerPort();
BindingProvider provider = (BindingProvider) port;
Map context = provider.getRequestContext();
context.put(WLStub.SAML_ATTRIBUTE_ONLY, "True");
context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:7001/partnerservice/partnerservice");

List credProviders = buildCredentialProviderList();
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST,
credProviders);

String result = port.echo(hello);
return result+" I'm ProxyService Echo!\n";

} catch(Exception ex ){
throw new RuntimeException(ex);
}
11.14 Examine the code to understand how to set custom SAML attributes.

private static class MySAMLCredentialProvider1 extends
SAML2CredentialProvider {

public SAMLAttributeStatementData
getSAMLAttributeData(Subject subject) {


System.out.println(" Providing SAML Attributes from
MySAMLCredentialProvider1 for Subject =" + subject);
// There are four types of attributes in this test

SAMLAttributeStatementData attributes = new
SAMLAttributeStatementDataImpl();

String xmlns = "www.oracle.com/webservices/saml/test";
// 1. The attribute without value

SAMLAttributeData attribute1 = new
SAMLAttributeDataImpl();
attribute1.setAttributeName("test.no.value.attribute");
// Friendly name is optional. It is set in this example.
attribute1.setAttributeFriendlyName("Type 1 - No Value");
attribute1.setAttributeNameSpace(xmlns);
attributes.addAttributeInfo(attribute1);

// 2. Static attribute that has static value

SAMLAttributeData attribute2 = new
SAMLAttributeDataImpl();
attribute2.setAttributeName("test.static.attribute");
attribute2.setAttributeFriendlyName("Type 2 - Static
Attribute");
attribute2.setAttributeNameSpace(xmlns);
attribute2.addAttributeValue("static.attribute.value");
attributes.addAttributeInfo(attribute2);
11.15 Navigate to ProxyService class, and right click and Run As > Run On Server.
Select the default server and click Finish.

Test the client application
11.16 Open the SAML20SVClient project
11.17 Navigate to the examples.webservices.saml.saml20sv package and open the
EchoClientServlet class. This is a simple servlet, which has a proxy client to invoke
the proxy service created above, which will in turn invoke the target partner service.
11.18 Browse the code to understand how to set BST and UNT credential providers in order to
comply with security policies of the proxy service.

private static CredentialProvider getClientBSTCredentialProvider()
throws Exception {


InputStream clientKeyInputStream =
EchoClientServlet.class.getResourceAsStream("/Alice.prv");

InputStream clientCertInputStream =
EchoClientServlet.class.getResourceAsStream("/Alice.cer");
InputStream serverCertInputStream =
EchoClientServlet.class.getResourceAsStream("/Bob.cer");


X509Certificate clientCert =
CertUtils.getCertificate(clientCertInputStream);
PrivateKey clientPrivateKey =
CertUtils.getPKCS8PrivateKey(clientKeyInputStream);
X509Certificate serverCert =
CertUtils.getCertificate(serverCertInputStream);



return new
ClientBSTCredentialProvider(clientCert, clientPrivateKey,
serverCert);
}

private static CredentialProvider
getClientUNTCredentialProvider() throws Exception {

String username = "Alice";

String password = "ecilA1a!";
return new ClientUNTCredentialProvider(username.getBytes(),
password.getBytes());
}
11.19 Right click and Run As > Run On Server. Select the default server and click Finish.
You should see the message on the embedded browser.
.


You can take a look at the command window that is running WebLogic Server, which
shows the message traces as follows.

<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <[SignatureValidationResult
:
[status: true]
[signature: 5rCpLSOmi/Dp/WhoDZF2WV3CZOg=]
[keySelectorResult: [KeySelectorResultImpl:
[Key: javax.crypto.spec.SecretKeySpec@15c94]
[Message: null]
[SecurityToken: weblogic.xml.crypto.wss11.internal.enckey.EncryptedKeyToken@1430
2aa]]]
[refValidationResults:
[ReferenceImpl.ValidateResultImpl:
[refURI: #Timestamp_eX9z7AamQMFJQQLS]
[status: true]
[digestValue: 0E30E22A2CBAB6E27F4046458E1F10EE86BAF48E]
[unmarshalledDigestValue: 0E30E22A2CBAB6E27F4046458E1F10EE86BAF48E]]
[ReferenceImpl.ValidateResultImpl:
[refURI: #Body_mIVU7ho7V5VVzQry]

[status: true]
[digestValue: 0141CF80B6822BA3B0CEBE4596EEC426122AF9DE]
[unmarshalledDigestValue: 0141CF80B6822BA3B0CEBE4596EEC426122AF9DE]]
[ReferenceImpl.ValidateResultImpl:
[refURI: #sigconf_SkB4gPhv1aiUDzZ5]
[status: true]
[digestValue: F453FFD632F21EC6013D1D3E58109946DF1CBEAB]
[unmarshalledDigestValue: F453FFD632F21EC6013D1D3E58109946DF1CBEAB]]]]>
<WSEE:15>WSEE[MONITORING[Invocation[DispatchTime=619316840][ExecutionTime
=0][Res
ponseTime=619316841]]]<WseeBaseOperationRuntimeData.reportInvocation:185>
<WSEE:15>set Message called: com.sun.xml.internal.messaging.saaj.soap.ver1_1.Mes
sage1_1Impl@1f7571<SoapMessageContext.setMessage:65>
<WSEE:15>Parsed header {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
wssecurity-secext-1.0.xsd}Security: <name={http://docs.oasis-open.org/wss/2004/0
1/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security> <role=null> <mustUndersta
nd=true><SoapMsgHeaders.parseHeaders:202>
<WSEE:15>isCompatMSFT set to false<SecurityPolicyBlueprintPlotter.drawPolicyComp
atibilityPreference:110>
<WSEE:15>policyNamespaceUri is http://docs.oasis-open.org/ws-sx/ws-securitypolic
y/200702<SecurityPolicyBlueprintPlotter.drawPolicyCompatibilityPreference:111>
<WSEE:15>Inspecting message age ...<SecurityMessageInspector.checkMessage:168>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <*************TIMESTAMP
VAL
IDATION: >
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <created = Mon Aug 16
17:24
:02 PDT 2010>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <now = Mon Aug 16
17:24:02
PDT 2010>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <expiry = Mon Aug 16
17:25:
02 PDT 2010>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <longCreated =
128200464200
0>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <longNow =
1282004642920>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <clockSkew used = 60000>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <clockSkew = 60000>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <clockPrecision = 60000>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <useClockSkew = true>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <clockSynchronized = true>

<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <maxProcessingDelay = -1>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <TIMESTAMP

VALIDATION: >
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <created = Mon Aug 16
17:24
:02 PDT 2010>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <now = Mon Aug 16
17:24:02
PDT 2010>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <expiry = Mon Aug 16
17:25:
02 PDT 2010>
<Aug 16, 2010 5:24:02 PM PDT> <Info> <> <BEA-000000> <clockSkew used = 60000>
<WSEE:15> timestamp(maxAgesSecs=60)
verified<SecurityMessageInspector.doMessageAge:756>
<WSEE:15>Inspecting message authentication identity ...<SecurityMessageInspector
.checkMessage:176>
<WSEE:15>Identity is not required.<SecurityMessageInspector.inspectIdentity:804>
<WSEE:15>Inspecting signature confirmation ...<SecurityMessageInspector.checkMes
sage:187>
<WSEE:15>Inspecting signature and encryption ..., request =false<SecurityMessage

11.20 Close the projects

You might also like