{"id":16998465,"url":"https://github.com/amusarra/liferay-72-soap-client-examples","last_synced_at":"2025-03-22T07:24:09.233Z","repository":{"id":144585931,"uuid":"206417948","full_name":"amusarra/liferay-72-soap-client-examples","owner":"amusarra","description":"In this project I want to show you how to build a SOAP JAX-WS (Java API for XML  Web Services) client using the Liferay infrastructure. Let's start with a  concrete example.","archived":false,"fork":false,"pushed_at":"2021-06-24T08:14:33.000Z","size":4004,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-27T07:42:06.620Z","etag":null,"topics":["jax-ws","liferay","liferay-portal","mutual-authentication","soap","ssl-tls","webservice"],"latest_commit_sha":null,"homepage":"http://bit.ly/2lA0ukT","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amusarra.png","metadata":{"files":{"readme":"README.markdown","changelog":"CHANGELOG.markdown","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-04T21:31:21.000Z","updated_at":"2022-11-23T11:27:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"1688ae1a-918d-4fbc-8c7d-6a2541247ee4","html_url":"https://github.com/amusarra/liferay-72-soap-client-examples","commit_stats":{"total_commits":42,"total_committers":1,"mean_commits":42.0,"dds":0.0,"last_synced_commit":"1eb8b0152d3a2628d7c34cca251ef4937972730f"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amusarra%2Fliferay-72-soap-client-examples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amusarra%2Fliferay-72-soap-client-examples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amusarra%2Fliferay-72-soap-client-examples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amusarra%2Fliferay-72-soap-client-examples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amusarra","download_url":"https://codeload.github.com/amusarra/liferay-72-soap-client-examples/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244921068,"owners_count":20532166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jax-ws","liferay","liferay-portal","mutual-authentication","soap","ssl-tls","webservice"],"created_at":"2024-10-14T04:05:20.854Z","updated_at":"2025-03-22T07:24:09.197Z","avatar_url":"https://github.com/amusarra.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Liferay 7.3 SOAP Client Examples\n\n[![Antonio Musarra's Blog](https://img.shields.io/badge/maintainer-Antonio_Musarra's_Blog-purple.svg?colorB=6e60cc)](https://www.dontesta.it)\n[![Build Status](https://travis-ci.com/amusarra/liferay-72-soap-client-examples.svg?branch=master)](https://travis-ci.com/amusarra/liferay-72-soap-client-examples)\n[![Twitter Follow](https://img.shields.io/twitter/follow/antonio_musarra.svg?style=social\u0026label=%40antonio_musarra%20on%20Twitter\u0026style=plastic)](https://twitter.com/antonio_musarra)\n\nAt the 2016 Liferay Symposium (Italy) I presented the topic: [How to develop SOAP \nand REST services in JAX-WS and JAX-RS standard on Liferay](https://www.slideshare.net/amusarra/jaxws-e-jaxrs). During the presentation I illustrated how to expose both REST (Representational State Transfer) and SOAP (Simple Object Access Protocol) services for each application using the [Liferay Extender](https://portal.liferay.dev/docs/7-0/tutorials/-/knowledge_base/t/jax-ws-and-jax-rs).\n\nIn this project I want to show you how to build a SOAP JAX-WS (Java API for XML \nWeb Services) client and [JAX-WS Handler](http://bit.ly/2Q9ibGN) using the Liferay \ninfrastructure. Let's start with a concrete example. The current release of the \nproject implemented and tested on **Liferay 7.3 Community Edition GA6**.\nI recommend that you read the project change logs.\n\n**It is important that you know that the current version of the project requires \nthe version 11 of Java JDK.**\n\nThe project code is still valid for the 7.0 and 7.1 versions of Liferay. \nBefore trying the project on Liferay 7.0, I recommend reading \nthis [LPS – Supplied JAX-WS implementation not working](https://issues.liferay.com/browse/LPS-67253)([CLOSED]) \nand [The Configuring Endpoints And Extenders Programmatically does not work](https://issues.liferay.com/browse/LPS-101642)([OPEN])\n\nLet’s consider the SOAP Calculator service whose [WSDL](http://www.dneonline.com/calculator.asmx) \n(Web Services Description Language) descriptor is available at the following \naddress http://www.dneonline.com/calculator.asmx which exposes the four arithmetic \noperations between two integers.\n\nThis project is related to article [How to implement a SOAP client using JAX-WS Liferay infrastructure](http://bit.ly/2lA0ukT) \npublished on [Antonio Musarra's Blog](https://www.dontesta.it) which I \nrecommend you read.\n\n## 1. Quick Start\nFollow the procedure below to try out the project immediately. You need to \nreplace or set the variable __$LIFERAY_HOME__ with the installation directory \nof your Liferay instance.\n\n```bash\n$ git clone https://github.com/amusarra/liferay-72-soap-client-examples.git\n$ cd liferay-72-soap-client-examples/\n$ echo \"liferay.workspace.home.dir=$LIFERAY_HOME\" \u003e gradle-local.properties\n$ ./gradlew clean deploy\n```\n\n**Console 1** - Clone, build and debloy\n\nThe topics covered by the project are:\n\n1. JAX-WS Client\n2. JAX-WS Client with the SSL/TLS Mutual Authentication supports\n3. JAX-WS Service End Point \n4. JAX-WS Handler\n\nThe table shows the list of modules that are available within this project.\n\n| Module                                            | Description                                                  |\n| ------------------------------------------------- | ------------------------------------------------------------ |\n| Calculator Client API                             | This module defines the APIs that each application can invoke to use the services of arithmetic operations (addition, subtraction, division and multiplication) |\n| Calculator SOAP Client Implementation             | This module implements the APIs defined by the calculator-api module and acts as a client to the SOAP Calculator service |\n| Calculator Client Gogo Shell Commands             | This module implements the Gogo Shell commands that use the APIs defined by the calculator-api module to perform the arithmetic operations |\n| Calculator Web Application                        | This module implements a standard MVC portlet that uses the APIs defined by the calculator-api module to perform the arithmetic operations |\n| Calculator SOAP Client SSL/TLS Mutual Auth Impl   | This module implements the SOAP Calculator client that supports Mutual Authentication |\n| Custom Users API (1.0.0)                          | This module defines the APIs that each application can invoke to use the custom users operation (getUsersByCategory, getUsersByTag, getUsersByTags, etc.) |\n| Custom Users Service Implementation               | This module implements the APIs defined by the custom-users-api module |\n| Custom Users Service JAX-WS API End Point         | This module implements the JAX-WS endpoint and two JAX-WS Handlers (**MacAddressValidatorHandler** and **AuditLogHandler**) |\n| Liferay Portal Remote SOAP Extender Impl Fragment | This module is an [OSGi Fragment](https://osgi.org/specification/osgi.core/7.0.0/framework.module.html#framework.module.fragmenthost) to export some Apache CXF packages |\n| UE VIES VAT Service Client API                    | This module defines the APIs that each application can invoke to use the VIES VAT Service |\n| UE VIES VAT Service SOAP Client Impl              | This module implements the APIs defined by the vat-service-client-api module and acts as a client to the SOAP VIES VAT Service |\n| UE VIES VAT Service Client Gogo Shell             | This module implements the Gogo Shell commands that use the APIs defined by the vat-service-client-api module to perform the check VAT operations |\n\n**Table 1** - The list of the modules of this project\n\n\n\nThe list to see are the nine bundles just installed against the deployment action.\n\n```bash\ng! lb it.dontesta.labs.liferay\nSTART LEVEL 20\n   ID|State      |Level|Name\n 1359|Resolved   |   15|Liferay Portal Remote SOAP Extender Implementation Fragment (1.0.0)|1.0.0\n 1360|Active     |   15|Calculator Web Application (2.0.0)|2.0.0\n 1361|Active     |   15|Calculator Client API (2.0.0)|2.0.0\n 1362|Active     |   15|Calculator SOAP Client Implementation (2.0.0)|2.0.0\n 1363|Active     |   15|Calculator SOAP Client SSL/TLS Mutual Auth Implementation (2.0.0)|2.0.0\n 1364|Active     |   15|Calculator Client Gogo Shell Commands (2.0.0)|2.0.0\n 1365|Active     |   15|Custom Users API (2.0.0)|2.0.0\n 1366|Active     |   15|Custom Users Service Implementation (2.0.0)|2.0.0\n 1367|Active     |   15|Custom Users Service JAX-WS API End Point (2.0.0)|2.0.0\n 1368|Active     |   15|UE VIES VAT Service Client API (2.0.0)|2.0.0\n 1369|Active     |   15|UE VIES VAT Service Client Gogo Shell (2.0.0)|2.0.0\n 1370|Active     |   15|UE VIES VAT Service SOAP Client Impl (2.0.0)|2.0.0\n```\n\n**Console 2** - Check status of the Calculator bundle\n\n\n\n## 2. How to implement a SOAP client that supports Mutual Authentication\nThere are situations where access to SOAP services can be protected through a \nmutual authentication mechanism over SSL/TLS.**In this situation, how do you \nbuild the client**?\n\nHere I don't want to bore you in technical details about the mutual \nauthentication mechanism, so I recommend reading my last article [Apache HTTP 2.4: How to Build a Docker Image for SSL/TLS Mutual Authentication](https://dzone.com/articles/apache-http-24-how-to-build-a-docker-image-for-ssl) \npublished on DZone Portal.\n\nWe recall that Liferay uses the [Apache CXF framework](https://cxf.apache.org/) \n(version 3.2.14 on Liferay 7.3 GA6). When using an **https URL**, Apache CXF \nwill, by default, use the certs and keystore that are part of the JDK. \nI have in fact configured the keystore and truststore at the system level, so \nthe mutual authentication works correctly.\n\n```bash\n-Djavax.net.ssl.trustStore=\n-Djavax.net.ssl.trustStorePassword=\n-Djavax.net.ssl.trustStoreType=\n-Djavax.net.ssl.keyStore=\n-Djavax.net.ssl.keyStorePassword=\n-Djavax.net.ssl.keyStoreType=\n```\n\n**Console 3** - System settings for configure truststore and keystore\n\nFor more information about Java security implementation, I recommend reading the [Java Secure Socket Extension (JSSE) Reference Guide](https://docs.oracle.com/en/java/javase/11/security/java-secure-socket-extension-jsse-reference-guide.html#GUID-93DEEE16-0B70-40E5-BBE7-55C3FD432345) \nand [Java Cryptography Architecture (JCA) Reference Guide](https://docs.oracle.com/en/java/javase/11/security/java-cryptography-architecture-jca-reference-guide.html#GUID-2BCFDD85-D533-4E6C-8CE9-29990DEB0190)\n\nFor many HTTPs applications, that is enough and no configuration is necessary. \nHowever, when using custom client certificates or self-signed server certificates \nor similar, you may need to specifically configure in the keystore and trust\nmanagers and such to establish the SSL connection.\n\nAlso we can't use the **SSLContext** setting via **JAX-WS API** because \nignored by Apache CXF and now deprecated.\n\n```java\n((BindingProvider)_calculatorSoap).getRequestContext().put(\n\t\t\"com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory\",\n  \t_getSSLConnectionSocketFactory()\n);\n```\n\n**Source Code 1** - Setting SSLSocketFactory\n\nWe can't even use *HttpsURLConnection.setDefaultSSLSocketFactory(_getSSLConnectionSocketFactory())* \nbecause ignored by Apache CXF unless I configure the \n*useHttpsURLConnectionDefaultSslSocketFactory* property.\n\nIn order to achieve our goal we need to be able to use Apache CXF directly. \nTherefore, it is necessary create an [OSGi Fragment](https://osgi.org/specification/osgi.core/7.0.0/framework.module.html#framework.module.fragmenthost) \nto export some Apache CXF packages. The fragment must be made on the module \n**Liferay Portal Remote SOAP Extender Implementation**\n\nThe module [liferay-portal-remote-soap-extender-impl-fragment](https://github.com/amusarra/liferay-72-soap-client-examples/tree/master/modules/liferay-hooks/liferay-portal-remote-soap-extender-impl-fragment) \nimplements the fragment above. Following the source of the bnd.bnd where it is \nevident the fragment and the Apache CXF exported package.\n\n\n\n```bash\nBundle-Name: Liferay Portal Remote SOAP Extender Implementation Fragment\nBundle-SymbolicName: it.dontesta.labs.liferay.portal.remote.soap.extender.impl\nBundle-Version: 1.0.0\nFragment-Host: com.liferay.portal.remote.soap.extender.impl;bundle-version=\"4.0.12\"\n\nExport-Package: \\\n\torg.apache.cxf.frontend;version=\"3.2.14\"\n```\n\n**Source Code 2** - The bnd.bnd of the OSGi Fragment Liferay Portal Remote SOAP Extender Implementation\n\nAt this point we can use Apache CXF to build our SOAP client that is able to \nperform mutual authentication over SSL / TLS. Following is the base code of \nthe [calculator-service-ssl-tls-mutual-auth](https://github.com/amusarra/liferay-72-soap-client-examples/tree/master/modules/calculator/calculator-service-ssl-tls-mutual-auth) \nmodule that implements the SOAP client with the support of mutual authentication.\n\nThe example implemented refers to the SOAP Calculator service whose \n[WSDL](http://www.dneonline.com/calculator.asmx) (Web Services Description Language) \ndescriptor is available at the following address http://www.dneonline.com/calculator.asmx \nwhich exposes the four arithmetic operations between two integers.\n\n1. The first code block performs the SOAP endpoint setup\n2. The second block of code sets the proxy client setup, the http policy and finally the TLS connection properties\n3. The third code block sets the SSL context, in particular it performs the KeyStore and TrustStore setup\n\n```java\nprivate CalculatorSoap _getService(boolean renew)\n\tthrows CalculatorServiceException {\n\n\ttry {\n\t\torg.tempuri.Calculator calculator =\n\t\t\tnew org.tempuri.Calculator();\n\t\t_calculatorSoap = calculator.getCalculatorSoap();\n\n\t\t((BindingProvider)_calculatorSoap).getRequestContext(\n\t\t).put(\n\t\t\tBindingProvider.ENDPOINT_ADDRESS_PROPERTY,\n\t\t\t_getSOAPEndPointAddress()\n\t\t);\n\n\t\t...\n\t\t\n\t}\n\tcatch (CertificateException | IOException | KeyManagementException |\n\t\t   KeyStoreException | NoSuchAlgorithmException |\n\t\t   UnrecoverableKeyException | WebServiceException wse) {\n\n\t\tif (_log.isErrorEnabled()) {\n\t\t\t_log.error(wse.getMessage(), wse);\n\t\t}\n\n\t\tthrow new CalculatorServiceException(wse.getMessage(), wse);\n\t}\n\n}\n```\n\n**Source Code 3** - Core implementation of the _getService() method of the service CalculatorClientSSLTLSMutualAuthImpl\n\n```java\nprivate void _setUpSecurityClientConnection()\n\tthrows CalculatorServiceException, CertificateException, IOException,\n\t\t   KeyManagementException, KeyStoreException,\n\t\t   NoSuchAlgorithmException, UnrecoverableKeyException {\n\n    ...\n\n\t// Get the underlying http conduit of the client proxy\n\tClient client = ClientProxy.getClient(_calculatorSoap);\n\n\tHTTPConduit http = (HTTPConduit)client.getConduit();\n\n\tHTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();\n\n\thttpClientPolicy.setConnectionTimeout(_getClientConnectionTimeOut());\n\thttpClientPolicy.setReceiveTimeout(_getClientReceiveTimeout());\n\thttpClientPolicy.setAllowChunking(false);\n\n\thttp.setClient(httpClientPolicy);\n\n\t// Set the TLS client parameters\n\tTLSClientParameters parameters = new TLSClientParameters();\n\n\tparameters.setDisableCNCheck(_getCommonNameCheck());\n\n\tif (!_getHostNameVerifier()) {\n\t\tparameters.setHostnameVerifier((hostName, session) -\u003e true);\n\t}\n\n\tparameters.setSSLSocketFactory(_getSSLConnectionSocketFactory());\n\n\thttp.setTlsClientParameters(parameters);\n}\n```\n\n**Source Code 4** - Core implementation of the _setUpSecurityClientConnection() method of the service CalculatorClientSSLTLSMutualAuthImpl\n\n```java\nprivate SSLSocketFactory _getSSLConnectionSocketFactory()\n\tthrows CertificateException, IOException, KeyManagementException,\n\t\t   KeyStoreException, NoSuchAlgorithmException,\n\t\t   UnrecoverableKeyException {\n\n\tSSLContext sslContext = SSLContext.getInstance(_getHTTPSProtocol());\n\n\t// Create and load the truststore\n\tKeyStore trustStore = KeyStore.getInstance(_getTrustStoreType());\n\n\ttrustStore.load(\n\t\t_getTrustStoreFile(), _getTrustStorePassword().toCharArray());\n\n\t// Create and load the keystore\n\tKeyStore keyStore = KeyStore.getInstance(_getKeyStoreType());\n\n\tkeyStore.load(_getKeyStoreFile(), _getKeyStorePassword().toCharArray());\n\n\t// Create and initialize the truststore manager\n\tTrustManagerFactory trustManagerFactory =\n\t\tTrustManagerFactory.getInstance(\"SunX509\");\n\n\ttrustManagerFactory.init(trustStore);\n\n\t// Create and initialize the keystore manager\n\tKeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(\n\t\tKeyManagerFactory.getDefaultAlgorithm());\n\n\tkeyManagerFactory.init(keyStore, _getKeyStorePassword().toCharArray());\n\n\tsslContext.init(\n\t\tkeyManagerFactory.getKeyManagers(),\n\t\ttrustManagerFactory.getTrustManagers(), new SecureRandom());\n\n\treturn sslContext.getSocketFactory();\n}\n```\n\n**Source Code 5** - Core implementation of the _getSSLConnectionSocketFactory() method of the service CalculatorClientSSLTLSMutualAuthImpl\n\nTo start a mutual authentication process we need two keystore, one that contains \npublic certificates (**truststore**) and one that contains private certificates \n(**keystore**). This module contains within it both the keystore and truststore \nthat can be used with the SOAP test service that I have prepared.\n\nIn the structure below we can see the keystore (tls-client.dontesta.it.p12) and \nthe truststore (client-truststore.p12). Both are in the standard \n[PKCS#12](https://en.wikipedia.org/wiki/PKCS_12) format. If you are curious \nabout how these certificates were generated read \n[How The Certificates Were Generated](https://dzone.com/articles/apache-http-24-how-to-build-a-docker-image-for-ssl).\n\n```bash\n├── calculator-service-ssl-tls-mutual-auth\n   └── src\n       └── main\n           └── resources\n               ├── META-INF\n                  ├── keystore\n                  │   ├── client-truststore.p12\n                  │   └── tls-client.dontesta.it.p12\n                  └── wsdl\n                      └── calculator.wsdl\n```\n\n**Console 4** - Resources of the calculator-service-ssl-tls-mutual-auth module\n\nI also wanted to implement the configuration bonus for this SOAP client. The \nfigures show a part of the module configuration. The following parameters can \nbe configured:\n\n1. TrustStore and KeyStore Type\n2. Path of the TrustStore and KeyStore\n3. Password of the TrustStore and KeyStore\n4. HTTPS Protocol\n5. SOAP EndPoint Address\n6. Check CN (Common Name)\n7. Check Hostname\n8. Connection Timeout (ms)\n9. Receive Timeout (ms)\n\n![ConfigurationSOAPExternalService_1](docs/images/ConfigurationSOAPExternalService_1.png)\n\n**Figure 1** - System Settings configuration for Calculator Service\n\n![ConfigurationSOAPExternalService_2](docs/images/ConfigurationSOAPExternalService_2.png)\n\n**Figure 2** - Configuration detail of the Calculator Service\n\n## 3. How to run a client test\nTo test our Calculator service SOAP client, we need the service to be protected \nby the mutual authentication mechanism. To facilitate the task we could take \nadvantage of the [Apache HTTP 2.4 - Docker image for SSL / TLS Mutual Authentication](https://github.com/amusarra/docker-apache-ssl-tls-mutual-authentication).\n\n```bash\n$ docker run -i -t -d \\\n\t-p 10443:10443 \\\n\t-e API_BASE_PATH='/secure/ws' \\\n\t-e API_BACKEND_BASE_URL='http://www.dneonline.com' \\\n\t-e APACHE_PROXY_PRESERVE_HOST=Off \\\n\t--name=apache-ssl-tls-mutual-authentication \\\n\tamusarra/apache-ssl-tls-mutual-authentication:1.2.8\n```\n\n**Console 5** - Start of the SOAP Calculator service protected by the mutual authentication mechanism.\n\nThe new WSDL of the service will be available at the URL \nhttps://localhost:10443/secure/ws/calculator.asmx?WSDL. \nTo avoid the **SSL_ERROR_BAD_CERT_DOMAIN** error from the browser, the following \nline must be added to your hosts file.\n\n```bash\n##\n# Mutual authentication service via Apache HTTPD\n##\n127.0.0.1       tls-auth.dontesta.it\n```\n\n**Source Code 6** - File /etc/hosts\n\nAfter adding entry on hosts file, the new WSDL of the service will be available \nat the URL https://tls-auth.dontesta.it:10443/secure/ws/calculator.asmx?WSDL \n\nThe two figures below show the process of mutual authentication to access the \nWSDL via browser. In this case the client certificate was installed on the browser.\n\n![MutualAuthenticationViaBrowser_1](docs/images/MutualAuthenticationViaBrowser_1.png)\n\n**Figure 3** - Mutual Authentication request for the WSDL resource\n\n![MutualAuthenticationViaBrowser_2](docs/images/MutualAuthenticationViaBrowser_2.png)\n\n**Figure 4** - WSDL document of the Calculator SOAP Service\n\nNow that the SOAP service is active, we can test our new client. I remind you \nthat we have two SOAP clients for the same service: \n\n1. The client that directly accesses the service without any security mechanism (modulo **calculator-service**)\n2. The client that instead uses the mutual authentication mechanism (modulo **calculator-service-ssl-tls-mutual-auth**).\n\nWe must therefore stop the first service, in this way both the web module and \nthe Gogo Shell module, will use the SOAP client in mutual authentication.\n\n```bash\ng! stop 1362\ng! lb Calculator\nSTART LEVEL 20\n   ID|State      |Level|Name\n 1360|Active     |   15|Calculator Web Application (2.0.0)|2.0.0\n 1361|Active     |   15|Calculator Client API (2.0.0)|2.0.0\n 1362|Active     |   15|Calculator SOAP Client Implementation (2.0.0)|2.0.0\n 1363|Active     |   15|Calculator SOAP Client SSL/TLS Mutual Auth Implementation (2.0.0)|2.0.0\n 1364|Active     |   15|Calculator Client Gogo Shell Commands (2.0.0)|2.0.0\n```\n\n**Console 6** - Stop the bundle Calculator SOAP Client Implementation\n\nIf we wanted to make sure that both the Gogo Shell commands, and the MVC portlet \nwere linked to the new service we could check with the command scr: info \n${component name}. As you can see, the linked service is the correct one: \n**it.dontesta.labs.liferay.webservice.calculator.client.tls**\n\n```bash\ng! scr:info it.dontesta.labs.liferay.webservice.calculator.gogoshell.CalculatorCommand\nComponent Description: it.dontesta.labs.liferay.webservice.calculator.gogoshell.CalculatorCommand\n=================================================================================================\nClass:         it.dontesta.labs.liferay.webservice.calculator.gogoshell.CalculatorCommand\nBundle:        1374 (it.dontesta.labs.liferay.webservice.calculator.gogoshell:2.0.0)\nEnabled:       true\nImmediate:     false\nServices:      [java.lang.Object]\nScope:         singleton\nConfig PID(s): [it.dontesta.labs.liferay.webservice.calculator.gogoshell.CalculatorCommand], Policy: optional\nBase Props:    (2 entries)\n  osgi.command.function\u003cString[]\u003e = [add, divide, multiply, subtract]\n  osgi.command.scope\u003cString\u003e = calculator\n\nComponent Configuration Id: 8180\n--------------------------------\nState:        ACTIVE\nService:      21763 [java.lang.Object]\n    Used by bundle 894 (com.liferay.portal.remote.cxf.common:6.0.13)\nConfig Props: (4 entries)\n  component.id\u003cLong\u003e = 8180\n  component.name\u003cString\u003e = it.dontesta.labs.liferay.webservice.calculator.gogoshell.CalculatorCommand\n  osgi.command.function\u003cString[]\u003e = [add, divide, multiply, subtract]\n  osgi.command.scope\u003cString\u003e = calculator\nReferences:   (total 1)\n  - _calculator: it.dontesta.labs.liferay.webservice.calculator.api.Calculator SATISFIED 1..1 dynamic+greedy\n    target=(*) scope=bundle (1 binding):\n    * Bound to [21775] from bundle 1373 (it.dontesta.labs.liferay.webservice.calculator.client.tls:2.0.0)\ng!\n```\n\n**Console 7** - src:info for checking the bound service for Gogo Shell Command\n\n```bash\ng! scr:info it.dontesta.labs.liferay.web.calculator.portlet.action.AddOperationMVCActionCommand\nComponent Description: it.dontesta.labs.liferay.web.calculator.portlet.action.AddOperationMVCActionCommand\n==========================================================================================================\nClass:         it.dontesta.labs.liferay.web.calculator.portlet.action.AddOperationMVCActionCommand\nBundle:        1376 (it.dontesta.labs.liferay.web.calculator:2.0.0)\nEnabled:       true\nImmediate:     true\nServices:      [com.liferay.portal.kernel.portlet.bridges.mvc.MVCActionCommand]\nScope:         singleton\nConfig PID(s): [it.dontesta.labs.liferay.web.calculator.portlet.action.AddOperationMVCActionCommand], Policy: optional\nBase Props:    (2 entries)\n  javax.portlet.name\u003cString\u003e = it_dontesta_labs_liferay_web_calculator_CalculatorAppPortlet\n  mvc.command.name\u003cString\u003e = /calculator/add-operation\n\nComponent Configuration Id: 8196\n--------------------------------\nState:        ACTIVE\nService:      21803 [com.liferay.portal.kernel.portlet.bridges.mvc.MVCActionCommand]\nConfig Props: (4 entries)\n  component.id\u003cLong\u003e = 8196\n  component.name\u003cString\u003e = it.dontesta.labs.liferay.web.calculator.portlet.action.AddOperationMVCActionCommand\n  javax.portlet.name\u003cString\u003e = it_dontesta_labs_liferay_web_calculator_CalculatorAppPortlet\n  mvc.command.name\u003cString\u003e = /calculator/add-operation\nReferences:   (total 1)\n  - _calculator: it.dontesta.labs.liferay.webservice.calculator.api.Calculator SATISFIED 1..1 static+greedy\n    target=(*) scope=bundle (1 binding):\n    * Bound to [21775] from bundle 1373 (it.dontesta.labs.liferay.webservice.calculator.client.tls:2.0.0)\ng!\n```\n\n**Console 8** - src:info for checking the bound service for AddOperationMVCActionCommand\n\n## 4. How to configure JAX-WS Handlers\nUsing the Liferay JAX-WS infrastructure it is possible in a very simple way to \nconfigure one or more JAX-WS Handlers for each endpoint.\n\nThe endpoint **/custom-user** must be configured manually via the control panel. \nThe **custom-users-ws** module has been set up for automatic [configuration](https://github.com/amusarra/liferay-72-soap-client-examples/tree/feature/jax-ws-soap-handler-in-server-side/modules/jaxws-service/custom-users-ws/src/main/resources/configuration) \nbut at the moment it doesn't seem to work (see [LPS-101642](https://issues.liferay.com/browse/LPS-101642)).\n\n![ConfigurationSOAPExternalService_3](docs/images/ConfigurationSOAPExternalService_3.png)\n\n**Figure 5** - JAX-WS Handler configuration for endpoint /custom-user\n\nThrough the **JAX-WS Handler Filters** you can specify a set of [OSGi filters](https://osgi.org/javadoc/r6/core/org/osgi/framework/Filter.html) \nthat select certain services registered in the OSGi framework. The selected \nservices should implement JAX-WS handlers and augment the JAX-WS services \nspecified in the *jax.ws.service.filters* property. These JAX-WS handlers \napply to each service selected in this extender.\n\nThe two code fragments show the two JAX-WS Handlers (which are OSGi components) \nconfigured in figure 5. Note the properties of the OSGi component where specified OSGi filter.\n\n```java\n/**\n * @author Antonio Musarra\n */\n@Component(\n\tconfigurationPid = MacAddressValidatorHandlerConfiguration.PID,\n\timmediate = true,\n\tproperty = \"mac.address.validator.jax.ws.handler.filters=true\",\n\tservice = Handler.class\n)\npublic class MacAddressValidatorHandler\n\timplements SOAPHandler\u003cSOAPMessageContext\u003e {\n\t\t...\n}\n```\n\n**Source Code 7** - Mac Address Validator JAX-WS Handler\n\nThe Handler [MacAddressValidatorHandler](https://github.com/amusarra/liferay-72-soap-client-examples/blob/feature/jax-ws-soap-handler-in-server-side/modules/jaxws-service/custom-users-ws/src/main/java/it/dontesta/labs/liferay/webservice/customusers/service/ws/handler/MacAddressValidatorHandler.java) \nperforms the validation of the Mac Address that the SOAP client passes in the SOAP Headers.\n\n```xml\n\u003csoapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.service.customusers.webservice.liferay.labs.dontesta.it/\" xmlns:soap=\"soap\"\u003e\n   \u003csoapenv:Header\u003e\n      \u003cmac:MacAddress \n      \tsoapenv:actor=\"http://schemas.xmlsoap.org/soap/actor/next\" \n      \txmlns:mac=\"http://ws.service.customusers.webservice.liferay.labs.dontesta.it/macaddress/value/\"\u003e88:e9:fe:69:c6:88\u003c/mac:MacAddress\u003e\n   \u003c/soapenv:Header\u003e\n   \u003csoapenv:Body\u003e\n      \u003cws:getUsersByTag\u003e\n         \u003c!--Optional:--\u003e\n         \u003carg0\u003eSoftwareArchitect\u003c/arg0\u003e\n      \u003c/ws:getUsersByTag\u003e\n   \u003c/soapenv:Body\u003e\n\u003c/soapenv:Envelope\u003e\n```\n\n**Source Code 8** - SOAP Request with evidence of the Mac Address header\n\n\n\n```xml\n\u003csoap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"\u003e\n   \u003csoap:Body\u003e\n      \u003csoap:Fault\u003e\n         \u003cfaultcode xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\u003esoapenv:Server\u003c/faultcode\u003e\n         \u003cfaultstring\u003eInvalid MAC Address, access is denied.\u003c/faultstring\u003e\n      \u003c/soap:Fault\u003e\n   \u003c/soap:Body\u003e\n\u003c/soap:Envelope\u003e\n```\n\n**Source Code 9** - SOAP Fault generated by the Mac Address validation Handler\n\nThe Mac Addresses to be enabled can be configured from the control panel.\n\n![ConfigurationSOAPExternalService_5](docs/images/ConfigurationSOAPExternalService_5.png)\n\n**Figure 6** - Configuration of the JAX-WS Handler Mac Address Validator\n\nThe Handler [AuditLogHandler](https://github.com/amusarra/liferay-72-soap-client-examples/blob/feature/jax-ws-soap-handler-in-server-side/modules/jaxws-service/custom-users-ws/src/main/java/it/dontesta/labs/liferay/webservice/customusers/service/ws/handler/AuditLogHandler.java) \naudits SOAP messages in input and output via the [Liferay Audit framework](https://amzn.to/2kMq4Dd).\n\n```java\n/**\n * @author Antonio Musarra\n */\n@Component(\n\timmediate = true, property = \"audit.log.jax.ws.handler.filters=true\",\n\tservice = Handler.class\n)\npublic class AuditLogHandler implements SOAPHandler\u003cSOAPMessageContext\u003e {\n    ...\n}\n```\n\n**Source Code 10** - Audit Log JAX-WS Handler\n\n![AuditLogJAXWSHandler_1](docs/images/AuditLogJAXWSHandler_1.png)\n\n**Figure 7** - Trace the Audit Event via Audit Log JAX-WS Handler\n\n## License\n\nMIT License\n\nCopyright 2009-present Antonio Musarra's Blog - https://www.dontesta.it\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famusarra%2Fliferay-72-soap-client-examples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famusarra%2Fliferay-72-soap-client-examples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famusarra%2Fliferay-72-soap-client-examples/lists"}