Added: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-attachments.adoc URL: http://svn.apache.org/viewvc/tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-attachments.adoc?rev=1772522&view=auto ============================================================================== --- tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-attachments.adoc (added) +++ tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-attachments.adoc Sun Dec 4 11:01:40 2016 @@ -0,0 +1,234 @@ += Webservice Attachments +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example webservice-attachments can be browsed at https://github.com/apache/tomee/tree/master/examples/webservice-attachments + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +== AttachmentImpl + + +[source,java] +---- +package org.superbiz.attachment; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.ejb.Stateless; +import javax.jws.WebService; +import javax.xml.ws.BindingType; +import javax.xml.ws.soap.SOAPBinding; +import java.io.IOException; +import java.io.InputStream; + +/** + * This is an EJB 3 style pojo stateless session bean + * Every stateless session bean implementation must be annotated + * using the annotation @Stateless + * This EJB has a single interface: {@link AttachmentWs} a webservice interface. + */ +@Stateless +@WebService( + portName = "AttachmentPort", + serviceName = "AttachmentWsService", + targetNamespace = "http://superbiz.org/wsdl", + endpointInterface = "org.superbiz.attachment.AttachmentWs") +@BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING) +public class AttachmentImpl implements AttachmentWs { + + public String stringFromBytes(byte[] data) { + return new String(data); + } + + public String stringFromDataSource(DataSource source) { + + try { + InputStream inStr = source.getInputStream(); + int size = inStr.available(); + byte[] data = new byte[size]; + inStr.read(data); + inStr.close(); + return new String(data); + } catch (IOException e) { + e.printStackTrace(); + } + return ""; + } + + public String stringFromDataHandler(DataHandler handler) { + + try { + return (String) handler.getContent(); + } catch (IOException e) { + e.printStackTrace(); + } + return ""; + } +} +---- + + +== AttachmentWs + + +[source,java] +---- +package org.superbiz.attachment; + +import javax.activation.DataHandler; +import javax.jws.WebService; + +/** + * This is an EJB 3 webservice interface to send attachments throughout SAOP. + */ +@WebService(targetNamespace = "http://superbiz.org/wsdl") +public interface AttachmentWs { + + public String stringFromBytes(byte[] data); + + // Not working at the moment with SUN saaj provider and CXF + //public String stringFromDataSource(DataSource source); + + public String stringFromDataHandler(DataHandler handler); +} +---- + + +== ejb-jar.xml + + +[source,xml] +---- +<ejb-jar/> +---- + + +== AttachmentTest + + +[source,java] +---- +package org.superbiz.attachment; + +import junit.framework.TestCase; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.mail.util.ByteArrayDataSource; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.xml.namespace.QName; +import javax.xml.ws.BindingProvider; +import javax.xml.ws.Service; +import javax.xml.ws.soap.SOAPBinding; +import java.net.URL; +import java.util.Properties; + +public class AttachmentTest extends TestCase { + + //START SNIPPET: setup + private InitialContext initialContext; + + protected void setUp() throws Exception { + + Properties properties = new Properties(); + properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory"); + properties.setProperty("openejb.embedded.remotable", "true"); + + initialContext = new InitialContext(properties); + } + //END SNIPPET: setup + + /** + * Create a webservice client using wsdl url + * + * @throws Exception + */ + //START SNIPPET: webservice + public void testAttachmentViaWsInterface() throws Exception { + Service service = Service.create( + new URL("http://127.0.0.1:4204/AttachmentImpl?wsdl"), + new QName("http://superbiz.org/wsdl", "AttachmentWsService")); + assertNotNull(service); + + AttachmentWs ws = service.getPort(AttachmentWs.class); + + // retrieve the SOAPBinding + SOAPBinding binding = (SOAPBinding) ((BindingProvider) ws).getBinding(); + binding.setMTOMEnabled(true); + + String request = "tszte...@gmail.com"; + + // Byte array + String response = ws.stringFromBytes(request.getBytes()); + assertEquals(request, response); + + // Data Source + DataSource source = new ByteArrayDataSource(request.getBytes(), "text/plain; charset=UTF-8"); + + // not yet supported ! +// response = ws.stringFromDataSource(source); +// assertEquals(request, response); + + // Data Handler + response = ws.stringFromDataHandler(new DataHandler(source)); + assertEquals(request, response); + } + //END SNIPPET: webservice +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.attachment.AttachmentTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/webservice-attachments +INFO - openejb.base = /Users/dblevins/examples/webservice-attachments +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/webservice-attachments/target/classes +INFO - Beginning load: /Users/dblevins/examples/webservice-attachments/target/classes +INFO - Configuring enterprise application: /Users/dblevins/examples/webservice-attachments/classpath.ear +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean AttachmentImpl: Container(type=STATELESS, id=Default Stateless Container) +INFO - Enterprise application "/Users/dblevins/examples/webservice-attachments/classpath.ear" loaded. +INFO - Assembling app: /Users/dblevins/examples/webservice-attachments/classpath.ear +INFO - Created Ejb(deployment-id=AttachmentImpl, ejb-name=AttachmentImpl, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=AttachmentImpl, ejb-name=AttachmentImpl, container=Default Stateless Container) +INFO - Deployed Application(path=/Users/dblevins/examples/webservice-attachments/classpath.ear) +INFO - Initializing network services +INFO - Creating ServerService(id=httpejbd) +INFO - Creating ServerService(id=cxf) +INFO - Creating ServerService(id=admin) +INFO - Creating ServerService(id=ejbd) +INFO - Creating ServerService(id=ejbds) +INFO - Initializing network services + ** Starting Services ** + NAME IP PORT + httpejbd 127.0.0.1 4204 + admin thread 127.0.0.1 4200 + ejbd 127.0.0.1 4201 + ejbd 127.0.0.1 4203 +------- +Ready! +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.034 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + +
Propchange: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-attachments.adoc ------------------------------------------------------------------------------ svn:executable = * Added: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-handlerchain.adoc URL: http://svn.apache.org/viewvc/tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-handlerchain.adoc?rev=1772522&view=auto ============================================================================== --- tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-handlerchain.adoc (added) +++ tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-handlerchain.adoc Sun Dec 4 11:01:40 2016 @@ -0,0 +1,409 @@ += @WebService handlers with @HandlerChain +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example webservice-handlerchain can be browsed at https://github.com/apache/tomee/tree/master/examples/webservice-handlerchain + + +In this example we see a basic JAX-WS `@WebService` component use a handler chain to alter incoming and outgoing SOAP messages. SOAP Handlers are similar to Servlet Filters or EJB/CDI Interceptors. + +At high level, the steps involved are: + + 1. Create handler(s) implementing `javax.xml.ws.handler.soap.SOAPHandler` + 1. Declare and order them in an xml file via `<handler-chain>` + 1. Associate the xml file with an `@WebService` component via `@HandlerChain` + +== The @HandlerChain + +First we'll start with our plain `@WebService` bean, called `Calculator`, which is annotated with `@HandlerChain` + + +[source,java] +---- +@Singleton +@WebService( + portName = "CalculatorPort", + serviceName = "CalculatorService", + targetNamespace = "http://superbiz.org/wsdl", + endpointInterface = "org.superbiz.calculator.wsh.CalculatorWs") +@HandlerChain(file = "handlers.xml") +public class Calculator implements CalculatorWs { + + public int sum(int add1, int add2) { + return add1 + add2; + } + + public int multiply(int mul1, int mul2) { + return mul1 * mul2; + } +} +---- + + +Here we see `@HandlerChain` pointing to a file called `handlers.xml`. This file could be called anything, but it must be in the same jar and java package as our `Calculator` component. + +== The <handler-chains> file + +Our `Calculator` service is in the package `org.superbiz.calculator.wsh`, which means our handler chain xml file must be at `org/superbiz/calculator/wsh/handlers.xml` in our application's classpath or the file will not be found and no handlers will be used. + +In maven we achieve this by putting our handlers.xml in `src/main/resources` like so: + + - `src/main/resources/org/superbiz/calculator/wsh/handlers.xml` + +With this file we declare and **order** our handler chain. + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"> + <handler-chain> + <handler> + <handler-name>org.superbiz.calculator.wsh.Inflate</handler-name> + <handler-class>org.superbiz.calculator.wsh.Inflate</handler-class> + </handler> + <handler> + <handler-name>org.superbiz.calculator.wsh.Increment</handler-name> + <handler-class>org.superbiz.calculator.wsh.Increment</handler-class> + </handler> + </handler-chain> +</handler-chains> +---- + + +The order as you might suspect is: + + - `Inflate` + - `Increment` + +== The SOAPHandler implementation + +Our `Inflate` handler has the job of monitoring *responses* to the `sum` and `multiply` operations and making them 1000 times better. Manipulation of the message is done by walking the `SOAPBody` and editing the nodes. The `handleMessage` method is invoked for both requests and responses, so it is important to check the `SOAPBody` before attempting to naviage the nodes. + + +[source,java] +---- +import org.w3c.dom.Node; +import javax.xml.namespace.QName; +import javax.xml.soap.SOAPBody; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPMessage; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; +import java.util.Collections; +import java.util.Set; + +public class Inflate implements SOAPHandler<SOAPMessageContext> { + + public boolean handleMessage(SOAPMessageContext mc) { + try { + final SOAPMessage message = mc.getMessage(); + final SOAPBody body = message.getSOAPBody(); + final String localName = body.getFirstChild().getLocalName(); + + if ("sumResponse".equals(localName) || "multiplyResponse".equals(localName)) { + final Node responseNode = body.getFirstChild(); + final Node returnNode = responseNode.getFirstChild(); + final Node intNode = returnNode.getFirstChild(); + + final int value = new Integer(intNode.getNodeValue()); + intNode.setNodeValue(Integer.toString(value * 1000)); + } + + return true; + } catch (SOAPException e) { + return false; + } + } + + public Set<QName> getHeaders() { + return Collections.emptySet(); + } + + public void close(MessageContext mc) { + } + + public boolean handleFault(SOAPMessageContext mc) { + return true; + } +} +---- + + +The `Increment` handler is identical in code and therefore not shown. Instead of multiplying by 1000, it simply adds 1. + +== The TestCase + +We use the JAX-WS API to create a Java client for our `Calculator` web service and use it to invoke both the `sum` and `multiply` operations. Note the clever use of math to assert both the existence and order of our handlers. If `Inflate` and `Increment` were reversed, the responses would be 11000 and 13000 respectively. + + +[source,java] +---- +public class CalculatorTest { + + @BeforeClass + public static void setUp() throws Exception { + Properties properties = new Properties(); + properties.setProperty("openejb.embedded.remotable", "true"); + EJBContainer.createEJBContainer(properties); + } + + @Test + public void testCalculatorViaWsInterface() throws Exception { + final Service calculatorService = Service.create( + new URL("http://127.0.0.1:4204/Calculator?wsdl"), + new QName("http://superbiz.org/wsdl", "CalculatorService")); + + assertNotNull(calculatorService); + + final CalculatorWs calculator = calculatorService.getPort(CalculatorWs.class); + + // we expect our answers to come back 1000 times better, plus one! + assertEquals(10001, calculator.sum(4, 6)); + assertEquals(12001, calculator.multiply(3, 4)); + } +} +---- + + +== Running the example + +Simply run `mvn clean install` and you should see output similar to the following: + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.calculator.wsh.CalculatorTest +INFO - openejb.home = /Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers +INFO - openejb.base = /Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Cannot find the configuration file [conf/openejb.xml]. Will attempt to create one for the beans deployed. +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Creating TransactionManager(id=Default Transaction Manager) +INFO - Creating SecurityService(id=Default Security Service) +INFO - Beginning load: /Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers/target/test-classes +INFO - Beginning load: /Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers/target/classes +INFO - Configuring enterprise application: /Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers +INFO - Auto-deploying ejb Calculator: EjbDeployment(deployment-id=Calculator) +INFO - Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container) +INFO - Auto-creating a container for bean Calculator: Container(type=SINGLETON, id=Default Singleton Container) +INFO - Creating Container(id=Default Singleton Container) +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean org.superbiz.calculator.wsh.CalculatorTest: Container(type=MANAGED, id=Default Managed Container) +INFO - Creating Container(id=Default Managed Container) +INFO - Enterprise application "/Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers" loaded. +INFO - Assembling app: /Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers +INFO - Created Ejb(deployment-id=Calculator, ejb-name=Calculator, container=Default Singleton Container) +INFO - Started Ejb(deployment-id=Calculator, ejb-name=Calculator, container=Default Singleton Container) +INFO - Deployed Application(path=/Users/dblevins/work/all/trunk/openejb/examples/webservice-handlers) +INFO - Initializing network services +INFO - Creating ServerService(id=httpejbd) +INFO - Creating ServerService(id=cxf) +INFO - Creating ServerService(id=admin) +INFO - Creating ServerService(id=ejbd) +INFO - Creating ServerService(id=ejbds) +INFO - Initializing network services +INFO - ** Starting Services ** +INFO - NAME IP PORT +INFO - httpejbd 127.0.0.1 4204 +INFO - Creating Service {http://superbiz.org/wsdl}CalculatorService from class org.superbiz.calculator.wsh.CalculatorWs +INFO - Setting the server's publish address to be http://nopath:80 +INFO - Webservice(wsdl=http://127.0.0.1:4204/Calculator, qname={http://superbiz.org/wsdl}CalculatorService) --> Ejb(id=Calculator) +INFO - admin thread 127.0.0.1 4200 +INFO - ejbd 127.0.0.1 4201 +INFO - ejbd 127.0.0.1 4203 +INFO - ------- +INFO - Ready! +INFO - Creating Service {http://superbiz.org/wsdl}CalculatorService from WSDL: http://127.0.0.1:4204/Calculator?wsdl +INFO - Creating Service {http://superbiz.org/wsdl}CalculatorService from WSDL: http://127.0.0.1:4204/Calculator?wsdl +INFO - Default SAAJ universe not set +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.783 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + + +== Inspecting the messages + +The above would generate the following messages. + +=== Calculator wsdl + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + name="CalculatorService" targetNamespace="http://superbiz.org/wsdl" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:tns="http://superbiz.org/wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <wsdl:types> + <xsd:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" + targetNamespace="http://superbiz.org/wsdl" xmlns:tns="http://superbiz.org/wsdl" + xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <xsd:element name="multiply" type="tns:multiply"/> + <xsd:complexType name="multiply"> + <xsd:sequence> + <xsd:element name="arg0" type="xsd:int"/> + <xsd:element name="arg1" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="multiplyResponse" type="tns:multiplyResponse"/> + <xsd:complexType name="multiplyResponse"> + <xsd:sequence> + <xsd:element name="return" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="sum" type="tns:sum"/> + <xsd:complexType name="sum"> + <xsd:sequence> + <xsd:element name="arg0" type="xsd:int"/> + <xsd:element name="arg1" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="sumResponse" type="tns:sumResponse"/> + <xsd:complexType name="sumResponse"> + <xsd:sequence> + <xsd:element name="return" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> + </xsd:schema> + </wsdl:types> + <wsdl:message name="multiplyResponse"> + <wsdl:part element="tns:multiplyResponse" name="parameters"> + </wsdl:part> + </wsdl:message> + <wsdl:message name="sumResponse"> + <wsdl:part element="tns:sumResponse" name="parameters"> + </wsdl:part> + </wsdl:message> + <wsdl:message name="sum"> + <wsdl:part element="tns:sum" name="parameters"> + </wsdl:part> + </wsdl:message> + <wsdl:message name="multiply"> + <wsdl:part element="tns:multiply" name="parameters"> + </wsdl:part> + </wsdl:message> + <wsdl:portType name="CalculatorWs"> + <wsdl:operation name="multiply"> + <wsdl:input message="tns:multiply" name="multiply"> + </wsdl:input> + <wsdl:output message="tns:multiplyResponse" name="multiplyResponse"> + </wsdl:output> + </wsdl:operation> + <wsdl:operation name="sum"> + <wsdl:input message="tns:sum" name="sum"> + </wsdl:input> + <wsdl:output message="tns:sumResponse" name="sumResponse"> + </wsdl:output> + </wsdl:operation> + </wsdl:portType> + <wsdl:binding name="CalculatorServiceSoapBinding" type="tns:CalculatorWs"> + <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <wsdl:operation name="multiply"> + <soap:operation soapAction="" style="document"/> + <wsdl:input name="multiply"> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output name="multiplyResponse"> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + <wsdl:operation name="sum"> + <soap:operation soapAction="" style="document"/> + <wsdl:input name="sum"> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output name="sumResponse"> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:service name="CalculatorService"> + <wsdl:port binding="tns:CalculatorServiceSoapBinding" name="CalculatorPort"> + <soap:address location="http://127.0.0.1:4204/Calculator?wsdl"/> + </wsdl:port> + </wsdl:service> +</wsdl:definitions> +---- + + +=== SOAP sum and sumResponse + +Request: + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> + <soap:Body> + <ns1:sum xmlns:ns1="http://superbiz.org/wsdl"> + <arg0>4</arg0> + <arg1>6</arg1> + </ns1:sum> + </soap:Body> +</soap:Envelope> +---- + + +Response: + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> + <soap:Body> + <ns1:sumResponse xmlns:ns1="http://superbiz.org/wsdl"> + <return>10001</return> + </ns1:sumResponse> + </soap:Body> +</soap:Envelope> +---- + + +=== SOAP multiply and multiplyResponse + +Request: + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> + <soap:Body> + <ns1:multiply xmlns:ns1="http://superbiz.org/wsdl"> + <arg0>3</arg0> + <arg1>4</arg1> + </ns1:multiply> + </soap:Body> +</soap:Envelope> +---- + + +Response: + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> + <soap:Body> + <ns1:multiplyResponse xmlns:ns1="http://superbiz.org/wsdl"> + <return>12001</return> + </ns1:multiplyResponse> + </soap:Body> +</soap:Envelope> +---- + Propchange: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-handlerchain.adoc ------------------------------------------------------------------------------ svn:executable = * Added: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-holder.adoc URL: http://svn.apache.org/viewvc/tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-holder.adoc?rev=1772522&view=auto ============================================================================== --- tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-holder.adoc (added) +++ tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-holder.adoc Sun Dec 4 11:01:40 2016 @@ -0,0 +1,201 @@ += @WebService OUT params via javax.xml.ws.Holder +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example webservice-holder can be browsed at https://github.com/apache/tomee/tree/master/examples/webservice-holder + + +With SOAP it is possible to return multiple values in a single request. This is impossible in Java as a method can only return one object. + +JAX-WS solves this problem with the concept of Holders. A `javax.xml.ws.Holder` is a simple wrapper object that can be passed into the `@WebService` method as a parameter. The application sets the value of the holder during the request and the server will send the value back as an OUT parameter. + +== Using @WebParam and javax.xml.ws.Holder + +The `@WebParam` annotation allows us to declare the `sum` and `multiply` Holders as `WebParam.Mode.OUT` parameters. As mentioned, these holders are simply empty buckets the application can fill in with data to have sent to the client. The server will pass them in uninitialized. + + +[source,java] +---- +@Stateless +@WebService( + portName = "CalculatorPort", + serviceName = "CalculatorService", + targetNamespace = "http://superbiz.org/wsdl", + endpointInterface = "org.superbiz.ws.out.CalculatorWs") +public class Calculator implements CalculatorWs { + + public void sumAndMultiply(int a, int b, + @WebParam(name = "sum", mode = WebParam.Mode.OUT) Holder<Integer> sum, + @WebParam(name = "multiply", mode = WebParam.Mode.OUT) Holder<Integer> multiply) { + sum.value = a + b; + multiply.value = a * b; + } +} +---- + + +If the Holders were specified as `WebParam.Mode.INOUT` params, then the client could use them to send data and the application as well. The `Holder` instances would then be initialized with the data from the client request. The application could check the data before eventually overriting it with the response values. + +== The WSDL + +The above JAX-WS `@WebService` component results in the folliwing WSDL that will be created automatically. Note the `sumAndMultiplyResponse` complext type returns two elements. These match the `@WebParam` declarations and our two `Holder<Integer>` params. + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + name="CalculatorService" + targetNamespace="http://superbiz.org/wsdl" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:tns="http://superbiz.org/wsdl" + xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <wsdl:types> + <xsd:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" + targetNamespace="http://superbiz.org/wsdl" + xmlns:tns="http://superbiz.org/wsdl" + xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <xsd:element name="sumAndMultiply" type="tns:sumAndMultiply"/> + <xsd:complexType name="sumAndMultiply"> + <xsd:sequence> + <xsd:element name="arg0" type="xsd:int"/> + <xsd:element name="arg1" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="sumAndMultiplyResponse" type="tns:sumAndMultiplyResponse"/> + <xsd:complexType name="sumAndMultiplyResponse"> + <xsd:sequence> + <xsd:element minOccurs="0" name="sum" type="xsd:int"/> + <xsd:element minOccurs="0" name="multiply" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> + </xsd:schema> + </wsdl:types> + <wsdl:message name="sumAndMultiplyResponse"> + <wsdl:part element="tns:sumAndMultiplyResponse" name="parameters"/> + </wsdl:message> + <wsdl:message name="sumAndMultiply"> + <wsdl:part element="tns:sumAndMultiply" name="parameters"/> + </wsdl:message> + <wsdl:portType name="CalculatorWs"> + <wsdl:operation name="sumAndMultiply"> + <wsdl:input message="tns:sumAndMultiply" name="sumAndMultiply"/> + <wsdl:output message="tns:sumAndMultiplyResponse" name="sumAndMultiplyResponse"/> + </wsdl:operation> + </wsdl:portType> + <wsdl:binding name="CalculatorServiceSoapBinding" type="tns:CalculatorWs"> + <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <wsdl:operation name="sumAndMultiply"> + <soap:operation soapAction="" style="document"/> + <wsdl:input name="sumAndMultiply"> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output name="sumAndMultiplyResponse"> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:service name="CalculatorService"> + <wsdl:port binding="tns:CalculatorServiceSoapBinding" name="CalculatorPort"> + <soap:address location="http://127.0.0.1:4204/Calculator?wsdl"/> + </wsdl:port> + </wsdl:service> +</wsdl:definitions> +---- + + +== Testing the OUT params + +Here we see a JAX-WS client executing the `sumAndMultiply` operation. Two empty `Holder` instances are created and passed in as parameters. The data from the `sumAndMultiplyResponse` is placed in the `Holder` instances and is then available to the client after the operation completes. + +The holders themselves are not actually sent in the request unless they are configured as INOUT params via WebParam.Mode.INOUT on `@WebParam` + + +[source,java] +---- +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.ejb.embeddable.EJBContainer; +import javax.xml.namespace.QName; +import javax.xml.ws.Holder; +import javax.xml.ws.Service; +import java.net.URL; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class CalculatorTest { + + @BeforeClass + public static void setUp() throws Exception { + Properties properties = new Properties(); + properties.setProperty("openejb.embedded.remotable", "true"); + //properties.setProperty("httpejbd.print", "true"); + //properties.setProperty("httpejbd.indent.xml", "true"); + EJBContainer.createEJBContainer(properties); + } + + @Test + public void outParams() throws Exception { + final Service calculatorService = Service.create( + new URL("http://127.0.0.1:4204/Calculator?wsdl"), + new QName("http://superbiz.org/wsdl", "CalculatorService")); + + assertNotNull(calculatorService); + + final CalculatorWs calculator = calculatorService.getPort(CalculatorWs.class); + + final Holder<Integer> sum = new Holder<Integer>(); + final Holder<Integer> multiply = new Holder<Integer>(); + + calculator.sumAndMultiply(4, 6, sum, multiply); + + assertEquals(10, (int) sum.value); + assertEquals(24, (int) multiply.value); + } +} +---- + + + +== Inspecting the messages + +The above execution results in the following SOAP message. + +=== SOAP sumAndMultiply <small>client request</small> + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> + <soap:Body> + <ns1:sumAndMultiply xmlns:ns1="http://superbiz.org/wsdl"> + <arg0>4</arg0> + <arg1>6</arg1> + </ns1:sumAndMultiply> + </soap:Body> +</soap:Envelope> +---- + + +=== SOAP sumAndMultiplyResponse <small>server response</small> + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> + <soap:Body> + <ns1:sumAndMultiplyResponse xmlns:ns1="http://superbiz.org/wsdl"> + <sum>10</sum> + <multiply>24</multiply> + </ns1:sumAndMultiplyResponse> + </soap:Body> +</soap:Envelope> +---- + Propchange: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-holder.adoc ------------------------------------------------------------------------------ svn:executable = * Added: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-inheritance.adoc URL: http://svn.apache.org/viewvc/tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-inheritance.adoc?rev=1772522&view=auto ============================================================================== --- tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-inheritance.adoc (added) +++ tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-inheritance.adoc Sun Dec 4 11:01:40 2016 @@ -0,0 +1,476 @@ += Webservice Inheritance +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example webservice-inheritance can be browsed at https://github.com/apache/tomee/tree/master/examples/webservice-inheritance + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +== Item + + +[source,java] +---- +package org.superbiz.inheritance; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import java.io.Serializable; + +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +public class Item implements Serializable { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String brand; + private String itemName; + private double price; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } +} +---- + + +== Tower + + +[source,java] +---- +package org.superbiz.inheritance; + +import javax.persistence.Entity; + +@Entity +public class Tower extends Item { + private Fit fit; + private String tubing; + + public static enum Fit { + Custom, Exact, Universal + } + + public Fit getFit() { + return fit; + } + + public void setFit(Fit fit) { + this.fit = fit; + } + + public String getTubing() { + return tubing; + } + + public void setTubing(String tubing) { + this.tubing = tubing; + } + + ; +} +---- + + +== Wakeboard + + +[source,java] +---- +package org.superbiz.inheritance; + +import javax.persistence.Entity; + +@Entity +public class Wakeboard extends Wearable { +} +---- + + +== WakeboardBinding + + +[source,java] +---- +package org.superbiz.inheritance; + +import javax.persistence.Entity; + +@Entity +public class WakeboardBinding extends Wearable { +} +---- + + +== WakeRiderImpl + + +[source,java] +---- +package org.superbiz.inheritance; + +import javax.ejb.Stateless; +import javax.jws.WebService; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.PersistenceContextType; +import javax.persistence.Query; +import java.util.List; + +/** + * This is an EJB 3 style pojo stateless session bean Every stateless session + * bean implementation must be annotated using the annotation @Stateless This + * EJB has a single interface: {@link WakeRiderWs} a webservice interface. + */ +@Stateless +@WebService( + portName = "InheritancePort", + serviceName = "InheritanceWsService", + targetNamespace = "http://superbiz.org/wsdl", + endpointInterface = "org.superbiz.inheritance.WakeRiderWs") +public class WakeRiderImpl implements WakeRiderWs { + + @PersistenceContext(unitName = "wakeboard-unit", type = PersistenceContextType.TRANSACTION) + private EntityManager entityManager; + + public void addItem(Item item) throws Exception { + entityManager.persist(item); + } + + public void deleteMovie(Item item) throws Exception { + entityManager.remove(item); + } + + public List<Item> getItems() throws Exception { + Query query = entityManager.createQuery("SELECT i FROM Item i"); + List<Item> items = query.getResultList(); + return items; + } +} +---- + + +== WakeRiderWs + + +[source,java] +---- +package org.superbiz.inheritance; + +import javax.jws.WebService; +import javax.xml.bind.annotation.XmlSeeAlso; +import java.util.List; + +/** + * This is an EJB 3 webservice interface that uses inheritance. + */ +@WebService(targetNamespace = "http://superbiz.org/wsdl") +@XmlSeeAlso({Wakeboard.class, WakeboardBinding.class, Tower.class}) +public interface WakeRiderWs { + public void addItem(Item item) throws Exception; + + public void deleteMovie(Item item) throws Exception; + + public List<Item> getItems() throws Exception; +} +---- + + +== Wearable + + +[source,java] +---- +package org.superbiz.inheritance; + +import javax.persistence.MappedSuperclass; + +@MappedSuperclass +public abstract class Wearable extends Item { + protected String size; + + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } +} +---- + + +== ejb-jar.xml + + +[source,xml] +---- +<ejb-jar/> +---- + + + +== persistence.xml + + +[source,xml] +---- +<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> + + <persistence-unit name="wakeboard-unit"> + + <jta-data-source>wakeBoardDatabase</jta-data-source> + <non-jta-data-source>wakeBoardDatabaseUnmanaged</non-jta-data-source> + + <class>org.superbiz.inheritance.Item</class> + <class>org.superbiz.inheritance.Tower</class> + <class>org.superbiz.inheritance.Wakeboard</class> + <class>org.superbiz.inheritance.WakeboardBinding</class> + <class>org.superbiz.inheritance.Wearable</class> + + <properties> + <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> + </properties> + + </persistence-unit> +</persistence> +---- + + +== InheritanceTest + + +[source,java] +---- +package org.superbiz.inheritance; + +import junit.framework.TestCase; +import org.superbiz.inheritance.Tower.Fit; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import java.net.URL; +import java.util.List; +import java.util.Properties; + +public class InheritanceTest extends TestCase { + + //START SNIPPET: setup + private InitialContext initialContext; + + protected void setUp() throws Exception { + + Properties p = new Properties(); + p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory"); + p.put("wakeBoardDatabase", "new://Resource?type=DataSource"); + p.put("wakeBoardDatabase.JdbcDriver", "org.hsqldb.jdbcDriver"); + p.put("wakeBoardDatabase.JdbcUrl", "jdbc:hsqldb:mem:wakeBoarddb"); + + p.put("wakeBoardDatabaseUnmanaged", "new://Resource?type=DataSource"); + p.put("wakeBoardDatabaseUnmanaged.JdbcDriver", "org.hsqldb.jdbcDriver"); + p.put("wakeBoardDatabaseUnmanaged.JdbcUrl", "jdbc:hsqldb:mem:wakeBoarddb"); + p.put("wakeBoardDatabaseUnmanaged.JtaManaged", "false"); + + p.put("openejb.embedded.remotable", "true"); + + initialContext = new InitialContext(p); + } + //END SNIPPET: setup + + /** + * Create a webservice client using wsdl url + * + * @throws Exception + */ + //START SNIPPET: webservice + public void testInheritanceViaWsInterface() throws Exception { + Service service = Service.create( + new URL("http://127.0.0.1:4204/WakeRiderImpl?wsdl"), + new QName("http://superbiz.org/wsdl", "InheritanceWsService")); + assertNotNull(service); + + WakeRiderWs ws = service.getPort(WakeRiderWs.class); + + Tower tower = createTower(); + Item item = createItem(); + Wakeboard wakeBoard = createWakeBoard(); + WakeboardBinding wakeBoardbinding = createWakeboardBinding(); + + ws.addItem(tower); + ws.addItem(item); + ws.addItem(wakeBoard); + ws.addItem(wakeBoardbinding); + + + List<Item> returnedItems = ws.getItems(); + + assertEquals("testInheritanceViaWsInterface, nb Items", 4, returnedItems.size()); + + //check tower + assertEquals("testInheritanceViaWsInterface, first Item", returnedItems.get(0).getClass(), Tower.class); + tower = (Tower) returnedItems.get(0); + assertEquals("testInheritanceViaWsInterface, first Item", tower.getBrand(), "Tower brand"); + assertEquals("testInheritanceViaWsInterface, first Item", tower.getFit().ordinal(), Fit.Custom.ordinal()); + assertEquals("testInheritanceViaWsInterface, first Item", tower.getItemName(), "Tower item name"); + assertEquals("testInheritanceViaWsInterface, first Item", tower.getPrice(), 1.0d); + assertEquals("testInheritanceViaWsInterface, first Item", tower.getTubing(), "Tower tubing"); + + //check item + assertEquals("testInheritanceViaWsInterface, second Item", returnedItems.get(1).getClass(), Item.class); + item = (Item) returnedItems.get(1); + assertEquals("testInheritanceViaWsInterface, second Item", item.getBrand(), "Item brand"); + assertEquals("testInheritanceViaWsInterface, second Item", item.getItemName(), "Item name"); + assertEquals("testInheritanceViaWsInterface, second Item", item.getPrice(), 2.0d); + + //check wakeboard + assertEquals("testInheritanceViaWsInterface, third Item", returnedItems.get(2).getClass(), Wakeboard.class); + wakeBoard = (Wakeboard) returnedItems.get(2); + assertEquals("testInheritanceViaWsInterface, third Item", wakeBoard.getBrand(), "Wakeboard brand"); + assertEquals("testInheritanceViaWsInterface, third Item", wakeBoard.getItemName(), "Wakeboard item name"); + assertEquals("testInheritanceViaWsInterface, third Item", wakeBoard.getPrice(), 3.0d); + assertEquals("testInheritanceViaWsInterface, third Item", wakeBoard.getSize(), "WakeBoard size"); + + //check wakeboardbinding + assertEquals("testInheritanceViaWsInterface, fourth Item", returnedItems.get(3).getClass(), WakeboardBinding.class); + wakeBoardbinding = (WakeboardBinding) returnedItems.get(3); + assertEquals("testInheritanceViaWsInterface, fourth Item", wakeBoardbinding.getBrand(), "Wakeboardbinding brand"); + assertEquals("testInheritanceViaWsInterface, fourth Item", wakeBoardbinding.getItemName(), "Wakeboardbinding item name"); + assertEquals("testInheritanceViaWsInterface, fourth Item", wakeBoardbinding.getPrice(), 4.0d); + assertEquals("testInheritanceViaWsInterface, fourth Item", wakeBoardbinding.getSize(), "WakeBoardbinding size"); + } + //END SNIPPET: webservice + + private Tower createTower() { + Tower tower = new Tower(); + tower.setBrand("Tower brand"); + tower.setFit(Fit.Custom); + tower.setItemName("Tower item name"); + tower.setPrice(1.0f); + tower.setTubing("Tower tubing"); + return tower; + } + + private Item createItem() { + Item item = new Item(); + item.setBrand("Item brand"); + item.setItemName("Item name"); + item.setPrice(2.0f); + return item; + } + + private Wakeboard createWakeBoard() { + Wakeboard wakeBoard = new Wakeboard(); + wakeBoard.setBrand("Wakeboard brand"); + wakeBoard.setItemName("Wakeboard item name"); + wakeBoard.setPrice(3.0f); + wakeBoard.setSize("WakeBoard size"); + return wakeBoard; + } + + private WakeboardBinding createWakeboardBinding() { + WakeboardBinding wakeBoardBinding = new WakeboardBinding(); + wakeBoardBinding.setBrand("Wakeboardbinding brand"); + wakeBoardBinding.setItemName("Wakeboardbinding item name"); + wakeBoardBinding.setPrice(4.0f); + wakeBoardBinding.setSize("WakeBoardbinding size"); + return wakeBoardBinding; + } +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.inheritance.InheritanceTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/webservice-inheritance +INFO - openejb.base = /Users/dblevins/examples/webservice-inheritance +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Configuring Service(id=wakeBoardDatabaseUnmanaged, type=Resource, provider-id=Default JDBC Database) +INFO - Configuring Service(id=wakeBoardDatabase, type=Resource, provider-id=Default JDBC Database) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/webservice-inheritance/target/classes +INFO - Beginning load: /Users/dblevins/examples/webservice-inheritance/target/classes +INFO - Configuring enterprise application: /Users/dblevins/examples/webservice-inheritance/classpath.ear +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean WakeRiderImpl: Container(type=STATELESS, id=Default Stateless Container) +INFO - Configuring PersistenceUnit(name=wakeboard-unit) +INFO - Enterprise application "/Users/dblevins/examples/webservice-inheritance/classpath.ear" loaded. +INFO - Assembling app: /Users/dblevins/examples/webservice-inheritance/classpath.ear +INFO - PersistenceUnit(name=wakeboard-unit, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 396ms +INFO - Created Ejb(deployment-id=WakeRiderImpl, ejb-name=WakeRiderImpl, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=WakeRiderImpl, ejb-name=WakeRiderImpl, container=Default Stateless Container) +INFO - Deployed Application(path=/Users/dblevins/examples/webservice-inheritance/classpath.ear) +INFO - Initializing network services +INFO - Creating ServerService(id=httpejbd) +INFO - Creating ServerService(id=cxf) +INFO - Creating ServerService(id=admin) +INFO - Creating ServerService(id=ejbd) +INFO - Creating ServerService(id=ejbds) +INFO - Initializing network services + ** Starting Services ** + NAME IP PORT + httpejbd 127.0.0.1 4204 + admin thread 127.0.0.1 4200 + ejbd 127.0.0.1 4201 + ejbd 127.0.0.1 4203 +------- +Ready! +WARN - Found no persistent property in "org.superbiz.inheritance.WakeboardBinding" +WARN - Found no persistent property in "org.superbiz.inheritance.Wakeboard" +WARN - Found no persistent property in "org.superbiz.inheritance.WakeboardBinding" +WARN - Found no persistent property in "org.superbiz.inheritance.Wakeboard" +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.442 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + + Propchange: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-inheritance.adoc ------------------------------------------------------------------------------ svn:executable = * Added: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-security.adoc URL: http://svn.apache.org/viewvc/tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-security.adoc?rev=1772522&view=auto ============================================================================== --- tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-security.adoc (added) +++ tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-security.adoc Sun Dec 4 11:01:40 2016 @@ -0,0 +1,233 @@ += Webservice Security +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example webservice-security can be browsed at https://github.com/apache/tomee/tree/master/examples/webservice-security + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +== CalculatorImpl + + +[source,java] +---- +package org.superbiz.calculator; + +import javax.annotation.security.DeclareRoles; +import javax.annotation.security.RolesAllowed; +import javax.ejb.Stateless; +import javax.jws.WebService; + +/** + * This is an EJB 3 style pojo stateless session bean + * Every stateless session bean implementation must be annotated + * using the annotation @Stateless + * This EJB has a single interface: CalculatorWs a webservice interface. + */ +//START SNIPPET: code +@DeclareRoles(value = {"Administrator"}) +@Stateless +@WebService( + portName = "CalculatorPort", + serviceName = "CalculatorWsService", + targetNamespace = "http://superbiz.org/wsdl", + endpointInterface = "org.superbiz.calculator.CalculatorWs") +public class CalculatorImpl implements CalculatorWs, CalculatorRemote { + + @RolesAllowed(value = {"Administrator"}) + public int sum(int add1, int add2) { + return add1 + add2; + } + + @RolesAllowed(value = {"Administrator"}) + public int multiply(int mul1, int mul2) { + return mul1 * mul2; + } +} +---- + + +== CalculatorRemote + + +[source,java] +---- +package org.superbiz.calculator; + +import javax.ejb.Remote; + +@Remote +public interface CalculatorRemote { + + public int sum(int add1, int add2); + + public int multiply(int mul1, int mul2); +} +---- + + +== CalculatorWs + + +[source,java] +---- +package org.superbiz.calculator; + +import javax.jws.WebService; + +//END SNIPPET: code + +/** + * This is an EJB 3 webservice interface + * A webservice interface must be annotated with the @Local + * annotation. + */ +//START SNIPPET: code +@WebService(targetNamespace = "http://superbiz.org/wsdl") +public interface CalculatorWs { + + public int sum(int add1, int add2); + + public int multiply(int mul1, int mul2); +} +---- + + +== ejb-jar.xml + + +[source,xml] +---- +<ejb-jar/> +---- + + +== openejb-jar.xml + + +[source,xml] +---- +<openejb-jar xmlns="http://tomee.apache.org/xml/ns/openejb-jar-2.2"> + <enterprise-beans> + <session> + <ejb-name>CalculatorImpl</ejb-name> + <web-service-security> + <security-realm-name/> + <transport-guarantee>NONE</transport-guarantee> + <auth-method>BASIC</auth-method> + </web-service-security> + </session> + </enterprise-beans> +</openejb-jar> +---- + + +== CalculatorTest + + +[source,java] +---- +package org.superbiz.calculator; + +import junit.framework.TestCase; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.xml.namespace.QName; +import javax.xml.ws.BindingProvider; +import javax.xml.ws.Service; +import java.net.URL; +import java.util.Properties; + +public class CalculatorTest extends TestCase { + + //START SNIPPET: setup + private InitialContext initialContext; + + protected void setUp() throws Exception { + Properties properties = new Properties(); + properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory"); + properties.setProperty("openejb.embedded.remotable", "true"); + + initialContext = new InitialContext(properties); + } + //END SNIPPET: setup + + /** + * Create a webservice client using wsdl url + * + * @throws Exception + */ + //START SNIPPET: webservice + public void testCalculatorViaWsInterface() throws Exception { + URL url = new URL("http://127.0.0.1:4204/CalculatorImpl?wsdl"); + QName calcServiceQName = new QName("http://superbiz.org/wsdl", "CalculatorWsService"); + Service calcService = Service.create(url, calcServiceQName); + assertNotNull(calcService); + + CalculatorWs calc = calcService.getPort(CalculatorWs.class); + ((BindingProvider) calc).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "jane"); + ((BindingProvider) calc).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "waterfall"); + assertEquals(10, calc.sum(4, 6)); + assertEquals(12, calc.multiply(3, 4)); + } + //END SNIPPET: webservice +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.calculator.CalculatorTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/webservice-security +INFO - openejb.base = /Users/dblevins/examples/webservice-security +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/webservice-security/target/classes +INFO - Beginning load: /Users/dblevins/examples/webservice-security/target/classes +INFO - Configuring enterprise application: /Users/dblevins/examples/webservice-security/classpath.ear +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean CalculatorImpl: Container(type=STATELESS, id=Default Stateless Container) +INFO - Enterprise application "/Users/dblevins/examples/webservice-security/classpath.ear" loaded. +INFO - Assembling app: /Users/dblevins/examples/webservice-security/classpath.ear +INFO - Jndi(name=CalculatorImplRemote) --> Ejb(deployment-id=CalculatorImpl) +INFO - Jndi(name=global/classpath.ear/webservice-security/CalculatorImpl!org.superbiz.calculator.CalculatorRemote) --> Ejb(deployment-id=CalculatorImpl) +INFO - Jndi(name=global/classpath.ear/webservice-security/CalculatorImpl) --> Ejb(deployment-id=CalculatorImpl) +INFO - Created Ejb(deployment-id=CalculatorImpl, ejb-name=CalculatorImpl, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=CalculatorImpl, ejb-name=CalculatorImpl, container=Default Stateless Container) +INFO - Deployed Application(path=/Users/dblevins/examples/webservice-security/classpath.ear) +INFO - Initializing network services +INFO - Creating ServerService(id=httpejbd) +INFO - Creating ServerService(id=cxf) +INFO - Creating ServerService(id=admin) +INFO - Creating ServerService(id=ejbd) +INFO - Creating ServerService(id=ejbds) +INFO - Initializing network services + ** Starting Services ** + NAME IP PORT + httpejbd 127.0.0.1 4204 + admin thread 127.0.0.1 4200 + ejbd 127.0.0.1 4201 + ejbd 127.0.0.1 4203 +------- +Ready! +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.481 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + + Propchange: tomee/site/trunk/generators/site-tomee-ng/src/main/jbake/content/examples/webservice-security.adoc ------------------------------------------------------------------------------ svn:executable = *