org.pentaho.di.trans.steps.webservices.wsdl.Wsdl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kettle-engine Show documentation
Show all versions of kettle-engine Show documentation
Container pom for Pentaho Data Integration modules
The newest version!
/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.trans.steps.webservices.wsdl;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLLocator;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import org.apache.http.auth.AuthenticationException;
import org.pentaho.di.core.HTTPProtocol;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleStepException;
import org.pentaho.di.core.logging.LogChannel;
import org.pentaho.di.core.xml.XMLHandler;
import org.w3c.dom.Document;
/**
* Wsdl abstraction.
*/
public final class Wsdl implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Port _port;
private final Definition _wsdlDefinition;
private final Service _service;
private final WsdlTypes _wsdlTypes;
private HashMap _operationCache;
private URI wsdlURI = null;
/**
* Loads and parses the specified WSDL file.
*
* @param wsdlURI
* URI of a WSDL file.
* @param serviceQName
* Name of the service in the WSDL, if null default to first service in WSDL.
* @param portName
* The service port name, if null default to first port in service.
*/
public Wsdl( URI wsdlURI, QName serviceQName, String portName ) throws AuthenticationException {
this( wsdlURI, serviceQName, portName, null, null );
}
public Wsdl( URI wsdlURI, QName serviceQName, String portName, String username, String password ) throws AuthenticationException {
this.wsdlURI = wsdlURI;
try {
_wsdlDefinition = parse( wsdlURI, username, password );
} catch ( AuthenticationException ae ) {
// throw this again since KettleException is catching it
throw ae;
} catch ( WSDLException e ) {
throw new RuntimeException( "Could not load WSDL file: " + e.getMessage(), e );
} catch ( KettleException e ) {
throw new RuntimeException( "Could not load WSDL file: " + e.getMessage(), e );
}
if ( serviceQName == null ) {
_service = (Service) _wsdlDefinition.getServices().values().iterator().next();
} else {
_service = _wsdlDefinition.getService( serviceQName );
if ( _service == null ) {
throw new IllegalArgumentException( "Service: "
+ serviceQName + " is not defined in the WSDL file " + wsdlURI );
}
}
if ( portName == null ) {
_port = getSoapPort( _service.getPorts().values() );
} else {
_port = _service.getPort( portName );
if ( _port == null ) {
throw new IllegalArgumentException( "Port: "
+ portName + " is not defined in the service: " + serviceQName );
} else {
_port = _service.getPort( portName );
}
}
_wsdlTypes = new WsdlTypes( _wsdlDefinition );
_operationCache = new HashMap();
}
/**
* Returns the first Soap port from the passed collection of Ports.
*
* @param portCollection
* @return
*/
private Port getSoapPort( Collection> portCollection ) {
Port soapPort = null;
Iterator> iterator = portCollection.iterator();
while ( iterator.hasNext() ) {
Port port = (Port) iterator.next();
if ( WsdlUtils.isSoapPort( port ) ) {
soapPort = port;
break;
}
}
return soapPort;
}
/**
* Loads and parses the specified WSDL file.
*
* @param wsdlLocator
* A javax.wsdl.WSDLLocator instance.
* @param serviceQName
* Name of the service in the WSDL.
* @param portName
* The service port name.
*/
public Wsdl( WSDLLocator wsdlLocator, QName serviceQName, String portName ) throws AuthenticationException {
this( wsdlLocator, serviceQName, portName, null, null );
}
public Wsdl( WSDLLocator wsdlLocator, QName serviceQName, String portName, String username, String password ) throws AuthenticationException {
// load and parse the WSDL
try {
_wsdlDefinition = parse( wsdlLocator, username, password );
} catch ( AuthenticationException ae ) {
// throw it again or KettleException will catch it
throw ae;
} catch ( WSDLException e ) {
throw new RuntimeException( "Could not load WSDL file: " + e.getMessage(), e );
} catch ( KettleException e ) {
throw new RuntimeException( "Could not load WSDL file: " + e.getMessage(), e );
}
_service = _wsdlDefinition.getService( serviceQName );
if ( _service == null ) {
throw new IllegalArgumentException( "Service: " + serviceQName + " is not defined in the WSDL file." );
}
_port = _service.getPort( portName );
if ( _port == null ) {
throw new IllegalArgumentException( "Port: " + portName + " is not defined in the service: " + serviceQName );
}
_wsdlTypes = new WsdlTypes( _wsdlDefinition );
_operationCache = new HashMap();
}
/**
* Get the WsdlComplexTypes instance of this wsdl. WsdlComplex types provides type information for named complextypes
* defined in the wsdl's <types> section.
*
* @return WsdlComplexTypes instance.
*/
public WsdlComplexTypes getComplexTypes() {
return _wsdlTypes.getNamedComplexTypes();
}
/**
* Find the specified operation in the WSDL definition.
*
* @param operationName
* Name of operation to find.
* @return A WsdlOperation instance, null if operation can not be found in WSDL.
*/
public WsdlOperation getOperation( String operationName ) throws KettleStepException {
// is the operation in the cache?
if ( _operationCache.containsKey( operationName ) ) {
return _operationCache.get( operationName );
}
Binding b = _port.getBinding();
PortType pt = b.getPortType();
Operation op = pt.getOperation( operationName, null, null );
if ( op != null ) {
try {
WsdlOperation wop = new WsdlOperation( b, op, _wsdlTypes );
// cache the operation
_operationCache.put( operationName, wop );
return wop;
} catch ( KettleException kse ) {
LogChannel.GENERAL.logError( "Could not retrieve WSDL Operator for operation name: " + operationName );
throw new KettleStepException(
"Could not retrieve WSDL Operator for operation name: " + operationName, kse );
}
}
return null;
}
/**
* Get a list of all operations defined in this WSDL.
*
* @return List of WsdlOperations.
*/
@SuppressWarnings( "unchecked" )
public List getOperations() throws KettleStepException {
List opList = new ArrayList();
PortType pt = _port.getBinding().getPortType();
List operations = pt.getOperations();
for ( Iterator itr = operations.iterator(); itr.hasNext(); ) {
WsdlOperation operation = getOperation( itr.next().getName() );
if ( operation != null ) {
opList.add( operation );
}
}
return opList;
}
/**
* Get the name of the current port.
*
* @return Name of the current port.
*/
public String getPortName() {
return _port.getName();
}
/**
* Get the PortType name for the service which has been specified by serviceName and portName at construction time.
*
* @return QName of the PortType.
*/
public QName getPortTypeQName() {
Binding b = _port.getBinding();
return b.getPortType().getQName();
}
/**
* Get the service endpoint.
*
* @return String containing the service endpoint.
*/
public String getServiceEndpoint() {
return WsdlUtils.getSOAPAddress( _port );
}
/**
* Get the name of this service.
*
* @return Service name.
*/
public String getServiceName() {
return _service.getQName().getLocalPart();
}
/**
* Get the target namespace for the WSDL.
*
* @return The targetNamespace
*/
public String getTargetNamespace() {
return _wsdlDefinition.getTargetNamespace();
}
/**
* Change the port of the service.
*
* @param portName
* The new port name.
* @throws IllegalArgumentException
* if port name is not defined in WSDL.
*/
public void setPort( QName portName ) {
Port port = _service.getPort( portName.getLocalPart() );
if ( port == null ) {
throw new IllegalArgumentException( "Port name: '" + portName + "' was not found in the WSDL file." );
}
_port = port;
_operationCache.clear();
}
/**
* Get a WSDLReader.
*
* @return WSDLReader.
* @throws WSDLException
* on error.
*/
private WSDLReader getReader() throws WSDLException {
WSDLFactory wsdlFactory = WSDLFactory.newInstance();
WSDLReader wsdlReader = wsdlFactory.newWSDLReader();
ExtensionRegistry registry = wsdlFactory.newPopulatedExtensionRegistry();
wsdlReader.setExtensionRegistry( registry );
wsdlReader.setFeature( "javax.wsdl.verbose", true );
wsdlReader.setFeature( "javax.wsdl.importDocuments", true );
return wsdlReader;
}
/**
* Load and parse the WSDL file using the wsdlLocator.
*
* @param wsdlLocator
* A WSDLLocator instance.
* @param username
* to use for authentication
* @param password
* to use for authentication
* @return wsdl Definition.
* @throws WSDLException
* on error.
*/
private Definition parse( WSDLLocator wsdlLocator, String username, String password ) throws WSDLException,
KettleException, AuthenticationException {
WSDLReader wsdlReader = getReader();
try {
return wsdlReader.readWSDL( wsdlLocator );
} catch ( WSDLException we ) {
readWsdl( wsdlReader, wsdlURI.toString(), username, password );
return null;
}
}
/**
* Load and parse the WSDL file at the specified URI.
*
* @param wsdlURI
* URI of the WSDL file.
* @param username
* to use for authentication
* @param password
* to use for authentication
* @return wsdl Definition
* @throws WSDLException
* on error.
*/
private Definition parse( URI wsdlURI, String username, String password ) throws WSDLException, KettleException,
AuthenticationException {
WSDLReader wsdlReader = getReader();
return readWsdl( wsdlReader, wsdlURI.toString(), username, password );
}
private Definition readWsdl( WSDLReader wsdlReader, String uri, String username, String password ) throws WSDLException, KettleException, AuthenticationException {
try {
HTTPProtocol http = new HTTPProtocol();
Document doc = XMLHandler.loadXMLString( http.get( wsdlURI.toString(), username, password ), true, false );
if ( doc != null ) {
return ( wsdlReader.readWSDL( doc.getBaseURI(), doc ) );
} else {
throw new KettleException( "Unable to get document." );
}
} catch ( MalformedURLException mue ) {
throw new KettleException( mue );
} catch ( AuthenticationException ae ) {
// re-throw this. If not IOException seems to catch it
throw ae;
} catch ( IOException ioe ) {
throw new KettleException( ioe );
}
}
/**
* Returns this objects WSDL types.
*
* @return WsdlTepes
*/
public WsdlTypes getWsdlTypes() {
return this._wsdlTypes;
}
}