将Camel的Java实现从2.13.0升级到2.17.2(cxf-rt-frontend-jaxrs从2.7.10升级到3.1.5,弹簧框架从3.2.8升级到4.3.2),作为代理的webapp停止正常工作。
该应用程序应拦截Web服务请求,修改通过ContextManager类在属性文件中定义的字段,并将请求转发到正确的端点。
升级后,应用程序无法在原始请求中设置缺少的字段,从而返回以下消息:“REQUEST_MESSAGE_NOT_COMPLIANT_WITH_SCHEMA - 您的请求消息不符合Web服务架构”。
这当然是预期的,因为没有设置缺少的字段。
非常感谢任何帮助。
更新
问题似乎来自xpath方法,该方法在之前的版本中返回了正确的节点,其中需要设置一些信息,现在返回null。
我的Camel路线定义如下:
CreditLimitRequestServiceRoute.class
public class CreditLimitRequestServiceRoute extends AbstractEHRoute {
@Autowired
private ContextManager contextManager;
@Override
public void configure() throws Exception {
Namespaces ns = new Namespaces("ns1", "http://ehsmartlink/commonError");
onException(SoapFault.class)
.to("consoleflux:message?level=ERROR&text=${exception.message}&content=${exception.detail}")
.setHeader("soapFaultDetail", simple("${exception.detail}"))
.choice()
.when(and(header("soapFaultDetail").isNotNull(), xpath("//ns1:commonError/errorType/text() = 'BusinessError'", ns, "soapFaultDetail")))
.to("consoleflux:finish?ignoreContent=true")
.otherwise()
.to("consoleflux:error?ignoreContent=true");
onException(Exception.class)
.to("consoleflux:error");
from("cxf:bean:creditLimitRequestServiceProxy?dataFormat=PAYLOAD").routeId("creditLimitRequestServiceRoute")
.log(LoggingLevel.INFO, "Invocation du WS").streamCaching()
.to("consoleflux:start?source=SOA&dest=EH&type=CREDIT_LIMIT")
.to("consoleflux:message?ignoreContent=true&text=Affectation du Contexte EH")
.setHeader("context").xpath("//context")
.bean(contextManager, "setContext")
.to("consoleflux:message?ignoreContent=true&text=Invocation du WS EH ${headers.operationName}")
.to("cxf:bean:creditLimitRequestService?dataFormat=PAYLOAD")
.to("consoleflux:finish");
}
}
AbstractEHRoute.class
public abstract class AbstractEHRoute extends RouteBuilder {
protected XPathBuilder xpath(String text, Namespaces namespaces, String headerName) {
XPathBuilder xpath = XPathBuilder.xpath(text).namespaces(namespaces);
xpath.setHeaderName(headerName);
return xpath;
}
}
ContextManager
package com.stef.soa.eh.integration.beans;
import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import java.util.Map;
import java.util.UUID;
import org.apache.camel.Header;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
@Component
public class ContextManager {
private static final String USER_NAME = "userName";
private static final String USER_PASSWORD = "userPassword";
private static final String LANGUAGE_TEXT_IDENTIFIER = "languageTextIdentifier";
private static final String TRANSACTION_IDENTIFIER = "transactionIdentifier";
private static final String POLICIY_IDENTIFIER = "policyIdentifier";
private static final String POLICY_EXTENSION_IDENTIFIER = "policyExtensionIdentifier";
private static final String POLICY_EHBU_IDENTIFIER = "policyEHBUIdentifier";
private static final String IP_ADRESS = "ipAdress";
@Value("${eh.context.userName}")
private String userName;
@Value("${eh.context.userPassword}")
private String userPassword;
@Value("${eh.context.languageTextIdentifier}")
private String languageTextIdentifier;
@Value("${eh.context.policyIdentifier}")
private String policyIdentifier;
@Value("${eh.context.policyExtensionIdentifier}")
private String policyExtensionIdentifier;
@Value("${eh.context.policyEHBUIdentifier}")
private String policyEHBUIdentifier;
@Value("${eh.context.ipAdress}")
private String ipAdress;
public void setContext(@Header("context") Node context) {
Preconditions.checkNotNull(context, "Le contexte doit être renseigné");
// Suppression des noeuds enfants avec sauvegarde les valeurs courantes dans une map
Map<String, String> currentValues = Maps.newHashMap();
NodeList list = context.getChildNodes();
for (int i = list.getLength() - 1; i >= 0; i--) {
Node child = list.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE && !isNullOrEmpty(child.getTextContent())) {
currentValues.put(child.getNodeName(), child.getTextContent());
}
context.removeChild(child);
}
// Ajout des noeuds enfants
appendChild(context, USER_NAME, userName, currentValues);
appendChild(context, USER_PASSWORD, userPassword, currentValues);
appendChild(context, LANGUAGE_TEXT_IDENTIFIER, languageTextIdentifier, currentValues);
appendChild(context, TRANSACTION_IDENTIFIER, UUID.randomUUID().toString(), currentValues);
appendChild(context, POLICIY_IDENTIFIER, policyIdentifier, currentValues);
appendChild(context, POLICY_EXTENSION_IDENTIFIER, policyExtensionIdentifier, currentValues);
appendChild(context, POLICY_EHBU_IDENTIFIER, policyEHBUIdentifier, currentValues);
appendChild(context, IP_ADRESS, ipAdress, currentValues);
}
private void appendChild(Node node, String name, String value, Map<String, String> currentValues) {
Document document = node.getOwnerDocument();
Element child = document.createElement(name);
child.setTextContent(firstNonNull(currentValues.get(name), value));
node.appendChild(child);
}
}
的context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:eh.properties, file:///${eh.home}/conf/eh.properties"
ignore-resource-not-found="true" system-properties-mode="OVERRIDE" />
<context:component-scan base-package="com.stef.soa.eh" />
<context:annotation-config />
<import resource="classpath:META-INF/eh/spring/broker.xml" />
<import resource="classpath:META-INF/eh/spring/camel.xml" />
<import resource="classpath:META-INF/eh/spring/cxf.xml" />
<import resource="classpath:META-INF/soa-console-flux-client/spring/context.xml"/>
</beans>
camel.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd" >
<!-- Camel Context -->
<camelContext xmlns="http://camel.apache.org/schema/spring" id="ehContext">
<properties>
<property key="org.apache.camel.xmlconverter.output.indent" value="yes"/>
<property key="org.apache.camel.xmlconverter.output.{http://xml.apache.org/xslt}indent-amount" value="4"/>
</properties>
<package>com.stef.soa.eh.integration</package>
</camelContext>
</beans>
cxf.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd" >
<!-- Serveur Proxy, Certificat -->
<http:conduit name="*.http-conduit">
<http:client ProxyServer="${proxy.host}" ProxyServerPort="${proxy.port}"
ConnectionTimeout="${http.client.connectionTimeout}" ReceiveTimeout="${http.client.receiveTimeout}" />
<http:proxyAuthorization>
<sec:UserName>${proxy.username}</sec:UserName>
<sec:Password>${proxy.password}</sec:Password>
</http:proxyAuthorization>
<http:tlsClientParameters>
<sec:keyManagers keyPassword="${eh.keyStore.password}">
<sec:keyStore type="pkcs12" password="${eh.keyStore.password}" file="${eh.home}/${eh.keyStore.file}" />
</sec:keyManagers>
</http:tlsClientParameters>
</http:conduit>
<!-- Services Proxy et Cible -->
<cxf:cxfEndpoint
id="creditLimitRequestServiceProxy"
address="/creditLimitRequestService"
wsdlURL="META-INF/eh/wsdl/CreditLimitRequestService/EH_SMARTLINK_CreditLimitRequestServiceV4.wsdl"
serviceName="ns:CreditLimitRequestServiceV4"
endpointName="ns:CreditLimitRequestServiceV4"
xmlns:ns="http://ehsmartlink/CreditLimitRequestService/v4"
/>
<cxf:cxfEndpoint
id="creditLimitRequestService"
address="${eh.creditLimitRequestService.url}"
wsdlURL="META-INF/eh/wsdl/CreditLimitRequestService/EH_SMARTLINK_CreditLimitRequestServiceV4.wsdl"
serviceName="ns:CreditLimitRequestServiceV4"
endpointName="ns:CreditLimitRequestServiceV4"
xmlns:ns="http://ehsmartlink/CreditLimitRequestService/v4"
loggingFeatureEnabled="true"
/>
<cxf:cxfEndpoint
id="customerListRetrieveServiceProxy"
address="/customerListRetrieveService"
wsdlURL="META-INF/eh/wsdl/CustomerListRetrieveService/CustomerListRetrieveV2.wsdl"
serviceName="ns:CustomerListRetrieveServiceV2"
endpointName="ns:CustomerListRetrieveServiceV2"
xmlns:ns="http://ehsmartlink/CustomerListRetrieve/v2"
/>
<cxf:cxfEndpoint
id="customerListRetrieveService"
address="${eh.customerListRetrieveService.url}"
wsdlURL="META-INF/eh/wsdl/CustomerListRetrieveService/CustomerListRetrieveV2.wsdl"
serviceName="ns:CustomerListRetrieveServiceV2"
endpointName="ns:CustomerListRetrieveServiceV2"
xmlns:ns="http://ehsmartlink/CustomerListRetrieve/v2"
loggingFeatureEnabled="true"
/>
<cxf:cxfEndpoint
id="firstEuroListRepertoireReadServiceProxy"
address="/firstEuroListRepertoireReadService"
wsdlURL="META-INF/eh/wsdl/FirstEuroListRepertoireReadService/EH_SMARTLINK_FirstEuroListRepertoireReadService-v1.wsdl"
serviceName="ns:FirstEuroListRepertoireReadService-v1"
endpointName="ns:FirstEuroListRepertoireReadServicePort-v1_soap11"
xmlns:ns="http://eulerhermes.com/SMARTLINK/services/FirstEuroListRepertoireReadService/v1"
/>
<cxf:cxfEndpoint
id="firstEuroListRepertoireReadService"
address="${eh.firstEuroListRepertoireReadService.url}"
wsdlURL="META-INF/eh/wsdl/FirstEuroListRepertoireReadService/EH_SMARTLINK_FirstEuroListRepertoireReadService-v1.wsdl"
serviceName="ns:FirstEuroListRepertoireReadService-v1"
endpointName="ns:FirstEuroListRepertoireReadServicePort-v1_soap11"
xmlns:ns="http://eulerhermes.com/SMARTLINK/services/FirstEuroListRepertoireReadService/v1"
loggingFeatureEnabled="true"
/>
<cxf:cxfEndpoint
id="firstEuroListRepertoireUpdateServiceProxy"
address="/firstEuroListRepertoireUpdateService"
wsdlURL="META-INF/eh/wsdl/FirstEuroListRepertoireUpdateService/EH_SMARTLINK_FirstEuroListRepertoireUpdateService-v1.wsdl"
serviceName="ns:FirstEuroListRepertoireUpdateService-v1"
endpointName="ns:FirstEuroListRepertoireUpdateServicePort-v1"
xmlns:ns="http://eulerhermes.com/SMARTLINK/services/FirstEuroListRepertoireUpdateService/v1"
/>
<cxf:cxfEndpoint
id="firstEuroListRepertoireUpdateService"
address="${eh.firstEuroListRepertoireUpdateService.url}"
wsdlURL="META-INF/eh/wsdl/FirstEuroListRepertoireUpdateService/EH_SMARTLINK_FirstEuroListRepertoireUpdateService-v1.wsdl"
serviceName="ns:FirstEuroListRepertoireUpdateService-v1"
endpointName="ns:FirstEuroListRepertoireUpdateServicePort-v1"
xmlns:ns="http://eulerhermes.com/SMARTLINK/services/FirstEuroListRepertoireUpdateService/v1"
loggingFeatureEnabled="true"
/>
<cxf:cxfEndpoint
id="limitDetailReadServiceProxy"
address="/limitDetailReadService"
wsdlURL="META-INF/eh/wsdl/LimitDetailReadService/EH_SMARTLINK_LimitDetailReadService-v2.wsdl"
serviceName="ns:LimitDetailReadService-v2"
endpointName="ns:LimitDetailReadServicePort-v2"
xmlns:ns="http://eulerhermes.com/SMARTLINK/services/LimitDetailReadService/v2"
/>
<cxf:cxfEndpoint
id="limitDetailReadService"
address="${eh.limitDetailReadService.url}"
wsdlURL="META-INF/eh/wsdl/LimitDetailReadService/EH_SMARTLINK_LimitDetailReadService-v2.wsdl"
serviceName="ns:LimitDetailReadService-v2"
endpointName="ns:LimitDetailReadServicePort-v2"
xmlns:ns="http://eulerhermes.com/SMARTLINK/services/LimitDetailReadService/v2"
loggingFeatureEnabled="true"
/>
</beans>