1.35k likes | 1.61k Views
Java Web Service Servers and Clients in Internet2 Grouper. February 2009 Chris Hyzer University of Pennsylvania IT Internet2. Purpose of this presentation. Show how Internet2 Grouper developed web services Grouper is open source, feel free to borrow or suggest improvements
E N D
Java Web Service Servers and Clients in Internet2 Grouper February 2009 Chris Hyzer University of Pennsylvania IT Internet2
Purpose of this presentation Show how Internet2 Grouper developed web services Grouper is open source, feel free to borrow or suggest improvements Discuss the successes and areas for improvement Mention planned enhancements University of Pennsylvania
Contents • Introduction to Internet2 Grouper • Introduction to web services • Architecture of REST/SOAP web service • SOAP web services with Axis2 (servers and clients) • REST web services with xstream (servers and clients) • Client • Documenting web services • Bonus material • Security • Axis serving Rest • Testing University of Pennsylvania
Introduction to Internet2 Grouper University of Pennsylvania
Internet2 Grouper Open source group management Internet2 has been working on group management for 8 years Generally used in educational institutions, but could be anywhere Funded by Internet2 University of Pennsylvania
Why central group management with Grouper? • Instead of apps managing own groups • Reuse group lists • Central place to see which groups a person is in • Central auditing of group and membership actions • Central management of authorization • Security: • Who can view/edit groups and memberships • Opt-in/Opt-out • Delegate authority • Automatic or manual membership management • Composite groups for group match: and / or / minus • Groups of groups University of Pennsylvania
Grouper architecture University of Pennsylvania
Introduction toWEB SERVICES University of Pennsylvania
User web request Person using browser makes a request to a server Person (user) views the results in browser, and types and or clicks to continue University of Pennsylvania
Web service request Program makes a request to a web application Program parses the output University of Pennsylvania
Overlap of web request and web service? • Ajax for example • Can be kicked off by a user click • Can update the screen similar to a web application • However, Ajax is making the request and parsing the response, it is a web service • If it doesn’t parse the output, and just puts the resultant HTML into the browser DOM, then not a web service • Web service screen scraping a web application • A program can “screen scrape” a web application • Beware of changes in the HTML! • This is not a web service • Is a browser an application making requests, are all user requests web services? University of Pennsylvania
Why web services • http(s) is a well understood protocol by programming languages and programmers • Ports 80/443 might already be available in firewall rules • Http is text based (easy to debug) • Http is not programming language specific, so the server technology can be different than the client (e.g. ajax) • Webpages are either XML, XHTML, or XML-like (e.g. HTML) • Most programming languages have XML libraries • Note: web services do not have to be XML, though generally the are • Development and production environments might be similar (or same) to existing web applications • Penn generally communicates between systems with WS University of Pennsylvania
SOAP web services Simple Object Access Protocol Specifies how web service messages are exchanged W3C standard Must use XML and XML schema for data Messages have XML envelopes, headers, body, exception handling Web Service Description Language (WSDL) describes the SOAP messages in a programmatic way (XML) Many features (security, error handling, caching, resource discovery, etc) Many programming languages generate SOAP Not considered light-weight University of Pennsylvania
Example SOAP request <?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> <soapenv:Body> <ns1:addMemberLite xmlns:ns1="http://soap.ws.grouper.middleware.internet2.edu/xsd"> <ns1:groupName>aStem:aGroup</ns1:groupName> <ns1:subjectIdentifier>mchyzer</ns1:subjectIdentifier> </ns1:addMemberLite> </soapenv:Body> </soapenv:Envelope> University of Pennsylvania
REST web services • Representational State Transfer • Two definitions: • (strict or RESTful): Protocol that specifies how HTTP (perhaps) and XML are used for web services • (non-strict): Any web service that does not have the overhead of SOAP. Aka Remote Procedure Call (RPC) University of Pennsylvania
RESTful web services The web services are organized like static web resources URL’s represent resources, not operations HTTP methods indicate the operations. Generally: GET, POST (update), PUT (insert), DELETE. Can use more, or custom Messages can be HTML so that systems or browsers can consume them University of Pennsylvania
Example REST web service • PUT /grouperWs/servicesRest/xhtml/v1_4_000/groups/aStem%3AaGroup/members/mchyzer • This means add this member to the group University of Pennsylvania
HTTP / XML / RPC / Hybrid web services • Each service makes its own standards • URL can be: • Resource: http://localhost/grouperWs/group • Operation: http://localhost/grouperWs/addGroup • Generally just use POST or GET as the HTTP method • The XML document sent can be: • Complete object representation:<group><name>myGroup</name><desc>MyGroup</desc></group> • Operational:<groupChangeName><groupId>123</groupId><newName>myGroup2</newName></groupChangeName> University of Pennsylvania
GROUPER WEB SERVICES University of Pennsylvania
Grouper web services • Generally web services are programmed to host a service • Grouper is software, so its WS are programmed so institutions can download and host services • E.g. Grouper is app server and database server agnostic • Requirements • Dozen operations • SOAP and REST (as close to RESTful as possible) • SOAP and REST should deploy in one webapp • Simple operations (Lite), and batched operations • Pluggable authentication • Documented well • Versioned (generally Grouper has bi-annual releases) University of Pennsylvania
Grouper web service operations • findGroups • findStems • stemSave • stemDelete • memberChangeSubject • getGrouperPrivileges • assignGrouperPrivileges addMember deleteMember getMembers hasMember getGroups groupSave groupDelete University of Pennsylvania
Litevs batched • One batched operation has less overhead than many smaller operations (performance test for yourself to validate) • Benchmarks • Add group (inserts), requires many queries • 100 batches of 1 add groups take 19.8 seconds • 10 batches of 10 add groups take 12.4 seconds • 5 batches of 20 add groups take 12.0 seconds • Has member, lightweight, readonly • 100 batches of 1 hasMember checks take 8.3 seconds • 10 batches of 10 checks take 1.9 seconds • 5 batches of 20 checks take 1.6 seconds • Benchmarks notes • Completely run on developer PC, local mysql • E.g. WsSampleHasMemberRest100 University of Pennsylvania
Object model • Assume web service data are simple POJOs (Plain Old Java Objects) • Use only: • Beans • Arrays (of beans or simple types) • Simple types: String, Integer • Note: • Don’t use Collections, enums, dates, timestamps, booleans University of Pennsylvania
Object model (continued) What makes up the data of a group? Here is a simple group University of Pennsylvania
Object model (continued) What makes up the data of a group? Here is a more complex group University of Pennsylvania
Object model (continued) University of Pennsylvania
Object model (continued) Request object model University of Pennsylvania
Object model (continued) Response object model University of Pennsylvania
Object model (continued) Metadata object model Response metadata is one per response Result metadata is one per Lite response, or one per each line item in batch Success: T|F Result code: many enums Codes also inHTTP headers University of Pennsylvania
Object model (continued) • Operations should be idempotent if possible • If they are sent twice, generally it is ok • Delete member mchyzer from group etc:sysAdminGroup • Idempotent • Delete the first member of group etc:sysAdminGroup • NOT idempotent 10/4/2014 University of Pennsylvania 30
SOAP web services with Axis2 University of Pennsylvania
Axis architecture University of Pennsylvania
Business logic for Axis Create a class (GrouperService) Contains only instance methods of business logic Each method takes all fields of the input bean, and returns the output bean Each bean is only simple pojo (uses Javabean properties) Note the Lite methods only take scalars are inputs University of Pennsylvania
Business logic for Axis (continued) University of Pennsylvania
Business logic for Axis (continued) GrouperService isn’t great for Javadoc since enums are strings Delegate to GrouperServiceLogic Decode booleans, dates, enums, etc University of Pennsylvania
Axis generate WSDL Generate WSDL from POJOs and GrouperService class <target name="java2wsdl" description="convert the java to a wsdl"> <touch file="${generated.client.project.dir}/GrouperService.wsdl" /> <delete file="${generated.client.project.dir}/GrouperService.wsdl" /> <java classname="org.apache.ws.java2wsdl.Java2WSDL" fork="true"> <classpath refid="ws.class.path" /> <arg value="-o" /><arg value="${generated.client.project.dir}" /> <arg value="-of" /><arg value="GrouperService.wsdl" /> <arg value="-cn" /> <arg value="edu.internet2.middleware.grouper.ws.soap.GrouperService" /> <arg value="-stn" /> <arg value="http://soap.ws.grouper.middleware.internet2.edu/xsd" /> <arg value="-l" /> <arg value="http://localhost:8090/grouper-ws/services/GrouperService" /> </target> University of Pennsylvania
Axis generate WSDL (continued) Generate WSDL from POJOs and GrouperService class C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws>ant java2wsdl Buildfile: build.xml java2wsdl: [delete] Deleting: C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws-java -generated-client\GrouperService.wsdl BUILD SUCCESSFUL Total time: 9 seconds C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws> University of Pennsylvania
Axis generate WSDL (continued) Result University of Pennsylvania
Axis generate WSDL (continued) Result – 2000 lines of SOAP definition University of Pennsylvania
Axis generate client Ant script to generate SOAP client from WSDL (any WSDL) <target name="wsdl2java" description="convert the wsdl to a java client"> <delete><fileset dir="${generated.client.project.dir}"> <include name=“…” /></fileset></delete> <java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true"> <classpath refid="ws.class.path" /> <arg value="-uri" /> <arg file="${generated.client.project.dir}/GrouperService.wsdl" /> <arg value="-t" /><arg value="-u" /><arg value="-p" /> <arg value="edu.internet2.middleware.grouper.webservicesClient" /> <arg value="-o" /><arg value="${generated.client.project.dir}" /> </java> </target> University of Pennsylvania
Axis generate client (continued) Run ant script to generate client C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws>ant wsdl2java Buildfile: build.xml wsdl2java: [java] Retrieving document at 'C:\dev_inst\eclipse\workspace\grouper_v1_4\g rouper-ws-java-generated-client\GrouperService.wsdl'. BUILD SUCCESSFUL Total time: 9 seconds C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws> University of Pennsylvania
Axis generate client (continued) Result: 100 classes, ~5megs of source University of Pennsylvania
Axis archive Axis needs an AAR file of logic, create via ant to WEB-INF/services/GrouperService.aar <target name="generate-aar" depends="compile"> <property name="webservice.folder" value="${basedir}/webservices" /> <delete dir="${webservice.folder}/classes" /> <copy toDir="${webservice.folder}/classes" failonerror="false"> <fileset dir="${build.dir.grouper-ws}"> <include name="edu/internet2/middleware/grouper/ws/**/*.class" /> </fileset></copy> <jar destfile="${basedir}/webapp/WEB-INF/services/GrouperService.aar"> <fileset excludes="edu/internet2/middleware/grouper/ws/**/*Test.class" dir="${webservice.folder}/classes" /> <fileset dir="webservices/GrouperService.aar" /> </jar> </target> University of Pennsylvania
Axis configuration Configure the web.xml for Axis <servlet><servlet-name>AxisServlet</servlet-name> <display-name>Apache-Axis Servlet</display-name> <servlet-class> edu.internet2.middleware.grouper.ws.GrouperServiceAxisServlet </servlet-class> <load-on-startup>1</load-on-startup> <!-- hint that this is the wssec servlet --> <!-- init-param> <param-name>wssec</param-name> <param-value>true</param-value> </init-param --> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> University of Pennsylvania
Axis configuration (continued) Boilerplate WEB-INF/conf/axis2.xml WEB-INF/modules/*.mar WEB-INF/modules/modules.list WEB-INF/services/*.aar (including GrouperService.aar) WEB-INF/service/services.list WEB-INF/lib/ (50 axis jars) University of Pennsylvania
Axis Example See video (make sure you have the Xvid codec): https://wiki.internet2.edu/confluence/download/attachments/3014660/soapExample.avi University of Pennsylvania
REST web services with xstream University of Pennsylvania
Xstream Easy to use Java object to XML processor In this example I alias the class names so they arent so long publicclass XstreamPocGroup { public XstreamPocGroup(String theName, XstreamPocMember[] theMembers) { this.name = theName; this.members = theMembers; } private String name; private XstreamPocMember[] members; public String getName() { ... University of Pennsylvania
Xstream (continued) This is the child bean publicclass XstreamPocMember { publicXstreamPocMember(String theName, String theDescription) { this.name = theName; this.description = theDescription; } private String name; private String description; } University of Pennsylvania
Xstream (continued) publicstaticvoid main(String[] args) { XstreamPocGroup group = newXstreamPocGroup("myGroup", newXstreamPocMember[]{ newXstreamPocMember("John", "John Smith - Employee"), newXstreamPocMember("Mary", "Mary Johnson - Student")}); XStreamxStream = newXStream(newXppDriver()); xStream.alias("XstreamPocGroup", XstreamPocGroup.class); xStream.alias("XstreamPocMember", XstreamPocMember.class); StringWriterstringWriter = newStringWriter(); xStream.marshal(group, newCompactWriter(stringWriter)); String xml = stringWriter.toString(); System.out.println(GrouperUtil.indent(xml, true)); group = (XstreamPocGroup)xStream.fromXML(xml); System.out.println(group.getName() + ", number of members:" + group.getMembers().length); } University of Pennsylvania