1 web service implementation, deploy and test...
TRANSCRIPT
1
Web Service Implementation, Deploy and Test
课程名:以服务为中心的软件开发设计与实现
2
Outline
• Web service implementation and deploy– REST– JAX-WS– XFire
• Web service test– Junit
• Web service invoke– Ajax
3
Xfire – A Java SOAP framework for development and consumption
of web services
4
Writing A Web Service with Xfire - Interface
package edu.thu.keg.core.webservice;
public interface ArnetminerSearchWebService {
/**
* search for person list
* @param keyword - E.g: Jiawei Han pos:professor aff:Illinois edu:ph.D all:computer
* @param start_page - the start page number you want to return
* @param num - the number of persons you want to return for each page
* @return
*/
public PersonSearchResult person_search(String keyword, int start_page,int num);
public PersonSearchResult person_search(String keyword);
…
}
XFire
Step1: Interface
5
Writing A Web Service with Xfire - Implementation
public class ArnetminerSearchWebServiceImpl implements ArnetminerSearchWebService {
public PersonSearchResult person_search(String keyword, int start_page,int num){
if(keyword == null || keyword.length() == 0) {
return null;
}
QueryContactInfoService service = new QueryContactInfoService();
SearchResult<ContactInformation> results = service.queryContactInfo(keyword, start_page, num);
return SearchResultConvertor.SearchResultToPersonSearchResult(results);
}
public PersonSearchResult person_search(String keyword){
if(keyword == null || keyword.length() == 0) {
return null;
}
int start_page = 0;
int num = 10;
return person_search(keyword, start_page, num);
}
…
}
XFire
Step2: Implementation
6
Writing A Web Service with Xfire - Configuration<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xfire.codehaus.org/schemas/1.0/mapping.xsd">
<mapping>
<method name="test">
<parameter index="0" mappedName="userId"/>
<return-type mappedName="Long" />
</method>
<method name="person_search">
<parameter index="0" mappedName="keyword"/>
<return-type mappedName="PersonList"
componentType="edu.thu.keg.core.model.indexer.PersonSearchResult"/>
</method>
</mapping>
</mappings>
XFire
Step3: Configuration
7
Writing A Web Service with Xfire - Configuration
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>ArnetminerSearchWebService</name>
<namespace>http://www.arnetminer.org/ArnetminerSearchWebService</namespace>
<serviceClass>edu.thu.keg.core.webservice.ArnetminerSearchWebService</serviceClass>
<implementationClass>edu.thu.keg.core.webservice.ArnetminerSearchWebServiceImpl</implementationClass>
</service>
</beans>
XFire
Step4: Release
8
Writing A Web Service with Xfire - Client in Java
public class ArnetminerSearchWebServiceClient {
public static void main(String args[]) throws Exception {
String url = "http://localhost:8080/Arnetminer/services/ArnetminerSearchWebService";
Service serviceModel = new ObjectServiceFactory().create(ArnetminerSearchWebService.class);
ArnetminerSearchWebService service = (ArnetminerSearchWebService)new XFireProxyFactory().
create(serviceModel, url);
assert(service != null);
/* System.out.println(id);*/
System.out.println("1. test person search...");
System.out.println("\t querying jie tang...");
PersonSearchResult results1 = service.person_search("jie tang");
System.out.println("Got " + results1.getResultCount() + " results!");
System.out.println("1. test person search...");
System.out.println("\t querying jie tang...");
PersonSearchResult results1_1 = service.person_search("jie tang",1,5);
System.out.println("Got " + results1_1.getResultCount() + " results!");
}
} Step5: Test
9
Unit Testing Framework for the Java Programming Language - JUnit
10
Test suites• Obviously you have to test your code to get it working in the
first place– You can do ad hoc testing (running whatever tests occur to you at the
moment), or– You can build a test suite (a thorough set of tests that can be run at any
time)• Disadvantages of a test suite
– It’s a lot of extra programming• This is true, but use of a good test framework can help quite a bit
– You don’t have time to do all that extra work• False—Experiments repeatedly show that test suites reduce debugging time
more than the amount spent building the test suite
• Advantages of a test suite– Reduces total number of bugs in delivered code– Makes code much more maintainable and refactorable
• This is a huge win for programs that get actual use!
11
JUnit
• JUnit is a framework for writing tests– JUnit was written by Erich Gamma (of Design Patterns fame) and Kent
Beck (creator of XP methodology)– JUnit uses Java’s reflection capabilities (Java programs can examine
their own code)– JUnit helps the programmer:
• define and execute tests and test suites• formalize requirements and clarify architecture• write and debug code• integrate code and always be ready to release a working version
– JUnit is not yet (as far as I know) included in Sun’s SDK, but an increasing number of IDEs include it
– BlueJ, JBuilder, and Eclipse now provide JUnit tools
12
Structure of a JUnit test class
• Here’s what you do to test a class named Fraction:• public class FractionTest
extends junit.framework.TestCase {– This is the unit test for the Fraction class; it declares (and possibly
defines) values used by one or more tests• public FractionTest() { }
– This is the default constructor• protected void setUp()
– Creates a test fixture by creating and initializing objects and values• protected void tearDown()
– Releases any system resources used by the test fixture• public void testAdd(), public void testToString(), etc.
– These methods contain tests for the Fraction methods add(), toString(), etc. (note how capitalization changes)
13
Assert methods I• Within a test,
– Call the method being tested and get the actual result– assert what the correct result should be with one of the provided assert
methods– These steps can be repeated as many times as necessary
• An assert method is a JUnit method that performs a test, and throws an AssertionFailedError if the test fails– JUnit catches these Errors and shows you the result
• static void assertTrue(boolean test)static void assertTrue(String message, boolean test)– Throws an AssertionFailedError if the test fails– The optional message is included in the Error
• static void assertFalse(boolean test)static void assertFalse(String message, boolean test)– Throws an AssertionFailedError if the test fails
14
Example: Counter class
• For the sake of example, we will create and test a trivial “counter” class– The constructor will create a counter and set it to zero– The increment method will add one to the counter and return the new
value– The decrement method will subtract one from the counter and return
the new value• We write the test methods before we write the code
– This has the advantages described earlier– Depending on the JUnit tool we use, we may have to create the class
first, and we may have to populate it with stubs (methods with empty bodies)
• Don’t be alarmed if, in this simple example, the JUnit tests are more code than the class itself
15
JUnit tests for Counter public class CounterTest extends junit.framework.TestCase {
Counter counter1;
public CounterTest() { } // default constructor
protected void setUp() { // creates a (simple) test fixture counter1 = new Counter(); }
protected void tearDown() { } // no resources to release
public void testIncrement() { assertTrue(counter1.increment() == 1); assertTrue(counter1.increment() == 2); }
public void testDecrement() { assertTrue(counter1.decrement() == -1); }}
Note that each test begins with a brand new counter
This means you don’t have to worry about the order in which the tests are run
16
The Counter class itself public class Counter {
int count = 0;
public int increment() { return ++count;}
public int decrement() { return --count;}
public int getCount() { return count; }}
• Is JUnit testing overkill for this little class?• The Extreme Programming view is: If it isn’t tested, assume it doesn’t work• You are not likely to have many classes this trivial in a real program, so
writing JUnit tests for those few trivial classes is no big deal• Often even XP programmers don’t bother writing tests for simple getter
methods such as getCount()• We only used assertTrue in this example, but there are additional assert
methods
17
Assert methods II
• assertEquals(expected, actual)assertEquals(String message, expected, actual)– This method is heavily overloaded: expected and actual must be both
objects or both of the same primitive type– For objects, uses your equals method, if you have defined it properly, as
public boolean equals(Object o)—otherwise it uses ==
• assertSame(Object expected, Object actual)assertSame(String message, Object expected, Object actual) – Asserts that two objects refer to the same object (using ==)
• assertNotSame(Object expected, Object actual)assertNotSame(String message, Object expected, Object actual) – Asserts that two objects do not refer to the same object
18
Assert methods III
• assertNull(Object object)assertNull(String message, Object object) – Asserts that the object is null
• assertNotNull(Object object)assertNotNull(String message, Object object) – Asserts that the object is null
• fail()fail(String message) – Causes the test to fail and throw an AssertionFailedError– Useful as a result of a complex test, when the other assert methods
aren’t quite what you want
19
The assert statement• Earlier versions of JUnit had an assert method instead of an
assertTrue method– The name had to be changed when Java 1.4 introduced the assert
statement• There are two forms of the assert statement:
– assert boolean_condition;– assert boolean_condition: error_message;– Both forms throw an AssertionFailedError if the boolean_condition is
false– The second form, with an explicit error message, is seldom necessary
• When to use an assert statement:– Use it to document a condition that you “know” to be true– Use assert false; in code that you “know” cannot be reached (such as a
default case in a switch statement)– Do not use assert to check whether parameters have legal values, or
other places where throwing an Exception is more appropriate
20
Junit in eclipse - Setup
• In Eclipse– Create a new project– Open project’s property
window (File -> Properties) – Select: Java build path– Select: libraries– Add Library– Select Junit
• Select the type 3.x or 4.x
21
Create a new JUnit test case
• File– New
• Junit Test Case– Set the parameters:
» Junit 3.x or 4.x» name of the class» etc.
– Finish
Eclipse Menu
File Edit Source Refactor Navigate Search Project Run Window Help
22
Run as JUnit Test
• Run– Run As
• Junit Test
Eclipse Menu
File Edit Source Refactor Navigate Search Project Run Window Help
23
Red / Green Bar
expected <-3> but was <-4>
Fail
Pass
24
Unit Testing Web Services
• Web services as a presentation layer of sorts– Tested using an approach analogous to testing GUI – Separating the presentation layer from the application logic– Each method and behavior of the web service interface
should have corresponding tests• To validate how the service methods work "over the
wire," it's not sufficient just to create an instance of the service interface class and invoke its methods directly.
• The service methods must be validated by calling them via the client interface, the same way they are called in the live application.
25
Unit Testing Web Services: An example
public class MyServiceTest extends TestCase { public void setUp() { String URI = "http://localhost/services/MyService"; // ... create service endpoint and connect to URI ... MyService service = endpoint.getMyService(); } public void testGetDoc() { service.putDoc( "test" ); assertEquals( "test", service.getDoc() ); } public void tearDown() { service.destroy(); } }
26
Web service invoke - Ajax
27
What is Ajax?
• AJAX (shorthand for asynchronous JavaScript and XHTML) is a group of interrelated web development techniques used on the client-side to create interactive web applications or rich Internet applications.
28
Simple Ajaxfunction Ajax_Call(myurl, callfunc){
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
if( req ) {
var localurl;
var isrefresh=true;
if(isrefresh) {
localurl = addTimeStamp1(myurl);
} else{
localurl = myurl;
}
req.open("GET", localurl, true);
req.onreadystatechange = callfunc;
req.send(null);
} }
<input type=button value=“ajaxcall” onClick="Ajax_Call (‘http://xyz.com/a.jsp?id=123 ‘);” />
客户端
button Ajax_call
服务器端
webserver
1
2 3
http request http response
callfunc
4
UI 5
29
Ajax Web Services (1)• First invoke a Web Service by:<script type="text/javascript" src="scripts/prototype.js"></script>
<script type="text/javascript" src="scripts/ws.js"></script>
<script type="text/javascript">
function sayHello(name, container) {
var call = new WS.Call('/AjaxWS/services/HelloWorld');
var nsuri = 'http://example';
var qn_op = new WS.QName('sayHello',nsuri);
var qn_op_resp = new WS.QName('sayHelloResponse',nsuri);
call.invoke_rpc(
qn_op,
new Array( {name:'name',value:name} ),
null,
function(call,envelope) {
var ret = envelope.get_body().get_all_children()[0].
get_all_children()[0].get_value();
container.innerHTML = ret;
$('soap').innerHTML = arguments[2].escapeHTML();
} );
} </script>
30
Ajax Web Services (2)
• Then Calling the sayHello function
<body>
<input name="name" id="name" />
<input value="Invoke the Web Service" type="button" onclick="sayHello($('name').value,$('result'))" />
<div id="container">Result:
<div id="result"> </div>
<div id="soap"> </div>
</div>
</body>Please refer to the source code: • ws-ajax-web-service-code.zip OR• http://www.simple-talk.com/dotnet/asp.net/calling-cross-domain-web-services-in-ajax/
31
Ajax is not just Web Service…<script type="text/javascript">
document.write(unescape("%3Cscript src='http://arnetminer.org/js/arnet.js‘ type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript"> arnet_socialGraph("jie tang",900,650);
</script>
32
WS call is not just ajax…<!-- Include css & js -->
<link type="text/css" rel="stylesheet" href="http://arnetminer.org/css/person-ranking.css" />
<script type="text/javascript" src="http://arnetminer.org/js/jquery.js">
<!-- First Include this js -->
<script type="text/javascript">document.write(unescape("%3Cscript src='http://arnetminer.org/js/arnet.js' type='text/javascript'%3E%3C/script%3E"));</script>
<!-- place person block in place -->
<script type="text/javascript">person_block_inline("jie tang", -1, -1, 90, 60);</script>
33
Summary
34
Summary
• As a distributed computing architecture, Web Services are the most important implementation for SOA;
• Web Services: Flexible machine-machine interaction;• SOAP is a light weight replacement for complicated
distributed object technology which we use to wrap Web Services message;
• The function and interface of Web Services is open by WSDL and the interaction between Web Services is presented by BPEL.
35
Further Question?
• SOAP?• WSDL?• BPEL?• UDDI?
36
Reference•A list of web service specifications. http://en.wikipedia.org/wiki/List_of_Web_service_specifications.•SOA & Webservices.http://www-900.ibm.com/developerWorks/cn/ webservices•WebServices. http://www.w3.org/2002/ws/•Ueli Wahli ,Thomas Kjaer…“WebSphere Version 6 Web Services Handbook Development&Deployment”,http://www.redbooks.ibm.com/redbooks/pdfs/sg246461.pdf,2005•Stan Kleijnen,Srikanth Raju.An Open Web Services Archiecture.NewYork: ACM Press,2003•XML.http://www.w3.org/TR/xml/•XML Schema. http://www.w3.org/TR/xmlschema11-1/•WSDL. http://www.w3.org/TR/wsdl•Tony Andrews, Francisco Curbera. Business Process Execution Language for Web Services Version 1.1.http://download.boulder.ibm.com/ ibmdl/pub/software/dw/specs/ws-bpel/ws-bpel.pdf•The Stencil Group.” The Evolution of UDDI ,UDDI.org White Paper” http://www.uddi.org/pubs/the_evolution_of_uddi_20020719.pdf
37
References
• Reference WebSite: http://ww.junit.org • JUnit 4.0 in 10 minutes
http://www.instrumentalservices.com/media/articles/java/junit4/JUnit4.pdf • Quick and easy introduction http://clarkware.com/articles/JUnitPrimer.html • Ted Husted, Vincent Massol. JUnit in Action. Book.• Kent Beck, Eric Gamma, Test Infected: Programmers Love Writing Tests.
http://junit.sourceforge.net/doc/testinfected/testing.htm • Bryan Dollery. JUnit and Its Extensions Make Unit Testing Your Java Code Much
Easier. http://www.devx.com/Java/Article/9614 • Test First Demo:
http://rm.mirror.garr.it/mirrors/eclipse/technology/phoenix/demos/testfirst/testfirst.html
• An early look at JUnit 4, http://www.ibm.com/developerworks/java/library/j-junit4.html
• http://today.java.net/pub/a/today/2006/12/07/junit-reloaded.html • http://www.devx.com/Java/Article/31983/1763/page/2 • Unit Test Web Service, http://www.drdobbs.com/web-development/211201695
38
Links•Roy Felding’s dissertation –http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm•SOAP vs REST comparison paper –http://www.jopera.org/docs/publications/2008/restws•Security for REST web services presentation by Mark O’Neill of Vordel –http://www.vordel.com/downloads/rsa_conf_2006.pdf•Popular REST Frameworks in Java–Restlet (http://www.restlet.org)–Axis 2.0 (http://ws.apache.org/axis2/0_94/rest-ws.html)–Jboss RESTEasy (http://www.jboss.org/resteasy/)–Apache CXF (http://cxf.apache.org/)•Popular REST Frameworks in other lang.–Ruby on REST(http://rubyforge.org/projects/rubyrest/)–Rest in Python (http://lukearno.com/projects/rip/)–.NET•Familiar RESTful services–TeraGrid Info Services (http://info.teragrid.org/web-apps/html/index/)–Amazon Web Services (http://aws.amazon.com/)–Yahoo! Web Services (http://developer.yahoo.com/everything.html)–Google Web Services (http://code.google.com/apis/ajax/)•Accessing REST services–Python: http://developer.yahoo.com/python/python-rest.html
40
Appendix
41
Terminology• A test fixture sets up the data (both objects and primitives) that
are needed to run tests– Example: If you are testing code that updates an employee record, you
need an employee record to test it on• A unit test is a test of a single class• A test case tests the response of a single method to a particular
set of inputs• A test suite is a collection of test cases• A test runner is software that runs tests and reports results
• An integration test is a test of how well classes work together– JUnit provides some limited support for integration tests
42
What is soapUI?
• soapUI is an application for inspecting, invoking, developing, simulating/mocking and functional/load/compliance testing of web services over HTTP.
• More on soapUI on http://www.soapui.org . • Process
– In order to begin testing a service we need to have a WSDL file describing it.
– Next you will need to create the .xsd files needed in the WSDL description so that soapUI can validate the schema our services responses.
43
Creating Tests I
• Click to start soapUI• Now lets create a WSDL project. Go to the menu bar and click
File -> New WSDL project• From there you can give the project a name. Because of path
problems its not recommended to add a WSDL file yet. Click ok and the project will be created
44
Creating Tests II
• Right click on the newly created Project and choose Add WSDL from URL.
• Then enter something like file:./request.wdsl
• In windows this may not work. If this is the case then choose Add WSDL from file.
• Then agree to Create default Requests for all operations.
• Then you will see that a request was created based on your WSDL description
45
Creating Tests III
• The example requests accuracy is determined by the detail of the definitions in the xsd files
• You will notice that it’s not quite like the real thing and modifications are required. You may modify it or you can simple copy paste an example request inside the <soap:body> tag.
46
Creating Tests IV
• Right click on the service interface icon and choose Generate Testsuite in order to create the container for the test cases to come
• This will create the container for the test cases to be defined.
47
Creating Tests V
• To create a new test case right click on the newly created
Testsuite icon and choose New TestCase. Give it a name and the new test case is created.
48
Creating tests VI
• To add a request to the test case right click on the example request and choose Add to Testcase
• The test suite and test cases can be manipulated by right clicking on their icons and selecting their corresponding editors.
49
Creating tests VII
• The request window should now appear. Click on the green play button on the upper left side to send the request to the service.
• You can set the service address in the text bar on the top of the window. The response will appear on the right hand side
• By right clicking the space below the window you can add assertions-tests for the response
50
Creating Tests VIII
• Choose schema validation and in the next message box choose the response WSDL file
• soapUI will then validate the response.
• In the same manner one can add soap fault assertions XPath matches or simple contains matches
51
Creating Tests IX
• XPath matches are one of the most useful features of soapUI
• Choose the XPath matches. Then click on declare. Add your XPath expression and click Select from current. The result of the XPath expression on the response will appear on the expected result box
• If it is what you were going for click save and there you are!
52
Creating Tests X
• In the same manner one can add tests for the response not being a soap fault or just to check if a certain string is part of the result
• For more in depth testing and for database access the use of a Groovy script is needed…
53
• Survey on WS Testing– http://asusrl.eas.asu.edu/share/xyz/Research/
Research/work-on%20paper/WS%20testing/WS%20Testing%20Survey%2010.doc