Groovy Xml Web Services Paul King Apache Con2008

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Favorites, Groups & Events

    Groovy Xml Web Services Paul King Apache Con2008 - Presentation Transcript

    1. XML and Web Services with Groovy Dr Paul King paulk@asert.com.au ASERT, Australia
    2. What is Groovy? • “Groovy is like a super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, DSL support, builders and dynamic typing.” Groovy = Java – boiler plate code + optional dynamic typing + closures + domain specific languages + builders + metaprogramming
    3. Why Groovy? • Minimal learning curve • Compiles to bytecode • Java object model & integration • Annotations • Optional static typing • Both run-time and compile-time metaprogramming
    4. Groovy and XML ... • Reading XML – Special Groovy support: XmlParser, XmlSlurper, DOMCategory – Or Groovy sugar for your current favorites: DOM, SAX, StAX, DOM4J, JDom, XOM, XPath, XSLT, XQuery, etc. • Creating XML – Special Groovy support: MarkupBuilder and StreamingMarkupBuilder – Or again, enhanced syntax for your current favorites
    5. ... Groovy and XML • Updating XML – Using above: read followed by create – Can be done with XmlParser, XmlSlurper, DOMCategory – Or with your Java favorites • Verifying XML – Also DTD, W3C XML Schema, Relax NG in a similar fashion to Java mechanisms for these features
    6. An Xml Example ... import groovy.xml.dom.DOMCategory class Flights { static final String XML = ''' <trip> <flight hours=\"13\"> <from>Brisbane</from> <to>Los Angeles</to> </flight> <flight hours=\"4\"> <from>Los Angeles</from> <to>New Orleans</to> </flight> </trip> ''' ...
    7. ... An Xml Example ... static final Reader getReader() { new StringReader(XML) } static final Set getCities(flights) { Set cities = [] use(DOMCategory) { flights.each { f -> cities += f.to[0].text() cities += f.from[0].text() } } cities } }
    8. XmlParser def trip = new XmlParser().parseText(Flights.XML) assert trip.flight[0].to.text() == 'Los Angeles' assert trip.flight[1].@hours == '4' Set cities = trip.flight.from*.text() + trip.flight.to*.text() assert cities == ['Brisbane', 'Los Angeles', 'New Orleans'] as Set assert trip.flight.@hours == ['13', '4'] assert trip.flight.@hours*.toInteger().sum() == 17 • Builds an in-memory DOM tree
    9. XmlSlurper... def trip = new XmlSlurper().parseText(Flights.XML) assert trip.flight[0].to.text() == 'Los Angeles' assert trip.flight[1].@hours == '4' Set cities = trip.flight.from*.text() + trip.flight.to*.text() assert cities == ['Brisbane', 'Los Angeles', 'New Orleans'] as Set assert trip.flight.@hours.list() == ['13', '4'] assert trip.flight.@hours*.toInteger().sum() == 17 • Lazy evaluation of expressions – Consider this for streaming scenarios
    10. ...XmlSlurper... • What does Lazy mean? def trip = new XmlSlurper().parseText(Flights.XML) def moreThanFiveHours = { f -> f.@hours.toInteger() > 5 } def arrivingLax = { f -> f.to == 'Los Angeles' } def departingOz = { f -> f.from == 'Brisbane' } def longFlights = trip.flight.findAll(moreThanFiveHours) def longLaxFlights = longFlights.findAll(arrivingLax) def longOzLaxFlights = longLaxFlights.findAll(departingOz) assert longOzLaxFlights.@hours == '13'
    11. ...XmlSlurper Light-weight scanning here def trip = new XmlSlurper().parseText(Flights.XML) def moreThanFiveHours = { f -> f.@hours.toInteger() > 5 } def arrivingLax = { f -> f.to == 'Los Angeles' } def departingOz = { f -> f.from == 'Brisbane' } def longFlights = trip.flight.findAll(moreThanFiveHours) def longLaxFlights = longFlights.findAll(arrivingLax) def longOzLaxFlights = longLaxFlights.findAll(departingOz) assert longOzLaxFlights.@hours == '13' Lazy expression storage Usage triggers evaluation but deferred evaluation
    12. A Namespace Example class Books { static final String XML = ''' <rdf:RDF xmlns:bibterm=\"http://www.book-stuff.com/terms/\" xmlns:dc=\"http://purl.org/dc/elements/1.0/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"> <rdf:Description rdf:about=\"http://www.book-stuff.com/bib\"> <bibterm:book rdf:parseType=\"Resource\"> <bibterm:year>2007</bibterm:year> <dc:title>Groovy in Action</dc:title> <bibterm:author rdf:parseType=\"Resource\"> <bibterm:last>König</bibterm:last> <bibterm:first>Dierk</bibterm:first> </bibterm:author> <rdf:comment> Coauthors: Andrew Glover, Paul King, Guillaume Laforge and Jon Skeet </rdf:comment> </bibterm:book> </rdf:Description> </rdf:RDF> ''' ...
    13. XmlParser and Namespaces import groovy.xml.Namespace def book = new XmlParser().parseText(Books.XML) def rdf = new Namespace( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf') def dc = new Namespace( 'http://purl.org/dc/elements/1.0/', 'dc') def bibterm = new Namespace( 'http://www.book-stuff.com/terms/', 'bibterm') def b = book[rdf.Description][bibterm.book] assert b[dc.title].text() == 'Groovy in Action' assert b[bibterm.year].text() == '2007'
    14. XmlSlurper and Namespaces def book = new XmlSlurper().parseText(Books.XML) book.declareNamespace( rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', dc: 'http://purl.org/dc/elements/1.0/', bibterm: 'http://www.book-stuff.com/terms/') def b = book.'rdf:Description'.'bibterm:book' assert b.'dc:title' == 'Groovy in Action' assert b.'bibterm:year' == '2007'
    15. What about non-XML? def neko = new org.cyberneko.html.parsers.SAXParser() neko.setFeature('http://xml.org/sax/features/namespaces', false) def page = new XmlParser(neko).parse('http://groovy.codehaus.org/') def data = page.depthFirst().A.'@href'.grep{ it != null && it.endsWith('.html') } data.each { println it } def neko = new org.cyberneko.html.parsers.SAXParser() def page = new XmlSlurper(neko).parse('http://groovy.codehaus.org/') def data = page.depthFirst().grep{ it.name() == 'A' && it.@href.toString().endsWith('.html') }.'@href' data.each { println it } http://groovy.codehaus.org/apidocs/index.html /faq.html /groovy-jdk.html ...
    16. Raw DOM import groovy.xml.DOMBuilder def trip = DOMBuilder.parse(Flights.reader).documentElement def flights = trip.getElementsByTagName('flight') def dest = flights.item(0).getElementsByTagName('to').item(0) assert dest.firstChild.nodeValue == 'Los Angeles' assert flights.item(1).getAttribute('hours') == '4' assert Flights.getCities(flights) == ['Brisbane', 'Los Angeles', 'New Orleans'] as Set
    17. DOM plus metaprogramming import groovy.xml.DOMBuilder import org.w3c.dom.Element def trip = DOMBuilder.parse(Flights.reader).documentElement Element.metaClass.element = { t, i -> delegate.getElementsByTagName(t).item(i) } Element.metaClass.text = {-> delegate.firstChild.nodeValue } assert trip.element('flight', 0).element('to', 0).text() == 'Los Angeles' assert trip.element('flight', 1).getAttribute('hours') == '4'
    18. DOMCategory import groovy.xml.DOMBuilder import groovy.xml.dom.DOMCategory def doc = DOMBuilder.parse(Flights.reader) def trip = doc.documentElement use(DOMCategory) { assert trip.flight[0].to[0].text() == 'Los Angeles' assert trip.flight[1].'@hours' == '4' assert Flights.getCities(trip.flight) == ['Brisbane', 'Los Angeles', 'New Orleans'] as Set }
    19. DOM4J import org.dom4j.io.SAXReader def trip = new SAXReader().read(Flights.reader).rootElement assert trip.elements()[0].elementText('to') == 'Los Angeles' assert trip.elements()[1].attributeValue('hours') == '4'
    20. JDOM import org.jdom.input.SAXBuilder def b = new SAXBuilder() def trip = b.build(Flights.reader).rootElement assert trip.children[0].getChildText('to') == 'Los Angeles' assert trip.children[1].getAttribute('hours').value == '4'
    21. XOM import nu.xom.Builder def doc = new Builder().build(Flights.reader) def flights = doc.rootElement.childElements assert flights.get(0).getFirstChildElement('to').value == 'Los Angeles' assert flights.get(1).getAttribute('hours').value == '4'
    22. StAX import static javax.xml.stream.XMLInputFactory.newInstance as staxFactory import javax.xml.stream.XMLStreamReader as StaxReader def flights = [] def flight def seenTag StaxReader.metaClass.attr = { s -> delegate.getAttributeValue(null, s) } def reader = staxFactory().createXMLStreamReader(Flights.reader) while (reader.hasNext()) { def name = reader.localName if (reader.startElement) { if (name == 'flight') flight = [hours:reader.attr('hours')] else if (name in ['from', 'to']) seenTag = name } else if (reader.characters) { if (seenTag) flight[seenTag] = reader.text } else if (reader.endElement) { if (name == 'flight') flights += flight seenTag = null } reader.next() } assert flights[0].to == 'Los Angeles' assert flights[1].hours == '4'
    23. import javax.xml.parsers.SAXParserFactory SAX import org.xml.sax.* import org.xml.sax.helpers.DefaultHandler class TripHandler extends DefaultHandler { def flights = [] private flight private seenTag void startElement(String ns, String localName, String qName, Attributes atts) { if (qName == 'flight') flight = [hours:atts.getValue('hours')] else if (qName in ['from', 'to']) seenTag = qName } public void endElement(String uri, String localName, String qName) { if (qName == 'flight') flights += flight seenTag = null } public void characters(char[] ch, int start, int length) { if (seenTag) flight[seenTag] = new String(ch, start, length) } } def handler = new TripHandler() def reader = SAXParserFactory.newInstance().newSAXParser().xMLReader reader.setContentHandler(handler) reader.parse(new InputSource(Flights.reader)) assert handler.flights[0].to == 'Los Angeles' assert handler.flights[1].hours == '4'
    24. XPath import javax.xml.xpath.* import groovy.xml.DOMBuilder def xpath = XPathFactory.newInstance().newXPath() def trip = DOMBuilder.parse(Flights.reader).documentElement assert xpath.evaluate('flight/to/text()', trip) == 'Los Angeles' assert xpath.evaluate('flight[2]/@hours', trip) == '4' def flights = xpath.evaluate( 'flight', trip, XPathConstants.NODESET ) def hoursAsInt = { n -> xpath.evaluate('@hours', n).toInteger() } assert flights.collect(hoursAsInt).sum() == 17 assert Flights.getCities(flights) == ['Brisbane', 'Los Angeles', 'New Orleans'] as Set
    25. Xalan XPath import static org.apache.xpath.XPathAPI.* import groovy.xml.DOMBuilder def trip = DOMBuilder.parse(Flights.reader).documentElement assert eval(trip, 'flight/to/text()').str() == 'Los Angeles' assert eval(trip, 'flight[2]/@hours').str() == '4' def flights = selectNodeList(trip, '//flight') def hoursAsInt = { n -> eval(n, '@hours').str().toInteger() } assert flights.collect(hoursAsInt).sum() == 17 assert Flights.getCities(flights) == ['Brisbane', 'Los Angeles', 'New Orleans'] as Set
    26. Jaxen XPath import org.jaxen.dom.DOMXPath import groovy.xml.DOMBuilder def trip = DOMBuilder.parse(Flights.reader).documentElement assert new DOMXPath('flight/to/text()'). stringValueOf(trip) == 'Los Angeles' assert new DOMXPath('flight[2]/@hours'). stringValueOf(trip) == '4' def flights = new DOMXPath('flight').selectNodes(trip) def hoursAsInt = { n -> new DOMXPath('@hours').numberValueOf(n) } assert flights.collect(hoursAsInt).sum() == 17 assert Flights.getCities(flights) == ['Brisbane', 'Los Angeles', 'New Orleans'] as Set
    27. JSR 225 - XQJ import net.sf.saxon.xqj.SaxonXQDataSource import javax.xml.xquery.XQSequence XQSequence.metaClass.collect = { Closure c -> def items = [] while (delegate.next()) items += c(delegate) items } def asString = { seq -> seq.getItemAsString(null) } def hourAttr = { it.item.node.getAttribute('hours') as int } def flights = \"document { ${Flights.XML} }\" def exp = new SaxonXQDataSource().connection.createExpression() def seq = exp.executeQuery(\"$flights/trip/flight/to/text()\") assert seq.collect(asString) == ['Los Angeles', 'New Orleans'] seq = exp.executeQuery(\"$flights/trip/flight\") assert seq.collect(hourAttr).sum() == 17
    28. import javax.xml.transform.TransformerFactory XSLT... import javax.xml.transform.stream.* def xslt = ''' <xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\"> <xsl:template match=\"/trip\"> <html> <body> <h1>Flights</h1> <ul> <xsl:apply-templates select=\"flight\"/> </ul> </body> </html> </xsl:template> <xsl:template match=\"flight\"> <li> <xsl:value-of select=\"from\"/> => <xsl:value-of select=\"to\"/> </li> </xsl:template> </xsl:stylesheet> '''.trim() def factory = TransformerFactory.newInstance() def transformer = factory.newTransformer( new StreamSource(new StringReader(xslt))) transformer.transform(new StreamSource(Flights.reader), new StreamResult(System.out))
    29. import javax.xml.transform.TransformerFactory ...XSLT import javax.xml.transform.stream.* def xslt = ''' <xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\"> <xsl:template match=\"/trip\"> <html> <html> <body> <body> <h1>Flights</h1> <h1>Flights</h1> <ul> <ul> <xsl:apply-templates select=\"flight\"/> <li>Brisbane =&gt; Los Angeles</li> </ul> <li>Los Angeles =&gt; New Orleans</li> </body> </ul> </html> </body> </xsl:template> </html> <xsl:template match=\"flight\"> <li> <xsl:value-of select=\"from\"/> => <xsl:value-of select=\"to\"/> </li> </xsl:template> </xsl:stylesheet> '''.trim() def factory = TransformerFactory.newInstance() def transformer = factory.newTransformer( new StreamSource(new StringReader(xslt))) transformer.transform(new StreamSource(Flights.reader), new StreamResult(System.out))
    30. MarkupBuilder def writer = new StringWriter() def xml = new MarkupBuilder(writer) xml.records() { car(name:'HSV Maloo', make:'Holden', year:2006) { country('Australia') record(type:'speed', 'Production Pickup Truck with speed of 271kph') } car(name:'P50', make:'Peel', year:1962) { country('Isle of Man') record(type:'size', 'Smallest Street-Legal Car at 99cm wide and 59 kg in weight') } car(name:'Royale', make:'Bugatti', year:1931) { country('France') record(type:'price', 'Most Valuable Car at $15 million') } }
    31. StreamingMarkupBuilder def xml = new StreamingMarkupBuilder().bind{ records { car(name:'HSV Maloo', make:'Holden', year:2006) { country('Australia') record(type:'speed', 'Production Pickup Truck with speed of 271kph') } car(name:'P50', make:'Peel', year:1962) { country('Isle of Man') record(type:'size', 'Smallest Street-Legal Car at 99cm wide and 59 kg in weight') } car(name:'Royale', make:'Bugatti', year:1931) { country('France') record(type:'price', 'Most Valuable Car at $15 million') }}}
    32. Updating XML <shopping> <shopping> <category type=\"groceries\"> <category type=\"groceries\"> <item>Luxury Chocolate</item> <item>Chocolate</item> <item>Luxury Coffee</item> <item>Coffee</item> </category> </category> <category type=\"supplies\"> <category type=\"supplies\"> <item>Paper</item> <item>Paper</item> <item quantity=\"6\" <item quantity=\"4\">Pens</item> when=\"Urgent\">Pens</item> </category> </category> <category type=\"present\"> <category type=\"present\"> <item when=\"Aug 10\"> <item>Mum's Birthday</item> Kathryn's Birthday <item when=\"Oct 15\"> </item> Monica's Birthday </category> </item> </shopping> </category> </shopping>
    33. Updating with XmlParser def root = new XmlParser().parseText(input) // modify groceries: quality items please def groceries = root.category.findAll{ it.@type == 'groceries' }.item groceries.each { g -> g.value = 'Luxury ' + g.text() } // modify supplies: we need extra pens def supplies = root.category.findAll{ it.@type == 'supplies' }.item supplies.findAll{ it.text() == 'Pens' }.each { s -> s.@quantity = s.@quantity.toInteger() + 2 s.@when = 'Urgent' } // modify presents: August has come and gone def presentCategory = root.category.find{ it.@type == 'present' } presentCategory.children().clear() presentCategory.appendNode('item', \"Mum's Birthday\") presentCategory.appendNode('item', [when:'Oct 15'], \"Monica's Birthday\")
    34. Updating with XmlSlurper def root = new XmlSlurper().parseText(input) // modify groceries: quality items please def groceries = root.category.find{ it.@type == 'groceries' } (0..<groceries.item.size()).each { groceries.item[it] = 'Luxury ' + groceries.item[it] } // modify supplies: we need extra pens def pens = root.category.find{ it.@type == 'supplies' }.item.findAll{ it.text() == 'Pens' } pens.each { p -> p.@quantity = (p.@quantity.toInteger() + 2).toString() p.@when = 'Urgent' } // modify presents: August has come and gone def presents = root.category.find{ it.@type == 'present' } presents.replaceNode{ node -> category(type:'present'){ item(\"Mum's Birthday\") item(\"Monica's Birthday\", when:'Oct 15') } }
    35. Groovy and Web Services • Straight Web Services – JAXB out of the box for Java 6 – CXF, Axis2, Spring Web Services – GroovySOAP using XFire for Java 1.4 – GroovyWS using CXF for Java 1.5+ • Frameworks layered upon SOA – Synapse, Tuscany, ServiceMix
    36. GroovySOAP class MathService { • Based on double add(double a, double b) { a+b Xfire, Java 1.4 } double square(double c) { c*c } import groovy.net.soap.SoapServer } def server = new SoapServer('localhost', 6789) server.setNode('MathService') server.start() import groovy.net.soap.SoapClient def url = 'http://localhost:6789/MathServiceInterface?wsdl' def math = new SoapClient(url) assert math.add(1.0, 2.0) == 3.0 assert math.square(3.0) == 9.0
    37. GroovyWS class MathService { double add(double arg0, double arg1) { • CXF based arg0 + arg1 } • Java 1.5+ double square(double arg0) { arg0 * arg0 } } import groovyx.net.ws.WSServer def server = new WSServer() server.setNode MathService.name, \"http://localhost:6980/MathService\" import groovyx.net.ws.WSClient def url = \"http://localhost:6980/MathService?wsdl\" def proxy = new WSClient(url, this.class.classLoader) def result = proxy.add(1.0d, 2.0d) assert result == 3.0d result = proxy.square(3.0d) assert result == 9.0d
    38. JAXB Server import javax.xml.ws.Endpoint import javax.jws.WebService import javax.jws.soap.SOAPBinding import javax.jws.WebMethod @WebService(name=\"Echo\", serviceName=\"EchoService\", targetNamespace=\"http://jaxws.asert.com\") @SOAPBinding(style=SOAPBinding.Style.RPC) class EchoImpl { @WebMethod(operationName = \"echo\") String echo(String message) { println(\"Received: $message\") \"\\nYou said: \" + message } } Endpoint.publish(\"http://localhost:8080/Echo\", new EchoImpl()) println 'EchoService published and running ...'
    39. JAXB Client import javax.xml.namespace.QName import com.asert.jaxws.EchoService def url = new URL(\"http://localhost:8080/Echo?wsdl\") def qname = new QName(\"http://jaxws.asert.com\", \"EchoService\") def echoServer = new EchoService(url, qname).echoPort println echoServer.echo(\"Today is ${new Date()}\") JAXB Build wsimport -d ../build -p com.asert.jaxws http://localhost:8080/Echo?wsdl
    40. Raw CXF • Apache CXF helps you build and develop services. You can use frontend programming APIs, like JAX-WS and support is provided for SOAP, XML/HTTP, RESTful HTTP, ... over HTTP, JMS, JBI, ... – Follow instructions for Java but there is also some special things you can do with Groovy
    41. Axis2 • Apache Axis is a comprehensive implementation of SOAP – Follow the instructions for Java but use Groovy instead and precompile – Use GroovyShell to call script at runtime • Another article: – http://www.developer.com/services/article. php/10928_3570031_2
    42. RESTful options • Several Options – Already supported in discussed frameworks, e.g. CXF – Groovy Restlet DSL http://docs.codehaus.org/display/GROOVY/GroovyRestlet – Jersey http://wikis.sun.com/display/Jersey/Main – restlet.org http://www.restlet.org
    43. restlet.org import org.restlet.* import org.restlet.data.* class MailboxResource extends Restlet { void handle(Request request, Response response) { switch (request.method) { case Method.GET: handleGet(request, response) break case Method.PUT: handlePut(request, response) break case Method.POST: handlePost(request, response) break default: // The request method is not allowed; set an error status response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED) response.setAllowedMethods([Method.GET, Method.PUT, Method.POST] as Set) } } void handleGet(request, response) { response.setEntity(\"Hello, world!\", MediaType.TEXT_PLAIN) } // ...
    44. GroovyRestlet DSL builder.component { current.servers.add(protocol.HTTP, 8182) application(uri: \"\") { router { def guard = guard(uri: \"/docs\", scheme: challengeScheme.HTTP_BASIC, realm: \"Restlet Tutorials\") guard.secrets.put(\"scott\", \"tiger\".toCharArray()) guard.next = directory(root: \"\", autoAttach: false) restlet(uri: \"/users/{user}\", handle: {req, resp -> resp.setEntity(\"Account of user \\\"${req.attributes.get('user')}\\\"\", mediaType.TEXT_PLAIN) }) restlet(uri: \"/users/{user}/orders\", handle: {req, resp -> resp.setEntity(\"Orders or user \\\"${req.attributes.get('user')}\\\"\", mediaType.TEXT_PLAIN) }) restlet(uri: \"/users/{user}/orders/{order}\", handle: {req, resp -> def attrs = req.attributes def message = \"Order \\\"${attrs.get('order')}\\\" for User \\\"${attrs.get('user')}\\\"\" resp.setEntity(message, mediaType.TEXT_PLAIN) }) } } Source: http://docs.codehaus.org/display/GROOVY/GroovyRestlet }.start()
    45. Jersey... package com.asert import javax.ws.rs.GET import javax.ws.rs.Path import javax.ws.rs.Produces import static com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory.* @Path (\"/helloworld\") class HelloWorldResource { @GET @Produces(\"text/plain\") String getPlainMessage() { \"Hello World\" } } def baseUri = \"http://localhost:9998/\" def initParams = [\"com.sun.jersey.config.property.packages\": \"com.asert\"] println \"\"\" Starting grizzly with Jersey... App WADL available at ${baseUri}application.wadl App available at ${baseUri}helloworld \"\"\" create(baseUri, initParams)
    46. ...Jersey... import javax.ws.rs.PathParam import javax.xml.bind.annotation.* class PrettyXml { static print(node) { def writer = new StringWriter() new XmlNodePrinter(new PrintWriter(writer)).print(node) writer.toString() } } @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) class FlightInfoBean { @XmlAttribute String hours @XmlElement String from, to static populate(num) { def trip = new XmlParser().parse(Flights.reader) def f = trip.flight[num as int] new FlightInfoBean(hours:f.@hours, from:f.from.text(), to:f.to.text()) } }
    47. ...Jersey @Path(\"/flight/xml/{flightnum}\") class FlightInfoXml { @GET @Produces(\"text/xml\") String getXmlMessage(@PathParam('flightnum') String num) { def trip = new XmlParser().parse(Flights.reader) PrettyXml.print(trip.flight[num as int]) } } @Path(\"/flight/json/{flightnum}\") class FlightInfoJson { @GET @Produces(\"application/json\") FlightInfoBean getJsonMessage(@PathParam('flightnum') String num) { FlightInfoBean.populate(num) } } @Path(\"/flight/atom/{flightnum}\") class FlightInfoAtom { @GET @Produces(\"application/atom\") FlightInfoBean getAtomMessage(@PathParam('flightnum') String num) { FlightInfoBean.populate(num) } }
    48. Synapse • Apache Synapse is a simple, lightweight and high performance Enterprise Service Bus (ESB) with support for XML, Web services, binary and text formats – Groovy scripting, endpoints, Synapse DSL – https://svn.apache.org/repos/asf/synapse/ trunk/java/src/site/resources/presentations /makingsoagroovyfremantle.pdf
    49. ServiceMix • ServiceMix is an open source Enterprise Service Bus (ESB) combining Service Oriented Architecture (SOA), Event Driven Architecture (EDA) and Java Business Integration (JBI) functionality – You can use ServiceMix Scripting – You can use legacy ScriptComponent and GroovyComponent – You can write Groovy JBI components
    50. Tuscany... • Tuscany embodies Service Component Architecture (SCA) which defines a simple, service-based model for construction, assembly and deployment of a network of services (existing and new ones) that are defined in a language-neutral way.” – You can define your services using Groovy either using Java mechanisms or Scripting integration
    51. ...Tuscany... <composite ...> <component name=\"CalculatorServiceComponent\" .../> <component name=\"AddServiceComponent\" .../> <component name=\"SubtractServiceComponent\"> <tuscany:implementation.java class=\"calculator.SubtractServiceImpl\"/> </component> <component name=\"MultiplyServiceComponent\"> <tuscany:implementation.script language=\"groovy\"> def multiply(n1, n2) { Compile your Groovy using groovyc n1 * n2 (with or without annotations) then } </tuscany:implementation.script> Need treat just like normal Java. </component> groovy jar in your runtime classpath. <component name=\"DivideServiceComponent\"> <tuscany:implementation.script script=\"calculator/DivideServiceImpl.groovy\"/> </component> </composite>
    52. ...Tuscany <composite ...> With Groovy scripts either <component name=\"CalculatorServiceComponent\" .../> <component name=\"AddServiceComponent\" .../> embedded or in files – no <component name=\"SubtractServiceComponent\"> compilation necessary. <tuscany:implementation.java class=\"calculator.SubtractServiceImpl\"/> </component> <component name=\"MultiplyServiceComponent\"> <tuscany:implementation.script language=\"groovy\"> def multiply(n1, n2) { n1 * n2 } </tuscany:implementation.script> </component> <component name=\"DivideServiceComponent\"> <tuscany:implementation.script script=\"calculator/DivideServiceImpl.groovy\"/> </component> </composite>
    53. More Information • Groovy in Action • Processing XML http://groovy.codehaus.org /Processing+XML • GroovyWS http://groovy.codehaus.org /GroovyWS • Coming soon ...
    SlideShare Zeitgeist 2009

    + Minh Chuc HoMinh Chuc Ho Nominate

    custom

    303 views, 0 favs, 0 embeds more stats

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 303
      • 303 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 0
    • Downloads 22
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?