我正在尝试使用Switchyard创建透明代理。 这个想法是由Switchyard提供的“推广”服务。对此Web服务的调用将通过Camel重定向到服务引用。服务引用(代理服务)和提升的服务具有相同的WSDL。
问题是用户执行的SOAP调用在SOAP信封标头中包含一个不传播的自定义标记。我该如何解决?
SOAP调用示例(用户 - >传播服务):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.test/">
<soapenv:Header>
<token>foo</token>
</soapenv:Header>
<soapenv:Body>
<ser:readSomethings>
<something>
</something>
</ser:readSomethings>
</soapenv:Body>
</soapenv:Envelope>
SOAP调用Switchyard做的“代理”服务(它不包含令牌!!):
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ser:readSomethings xmlns:ser=\"http://service.test/\">
<something></something>
</ser:readSomethings>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
switchyard.xml:
<?xml version="1.0" encoding="ASCII"?>
<switchyard xmlns="urn:switchyard-config:switchyard:1.0" xmlns:bean="urn:switchyard-component-bean:config:1.0" xmlns:camel="urn:switchyard-component-camel:config:1.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:soap="urn:switchyard-component-soap:config:1.0" name="SomethingService" targetNamespace="urn:my.company.something:SomethingService:1.0">
<sca:composite name="SomethingService" targetNamespace="urn:my.company.something:SomethingService:1.0">
<sca:service name="PromotedProxyService" promote="ProxyService/ProxyService">
<soap:binding.soap>
<soap:contextMapper includes=".*"/>
<soap:wsdl>META-INF/SomethingWS.wsdl</soap:wsdl>
<soap:socketAddr>:${jettyPort}</soap:socketAddr>
<soap:contextPath>SomethingService</soap:contextPath>
</soap:binding.soap>
</sca:service>
<sca:reference name="ProxifiedService" multiplicity="0..1" promote="ProxyService/ProxifiedService">
<soap:binding.soap>
<soap:contextMapper includes=".*"/>
<soap:wsdl>META-INF/SomethingWS.wsdl</soap:wsdl>
<soap:endpointAddress>http://IP:8080/ws_admin/SomethingWS</soap:endpointAddress>
</soap:binding.soap>
</sca:reference>
<sca:component name="ProxyService">
<camel:implementation.camel>
<camel:java class="my.company.something.RouterCamel"/>
</camel:implementation.camel>
<sca:service name="ProxyService">
<sca:interface.wsdl interface="META-INF/SomethingWS.wsdl#wsdl.porttype(SomethingWS)"/>
</sca:service>
<sca:reference name="ProxifiedService">
<sca:interface.wsdl interface="META-INF/SomethingWS.wsdl#wsdl.porttype(SomethingWS)"/>
</sca:reference>
</sca:component>
</sca:composite>
<domain>
<properties>
<property name="org.switchyard.handlers.messageTrace.enabled" value="true"/>
</properties>
</domain>
</switchyard>
RouterCamel.java
public class RouterCamel extends org.apache.camel.builder.RouteBuilder{
public void configure() {
org.apache.camel.Processor myProc = new org.apache.camel.Processor(){
public void process(org.apache.camel.Exchange exchange) throws Exception {
System.out.println("------------------------------ ENTRO\n\n\n\n");
String body = exchange.getIn().getBody(String.class);
// change the message to say Hello
System.out.println("\n\n\n\n------------------------------ BODY: " + body);
exchange.getOut().setBody(body);
// copy headers from IN to OUT to propagate them
System.out.println("Header in values:");
for(Entry<String, Object> header: exchange.getIn().getHeaders().entrySet()){
System.out.println("Header: " + header.getKey() + " Value: " + header.getValue());
}
exchange.getOut().setHeaders(exchange.getIn().getHeaders());
System.out.println("Header out values:");
for(Entry<String, Object> header: exchange.getOut().getHeaders().entrySet()){
System.out.println("Header: " + header.getKey() + " Value: " + header.getValue());
}
}
};
// Define routing rules here:
from("switchyard://ProxyService").process(myProc).to("switchyard://ProxifiedService");
}
}
答案 0 :(得分:0)
标头未传播,因为它没有名称空间。
答案 1 :(得分:-1)
<sca:reference name="ProxyReference" multiplicity="0..1" promote="Proxy/ProxyService">
<sca:interface.wsdl interface="META-INF/wsdl/RegisterService.wsdl#wsdl.porttypePortType)"/>
<soap:binding.soap name="soap">
<soap:contextMapper class="WSHeaderContextMapper"/>
<soap:wsdl>META-INF/wsdl/RegisterService.wsdl</soap:wsdl>
<soap:endpointAddress>${service.address}</soap:endpointAddress>
<soap:timeout>12000</soap:timeout>
</soap:binding.soap>
</sca:reference>
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.message.WSSecUsernameToken;
import org.switchyard.Context;
import org.switchyard.component.soap.composer.SOAPBindingData;
import org.switchyard.component.soap.composer.SOAPContextMapper;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
public class WSHeaderContextMapper extends SOAPContextMapper {
private String user = "user";
private String password = "pass";
@Override
public void mapTo(Context context, SOAPBindingData target) throws Exception {
SOAPFactory factory = SOAPFactory.newInstance();
SOAPElement element = factory.createElement("Security", "wsse", WSConstants.WSSE_NS);
WSSecUsernameToken utBuilder = createUsernameToken(this.user, password);
utBuilder.prepare(element.getOwnerDocument());
element.addChildElement(factory.createElement(utBuilder.getUsernameTokenElement()));
context.setProperty(element.getElementQName().toString(), element);
super.mapTo(context, target);
}
private WSSecUsernameToken createUsernameToken(String userName, String password) {
WSSecUsernameToken utBuilder = new WSSecUsernameToken();
utBuilder.setUserInfo(userName, password);
utBuilder.setPasswordType(WSConstants.PASSWORD_TEXT);
return utBuilder;
}
}