org.apache.servicemix.http.endpoints.HttpSoapProviderEndpoint Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.servicemix.http.endpoints;
import java.io.InputStream;
import javax.jbi.management.DeploymentException;
import javax.jbi.servicedesc.ServiceEndpoint;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.xml.namespace.QName;
import org.w3c.dom.Element;
import org.apache.servicemix.common.DefaultComponent;
import org.apache.servicemix.common.ServiceUnit;
import org.apache.servicemix.soap.api.Policy;
import org.apache.servicemix.soap.util.DomUtil;
import org.apache.servicemix.soap.wsdl.BindingFactory;
import org.apache.servicemix.soap.wsdl.WSDLUtils;
import org.apache.servicemix.soap.wsdl.validator.WSIBPValidator;
import org.apache.woden.WSDLFactory;
import org.apache.woden.WSDLReader;
import org.apache.woden.types.NCName;
import org.apache.woden.wsdl20.Description;
import org.apache.woden.wsdl20.Endpoint;
import org.apache.woden.wsdl20.xml.DescriptionElement;
import org.springframework.core.io.Resource;
import org.xml.sax.InputSource;
/**
* An HTTP provider endpoint optimized to work with SOAP messages. This type of endpoint requires the use of WSDL.
*
* @author gnodet
* @since 3.2
* @org.apache.xbean.XBean element="soap-provider" description=
* "an HTTP provider endpoint that is optimaized to work with SOAP messages."
*/
public class HttpSoapProviderEndpoint extends HttpProviderEndpoint {
private Resource wsdl;
private boolean useJbiWrapper = true;
private boolean validateWsdl = true;
private Policy[] policies;
public HttpSoapProviderEndpoint() {
super();
}
public HttpSoapProviderEndpoint(DefaultComponent component, ServiceEndpoint endpoint) {
super(component, endpoint);
}
public HttpSoapProviderEndpoint(ServiceUnit serviceUnit, QName service, String endpoint) {
super(serviceUnit, service, endpoint);
}
/**
* Gets the WSDL document needed by an endpoint.
*
* @return a Resource
containing the WSDL document
*/
public Resource getWsdl() {
return wsdl;
}
/**
* Sets the WSDL document needed by an endpoint.
*
* @param wsdl a Resource
containing the WSDL document
* @org.apache.xbean.Property description= "the URL of the WSDL document defining the endpoint's messages"
*/
public void setWsdl(Resource wsdl) {
this.wsdl = wsdl;
}
/**
* Determines if the WSDL will be checked for WS-I basic profile compliance.
*
* @return true if the WSDL is to be validated
*/
public boolean isValidateWsdl() {
return validateWsdl;
}
/**
* Specifies if an endpoint's WSDL document should be validated for WS-I basic profile compliance. Validation provides some
* assurence that the WSDL will be consumable by most Web services. However, validation is expensive.
*
* @param validateWsdl a boolean specifying if the WSDL document is to be validated
* @org.apache.xbean.Property description="Specifies if the WSDL is checked for WSI-BP compliance. Default is true
* ."
*/
public void setValidateWsdl(boolean validateWsdl) {
this.validateWsdl = validateWsdl;
}
/**
* Determines if the endpoint wraps SOAP messages in the JBI wrapper.
*
* @return a boolean specifying if the endpoint uses the JBI wrapper
*/
public boolean isUseJbiWrapper() {
return useJbiWrapper;
}
/**
* Specifies if an endpoint wraps SOAP messages in the JBI wrapper.
*
* @param useJbiWrapper a boolean specifying if the endpoint should use the JBI wrapper
* @org.apache.xbean.Property description="Specifies if the JBI wrapper is sent in the body of the message. Default is
* true
."
*/
public void setUseJbiWrapper(boolean useJbiWrapper) {
this.useJbiWrapper = useJbiWrapper;
}
public Policy[] getPolicies() {
return policies;
}
/**
* Specifies a list of interceptors that will process messages for the endpoint.
*
* @param policies an array of Policy
objects
* @org.apache.xbean.Property description="a list of interceptors that will process messages"
*/
public void setPolicies(Policy[] policies) {
this.policies = policies;
}
@Override
public void validate() throws DeploymentException {
if (wsdl == null) {
throw new DeploymentException("wsdl property must be set");
}
HttpSoapProviderMarshaler marshaler;
if (getMarshaler() instanceof HttpSoapProviderMarshaler) {
marshaler = (HttpSoapProviderMarshaler)getMarshaler();
} else if (getMarshaler() == null) {
marshaler = new HttpSoapProviderMarshaler();
} else {
throw new DeploymentException("The configured marshaler must inherit HttpSoapProviderMarshaler");
}
try {
description = DomUtil.parse(wsdl.getInputStream());
Element elem = description.getDocumentElement();
if (WSDLUtils.WSDL1_NAMESPACE.equals(elem.getNamespaceURI())) {
validateWsdl1(marshaler);
} else if (WSDLUtils.WSDL2_NAMESPACE.equals(elem.getNamespaceURI())) {
validateWsdl2(marshaler);
} else {
throw new DeploymentException("Unrecognized wsdl namespace: " + elem.getNamespaceURI());
}
marshaler.setUseJbiWrapper(useJbiWrapper);
marshaler.setPolicies(policies);
setMarshaler(marshaler);
} catch (DeploymentException e) {
throw e;
} catch (Exception e) {
throw new DeploymentException("Unable to read WSDL from: " + wsdl, e);
}
super.validate();
}
protected void validateWsdl1(HttpSoapProviderMarshaler marshaler) throws Exception {
InputStream is = wsdl.getInputStream();
try {
InputSource inputSource = new InputSource(is);
inputSource.setSystemId(wsdl.getURL().toString());
Definition def = WSDLUtils.createWSDL11Reader().readWSDL(wsdl.getURL().toString(), inputSource);
if (validateWsdl) {
WSIBPValidator validator = new WSIBPValidator(def);
if (!validator.isValid()) {
throw new DeploymentException("WSDL is not WS-I BP compliant: " + validator.getErrors());
}
}
Service svc;
if (getService() != null) {
svc = def.getService(getService());
if (svc == null) {
throw new DeploymentException("Could not find service '" + getService() + "' in wsdl");
}
} else if (def.getServices().size() == 1) {
svc = (Service)def.getServices().values().iterator().next();
setService(svc.getQName());
} else {
throw new DeploymentException(
"If service is not set, the WSDL must contain a single service definition");
}
Port port;
if (getEndpoint() != null) {
port = svc.getPort(getEndpoint());
if (port == null) {
throw new DeploymentException("Cound not find port '" + getEndpoint() + "' "
+ "in wsdl for service '" + getService() + "'");
}
} else if (svc.getPorts().size() == 1) {
port = (Port)svc.getPorts().values().iterator().next();
setEndpoint(port.getName());
} else {
throw new DeploymentException("If endpoint is not set, the WSDL service '" + getService()
+ "' " + "must contain a single port definition");
}
SOAPAddress sa11 = WSDLUtils.getExtension(port, SOAPAddress.class);
SOAP12Address sa12 = WSDLUtils.getExtension(port, SOAP12Address.class);
if (getLocationURI() != null) {
marshaler.setBaseUrl(getLocationURI());
} else if (sa11 != null) {
marshaler.setBaseUrl(sa11.getLocationURI());
} else if (sa12 != null) {
marshaler.setBaseUrl(sa12.getLocationURI());
} else {
throw new DeploymentException("No locationURI set and no SOAP address defined on port '"
+ port.getName() + "'");
}
description = WSDLUtils.getWSDL11Factory().newWSDLWriter().getDocument(def);
marshaler.setBinding(BindingFactory.createBinding(port));
} finally {
is.close();
}
}
protected void validateWsdl2(HttpSoapProviderMarshaler marshaler) throws Exception {
new Wsdl2Validator().validate(marshaler);
}
/**
* Use an inner class to avoid having a strong dependency on Woden if not needed
*/
protected class Wsdl2Validator {
public void validate(HttpSoapProviderMarshaler marshaler) throws Exception {
WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
reader.setFeature(WSDLReader.FEATURE_VERBOSE, false);
DescriptionElement descElement = reader.readWSDL(wsdl.getURL().toString());
Description desc = descElement.toComponent();
org.apache.woden.wsdl20.Service svc;
if (getService() != null) {
svc = desc.getService(getService());
if (svc == null) {
throw new DeploymentException("Could not find service '" + getService() + "' in wsdl");
}
} else if (desc.getServices().length == 1) {
svc = desc.getServices()[0];
setService(svc.getName());
} else {
throw new DeploymentException(
"If service is not set, the WSDL must contain a single service definition");
}
Endpoint endpoint;
if (getEndpoint() != null) {
endpoint = svc.getEndpoint(new NCName(getEndpoint()));
if (endpoint == null) {
throw new DeploymentException("Cound not find endpoint '" + getEndpoint()
+ "' in wsdl for service '" + getService() + "'");
}
} else if (svc.getEndpoints().length == 1) {
endpoint = svc.getEndpoints()[0];
setEndpoint(endpoint.getName().toString());
} else {
throw new DeploymentException("If endpoint is not set, the WSDL service '" + getService()
+ "' " + "must contain a single port definition");
}
marshaler.setBinding(BindingFactory.createBinding(endpoint));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy