I have recently worked on an interesting use case to integrate JDV with a SOAP Webservice which exposes WS-Addressing behavior via SOAP headers and requires a 2-way SSL. The use case stems from some strict regulations in the host country which prevent direct access to data sensitive systems and any access has to be via a web service, authenticated and encrypted. The following example showcases the configurations required and can be found in github. Installation Guide - Red Hat Customer Portal
Setup JDV Server
-
Install EAP 6.4.0
-
Patch EAP 6.4.0 with Patch 6.4.9
-
Install JDV 6.3.0
-
Patch JDV with patch 6.3.0
-
Add odata role to teiidUser (standalone/configuration/application-roles.properties
TEIID Username : teiidUser TEIID Password : xxxx
Install JBDS 9.1.0Setup JDV Design Environment (TEIID Designer)
-
Install TEIID Development Kit – Install devstudio-integration-stack-9.0.3.GA-updatesite.zip
-
6.4. Installing JBoss Data Virtualization Development Tools (Insallation Guide)
-
Create JDV Server Configuration on JBDS & Test Connection
Setup EAP Server with two-way SSL authentication
(see JDVTooling/jdv-jax-wsa-ssl-example/ssl-materials at master · skoussou/JDVTooling · GitHub folder)
All the client and server keystores are included in the folders
- JDV-SSL-CLient
- EAP-SSL-Server
JDVTooling/READEME-Setup-Server-Client-SSL-Keystores-JBoss-EAP-SSL-Config.md at master · skoussou/JDVTooling · GitHub describes the setup
Setup JDV Project
Create Datasource Connection to SOAP Web Service
In JBDS perform the following steps:
-
Open the “Data Source Explorer View” via menu Window → Show View → Other → Data Source Explorer View
-
Choose “Teiid Importer Connections” right click New → Web Services Data Source (SOAP) define name eg. WSAAddressing (SOAP) → URL → (URL where the WSDL can be found) + Security Type (HNone) → Test Connection → Select the Endpoint → Finish
IMPORTANT: The WSDL exposed does not seem to be possible to be imported via the URL (possibly due to 2-way SSL) in TEIID Designer. As a result in the above instructions two parts have to be different.
a) From the browser downlad the WSDL xml saving as AddressingService.wsdl and then use instead of URL the FileSystem and locate the WSDL (AddressingService.wsdl)
b) Do not press Testing as it will fail and you will have to start from the beginning the process.
Create Source & Virtual Base Layer Models to SOAP Webservice
JDV best practices define the the Views created inside the engine are abstracted from the physical view of the datasource so that in the case that in the future the PHYSICAL source changes the enterprise and federated queries remain the same. Therefore, we always create one Source Model for each datasource and one Virtual Base Layer (with potentially more built on top of it as we further abstract the queries and combine Views from multiple datasources).
On the Source Models folder inside the JBDS Teiid Project (if no folder then create) Right click → Import → Web Service Source >> Source And View Model (SOAP) → In the next page choose
-
Connection Profile: WSAAddressing (SOAP) which we created above
-
Validate the WSDL
-
Service Mode: MESSAGE (as the web service we connect to requires WS-A headers we had to define and send the whole<soap:envelope> via the MODELs not just the payload
-
Select the Operation or Operations which we will connect to (think of these as Database Names)
Proceed through the next screens without changes unless you desire to until you reach “Procedure Definition” where you will selected for REQUEST the fields from the elements required for the request and the response”. We have selected
REQUEST: sayHello element
RESPONSE: return
Then in the resulting Virtual Base Layer View you can define the appropriate query to provide in the Request the WS-A headers (see Appendix C – SOA-P Request) and additional request fields (the additional you need to add them manually to the model request).
Important: The headers are not defined in the default query despite earlier selecting MESSAGE as the option you will have to create them as the example request shows.
SayHello_request
BEGIN SELECT XMLELEMENT(NAME "soap:Envelope", XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS soap, 'http://www.jboss.org/jbossws/ws-extensions/wsaddressing' AS tns, 'http://www.w3.org/2005/08/addressing' AS wsa), XMLELEMENT(NAME "soap:Header", XMLELEMENT(NAME"wsa:MessageID", AddressingServiceView_4.sayHello_request.MessageID), XMLELEMENT(NAME "wsa:To", AddressingServiceView_4.sayHello_request."To"),XMLELEMENT(NAME "wsa:ReplyTo", AddressingServiceView_4.sayHello_request.ReplyTo), XMLELEMENT(NAME "wsa:Action",AddressingServiceView_4.sayHello_request.Action)), XMLELEMENT(NAME "soap:Body", XMLELEMENT(NAME "tns:sayHello",AddressingServiceView_4.sayHello_request.sayHello))) AS xml_out; END
SayHello_response
BEGIN SELECT t.* FROM XMLTABLE(XMLNAMESPACES('http://www.jboss.org/jbossws/ws-extensions/wsaddressing' AS tns,'http://schemas.xmlsoap.org/soap/envelope/' AS soap), '/soap:Envelope' PASSING AddressingServiceView_4.sayHello_response.xml_in COLUMNS "return"string PATH '/soap:Body/tns:sayHelloResponse/return') AS t; END
Overall query SayHello
BEGIN SELECT t.* FROM TABLE(EXEC AddressingServiceView_4.sayHello_request(AddressingServiceView_4.sayHello.sayHello,AddressingServiceView_4.sayHello.MessageID, AddressingServiceView_4.sayHello."To", AddressingServiceView_4.sayHello.ReplyTo,AddressingServiceView_4.sayHello.Action)) AS request, TABLE(EXEC AddressingService_4.invoke(binding => 'SOAP11', action => '', request =>request.xml_out, endpoint => null, stream => TRUE)) AS response, TABLE(EXEC AddressingServiceView_4.sayHello_response(response.result)) AS t; END
-
https://developer.jboss.org/wiki/JBossWS-CXFWS-Addressingtutorial
-
https://omgo.wordpress.com/2010/01/05/ws-addresssing-replyto-with-cxf/
-
https://docs.oracle.com/middleware/1213/wls/WSGET/jax-ws-wsaddressing.htm#WSGET663
Configure a JDV Web Service Datasource connection with 2-way SSL JDV to the SOAP Webservice Endpoint
JDV Utilizes Resource Adapters on the underlying JBoss EAP server (based on JEE specification) to connect to disparate technologies via defining configuration of the adapter on the server and making the usage of it available via a JNDI (Naming Directory) to the VDBs. The documentation which defines how to configure the resource adapter for a web service datasource can be found at https://teiid.gitbooks.io/documents/content/admin/Web_Service_Data_Sources.html
see JDVTooling/standalone.xml at master · skoussou/JDVTooling · GitHub for an example
Resource Adapter configuration for connection to SOAP Webservice with HTTP Basic Authentication and SSL Connection
<subsystem xmlns="urn:jboss:domain:resource-adapters:1.1"> <resource-adapters> <resource-adapter id="AddressingService_4"> <module slot="main" id="org.jboss.teiid.resource-adapter.webservice"/> <transaction-support>NoTransaction</transaction-support> <connection-definitions> <connection-definition class-name="org.teiid.resource.adapter.ws.WSManagedConnectionFactory" jndi-name="java:/AddressingService_4" enabled="true" pool-name="AddressingService_4"> <config-property name="SecurityType"> None </config-property> <config-property name="EndPoint"> https://localhost:8543/jboss-jaxws-addressing/AddressingService </config-property> <config-property name="ConfigFile"> /home/stkousso/Stelios/sw10/JDV/Distros/jboss-eap-6.4/standalone/configuration/ssl-jbossws-cxf.xml </config-property> </connection-definition> </connection-definitions> </resource-adapter> </resource-adapters>
The ConfigFile provides the ability for the connector to utilize a technology called CXF to produce the appropriate protocol settings. In the case above the two settings are
-
HTTP Basic Authentication via a service user (ie. not pass through)
-
2-way SSL
see JDVTooling/ssl-jbossws-cxf.xml at master · skoussou/JDVTooling · GitHub for an example
ssl-jbossws-cxf.xml: CXF Configuration for 2-way SSL
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:jaxws2="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws2:client name="http://localhost:31000" createdFromAPI="true"> <jaxws2:features> <bean class="org.apache.cxf.feature.LoggingFeature"/> </jaxws2:features> </jaxws2:client> <http-conf:conduit name="*.http-conduit"> <!--NOTE you can limit this to the service by giving a more restrictive conduit name http-conf:conduit name="https://ws-gateway-cert-qs.wob.vw.vwg/services"--> <!-- WARNING ! disableCNcheck=true should NOT be used in production disableCNcheck="true" but instead the domain of the certificate should match the endpoint of the exposed web serice--> <http-conf:authorization> <!--sec:UserName>DWSUCDQ</sec:UserName> <sec:Password>xxxxxxxxxx</sec:Password--> <sec:AuthorizationType>None</sec:AuthorizationType> </http-conf:authorization> --> <http-conf:client ConnectionTimeout="120000" ReceiveTimeout="240000"/> <http-conf:tlsClientParameters disableCNCheck="true" secureSocketProtocol="SSL" > <!-- Client Trustore with server certificate to check against the server provided <sec:trustManagers> <sec:keyStore type="JKS" password="[CLIENT TRUSTORE KEYSTORE PASSWORD]" file="../standalone/configuration/client_truststore.jks"/> <!-- Client Certificate to be provided for the 2-way SSL handshake </sec:trustManagers> <sec:keyManagers keyPassword="1WPS2N0Q"> <sec:keyStore type="PKCS12" password="KEYSTORE PASSWORD" file="../standalone/configuration/DWSUCDQ.p12"/> </sec:keyManagers> </http-conf:tlsClientParameters> </http-conf:conduit> </beans> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd"> <jaxws2:client name="http://localhost:31000" createdFromAPI="true"> <jaxws2:features> <bean class="org.apache.cxf.feature.LoggingFeature"/> </jaxws2:features> </jaxws2:client> <http-conf:conduit name="*.http-conduit"> <!--NOTE you can limit this to the service by giving a more restrictive conduit name http-conf:conduit name="https://localhost:8543/jboss-jaxws-addressing/AddressingService"--> <!-- WARNING ! disableCNcheck=true should NOT be used in production disableCNcheck="true" --> <http-conf:client ConnectionTimeout="120000" ReceiveTimeout="240000"/> <http-conf:tlsClientParameters disableCNCheck="true" secureSocketProtocol="SSL" > <sec:trustManagers> <sec:keyStore type="JKS" password="mypass" file="../standalone/configuration/client.jks"/> </sec:trustManagers> <sec:keyManagers keyPassword="sslworkshop"> <sec:keyStore type="JKS" password="sslworkshop" file="../standalone/configuration/clientauth_ks.jks"/> </sec:keyManagers> </http-conf:tlsClientParameters> </http-conf:conduit> </beans>
IMPORTANT: The JDV server MUST be started with standalone.bat -Dhttps.protocols=TLSv1
Resources:
-
http://javarevisited.blogspot.gr/2012/09/difference-between-truststore-vs-keyStore-Java-SSL.html
-
https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/KeyManager.html
-
http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html
For the creation of the keystores read the READEME-Setup-Server-Client-SSL-Keystores-JBoss-EAP-SSL-Config.md
The VDB
In the project we created a Folder VirtualDatabase and in there we used the modelling menu to create a new VDB named WSA-Models.vdb chooing the choosing
- Source Model: AddressingService_4
- Virtual Base Model: AddressingServiceView_4
- and very important the translator name AddressingService_4_ws which provides overrides on sending SOAP messages via MESSAGE and not PAYLOAD in comparison to the translator provided by default in the JDV Server.
- Relies on the resource adapter above with JNDI Name: "java:/AddressingService_4"
- To expose the WSA-Models VDB via JDBC the following setting is required on the datasources subsystem
VDB Datasource
<datasource jndi-name="java:/WSA-Models" pool-name="WSA-Models" enabled="true"> <connection-url>jdbc:teiid:WSA-Models@mm://localhost:31000</connection-url> <driver>teiid</driver> <security> <user-name>teiidUser</user-name> <password>Password630!</password> </security> </datasource>
- Create a TEIID Connection against the server via an SQL client with the TEIID JDBC Driver and execute the query in Teiid-JDBC-Test-Queries.sql any changes to the ssl-jbossws-cxf.xml (eg. such as password or file names) will result in the 2-way SSL to fail
Patch the JDV Server
Due to a change in the behavior of one of the libraries JDV depends on to create SOAP messages the a JIRA https://issues.jboss.org/browse/TEIID-4755 was created and a patch provided by the engineering team. To apply the JIRA in the JDV Home directory follow the path modules/system/layers/dv/org/jboss/teiid/translator/ws/main and
a) place the translator-ws-8.12.9.6_3.jar that accompanies this report
b) replace the module.xml with
module.xml
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="org.jboss.teiid.translator.ws"> <properties> <property name="jboss.api" value="private"/> </properties> <resources> <!-- resource-root path="translator-ws-8.12.5.redhat-8.jar" /--> <!-- Patched to correct ClassCastException --> <resource-root path="translator-ws-8.12.9.6_3.jar" /> <!-- Insert resources here --> </resources> <dependencies> <module name="javax.xml.ws.api"/> <module name="javax.api"/> <module name="javax.resource.api"/> <module name="org.jboss.teiid.common-core" /> <module name="org.jboss.teiid.api" /> <module name="org.jboss.teiid" /> <module name="javax.wsdl4j.api"/> <module name="org.springframework.spring" optional="true"/> </dependencies> </module>
This will be added in teiid 9.2 & 9.3
Connect with Red Hat Services
Learn more about Red Hat Consulting
Learn more about Red Hat Training
Learn more about Red Hat Certification
Subscribe to the Training Newsletter
Follow Red Hat Services on Twitter
Follow Red Hat Open Innovation Labs on Twitter
Like Red Hat Services on Facebook
Watch Red Hat Training videos on YouTube
Follow Red Hat Certified Professionals on LinkedIn
저자 소개
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
오리지널 쇼
엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리
제품
- Red Hat Enterprise Linux
- Red Hat OpenShift Enterprise
- Red Hat Ansible Automation Platform
- 클라우드 서비스
- 모든 제품 보기
툴
체험, 구매 & 영업
커뮤니케이션
Red Hat 소개
Red Hat은 Linux, 클라우드, 컨테이너, 쿠버네티스 등을 포함한 글로벌 엔터프라이즈 오픈소스 솔루션 공급업체입니다. Red Hat은 코어 데이터센터에서 네트워크 엣지에 이르기까지 다양한 플랫폼과 환경에서 기업의 업무 편의성을 높여 주는 강화된 기능의 솔루션을 제공합니다.