When I try to assign a value to url-expression is working (Below working):
<bean id="requestData" class="net.model.RequestData"/>
<int-http:outbound-gateway request-channel="requestChannel"
url-expression="#requestData.getCompleteUrl()" http-method-expression="#requestData.getRequestMethod()"
expected-response-type="java.lang.String" header-mapper="headerMapper"
charset="UTF-8" reply-timeout="5000" reply-channel="responseChannel">
</int-http:outbound-gateway>
But when I try to assign a value in Header, it throws an Exception (below not working):
<int:gateway id="requestGateway" service-interface="net.model.RequestData" default-request-channel="jsonTransformationChannel">
<int:default-header name="X-MW-getId" value="#requestData.getId() />
<int:default-header name="X-Srcsys" value="ttsim" />
<int:default-header name="content-type" value="application/json" />
<int:default-header name="Accept" value="application/json" />
</int:gateway>
And I tried the lines below, but it didn't work:
<int:default-header name="X-MW-getId" expression="#requestData.id" />
This one must work:
<int:default-header name="X-MW-getId" expression="#requestData.id" />
It must be definitely an expression attribute and if you would like to get access to the requestData bean from there so that should be with the #. The getter indeed can be used as a property accessor.
Related
In Spring-integration Http request based on user logged in want to add dynamic header param.say for example if "A" user logged in & hitHttp request,now need to add dynamic 1 additional header,for others user,it should even the key too(i.e value as null)
For A user
<int:gateway id="requestGateway" service-interface="net.group.gateway.Gateway" default-request-channel="jsonTransformationChannel">
<int:default-header name="X-MW-LOGGEDID" expression="#requestData.getLoggedID()" />
<int:default-header name="X-Srcvalue" value="56789" />
<int:default-header name="content-type" value="application/json" />
<int:default-header name="Accept" value="application/json" />
</int:gateway>
For Other user
<int:gateway id="requestGateway" service-interface="net.group.gateway.Gateway" default-request-channel="jsonTransformationChannel">
<int:default-header name="X-MW-LOGGEDID" expression="#requestData.getLoggedID()" />
<int:default-header name="content-type" value="application/json" />
<int:default-header name="Accept" value="application/json" />
</int:gateway>
I guess the story is really about that X-Srcvalue. And since you say it's OK to null for anyone else, that would better to use an expression instead of value.
<int:default-header name="X-Srcvalue" expression="USER == A ? 56789 : null" />
In the expression you can use any bean in the application context to perform the logic any complexity.
Here is my spring configuration.
Spring.xml
-------------
<!-- Outgoing SOAP client endpoint -->
<cxf:cxfEndpoint id="serviceEndpoint" address="${endpointAddress}"
wsdlURL="${wsdlAddress}" endpointName="${portName}" serviceName="${serviceName}">
<!-- The interceptors - needed to log the SOAP requests and responses -->
<!-- They can be removed, when no logging is needed -->
<cxf:inInterceptors>
<ref bean="loggingInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outFaultInterceptors>
<cxf:inFaultInterceptors>
<ref bean="loggingInInterceptor" />
</cxf:inFaultInterceptors>
<cxf:properties>
<entry key="dataFormat" value="PAYLOAD" />
</cxf:properties>
</cxf:cxfEndpoint>
<http:conduit name="*.http-conduit">
<http:tlsClientParameters disableCNCheck="${disableHostnameCheck}">
<sec:keyManagers keyPassword="${keystorePassword}">
<sec:keyStore type="JKS" password="${keystorePassword}"
file="${keystoreLocation}" />
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="${truststorePassword}"
file="${truststoreLocation}" />
</sec:trustManagers>
<sec:cipherSuitesFilter>
<!-- these filters ensure that a ciphersuite with export-suitable or
null encryption is used, but exclude anonymous Diffie-Hellman key change
as this is vulnerable to man-in-the-middle attacks -->
<sec:include>.*_EXPORT_.*</sec:include>
<sec:include>.*_EXPORT1024_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:include>.*_WITH_AES_.*</sec:include>
<sec:include>.*_WITH_NULL_.*</sec:include>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http:tlsClientParameters>
<http:client AutoRedirect="true" Connection="Keep-Alive"
ReceiveTimeout="${connectionTimeout}" ConnectionTimeout="${connectionTimeout}" />
</http:conduit>
Here is the Camel route configuration
-------------
<from ...
<to uri="cxf:bean:serviceEndpoint" />
This works well and we can have the soap request/response logged into the log file. Here soap request with soap header is generated by cxf.
Do we have a way to capture the soap request and response into camel Exchange? I have to send an email attached with soap request and response if the service call is failed.
Have tried using thread local but it doesn't seems to work expected.
Suggestion:
You have it in CXF Interceptors - take a look at them.
I guess, you can send your e-mail out of it.
Start from org.apache.cxf.phase.AbstractPhaseInterceptor class - there are bunch of different ones for different phases.
P.S. From first glance org.apache.cxf.binding.soap.saaj.SAAJInInterceptor and
org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor could be good candidates...
Using below configuration:
<camel:camelContext>
<camel:template id="camelProcessTemplate" />
<camel:endpoint id="asyncEndpoint" uri="seda:asyncQueue" />
<camel:endpoint id="calcWeightEndpoint" uri="direct:calculateWeightIn" />
<camel:route id="route1">
<camel:from ref="..." />
<camel:to ref="asyncEndpoint" />
</camel:route>
<camel:route id="route2">
<camel:from ref="asyncEndpoint" />
<camel:to ref="calcWeightEndpoint" />
</camel:route>
<camel:route id="route3">
<camel:from ref="calcWeightEndpoint" />
<camel:process ref="..." />
<camel:to ref="..." />
</camel:route>
</camel:camelContext>
The message is entering into route2 but is not getting passed to route3.
You should use the uri attributes instead of the ref attributes in your froms and tos:
<camel:to uri="direct:calculateWeightIn" />
Also, it's possible that your processor in route3 is failing and not logging properly. Maybe add a <camel:log /> step between the from and the process.
EDIT 1: OP updated the question to correct their code block.
Could you please add a <camel:log /> between the from and the process, to verify whether the message is arriving in route3? The problem may be in your processor, as I said above.
Can I send distinct messages (distinct serialize/deserialize) to the same tcp server (same host and port) and differentiate the tcp-inbound-gateway by some value of header or payload with a router???
(...)
I want to add a router for select the correct tcp-inbound-gateway depends on some field in header or payload (for example named typedata). In what order would enter the request (or message) between router, tcp-inbound-gateway, tcp-connection-factory, serialize/deserialize? Will I have problems with the serialization/deserialization for chose the tcp-inbound-gateway? What is the correct way to do this?
Thanks in advance.
EDIT
In server:
<!-- Common -->
<int:channel id="channelConnectionFactoryRequest" />
<int:channel id="channelConnectionFactoryResponse" />
<router method="getDestinationChannel"
input-channel="channelSConnectionFactoryRequest">
<beans:bean class="org.mbracero.integration.CustomRouter" />
</router>
<beans:bean id="customSerializerDeserializer"
class="org.mbracero.integration.serialization.CustomSerializerDeserializer" />
<int-ip:tcp-connection-factory id="customConnectionFactory"
type="server" port="${payment.port}" single-use="true"
serializer="customSerializerDeserializer"
deserializer="customSerializerDeserializer" />
<int-ip:tcp-inbound-gateway id="customInboundGateway"
connection-factory="customConnectionFactory"
request-channel="channelCustomConnectionFactoryRequest"
reply-channel="channelCustomConnectionFactoryResponse"
error-channel="errorChannel" />
<!-- Custom -->
<beans:bean id="operations"
class="org.mbracero.integration.applepay.impl.OperationsImpl" />
<!-- Operation One -->
<int:channel id="operationOneRequest" />
<int:service-activator input-channel="operationOneRequest"
output-channel="operationOneResponse" ref="operations" method="getOperationOne" />
<!-- Operation Two -->
<int:channel id="operationTwoRequest" />
<int:service-activator input-channel="operationTwoRequest"
output-channel="operationTwoResponse" ref="operations" method="getOperationTwo" />
OperationsImpl:
ResultOne getOperationOne(RequestOne request);
ResultTwo getOperationOne(RequestTwo request);
ResultOne & ResultTwo implements ResultBase. And in serialize of customSerializerDeserializer I have:
#Override
public void serialize(ResultBase arg0, OutputStream arg1) throws IOException {
byte[] xxx = XXX.getBytes();
arg1.write(xxx);
byte[] yyy = yyy.getBytes();
arg1.write(senderName);
// **Each custom object have a method for serialize their own data**
arg0.transformDataToByte(arg1);
arg1.flush();
}
In client:
<gateway id="tmGateway"
service-interface="org.mbracero.integration.CustomGateway" />
<beans:bean id="operationOneSerializerDeserializer"
class="org.mbracero.integration.serialization.OperationOneSerializerDeserializer" />
<int-ip:tcp-connection-factory id="operationOneFactory"
type="client" host="127.0.0.1" port="7878" single-use="true"
serializer="operationOneSerializerDeserializer" deserializer="operationOneSerializerDeserializer" />
<int-ip:tcp-outbound-gateway id="operationOneOutGateway"
request-channel="operationOneChannel" connection-factory="operationOneFactory"
request-timeout="5000" reply-timeout="5000" remote-timeout="5000" />
<beans:bean id="operationTwoSerializerDeserializer"
class="org.mbracero.integration.operationTwoRequestSerializerDeserializer"/>
<int-ip:tcp-connection-factory id="operationTwoFactory"
type="client" host="127.0.0.1" port="7878" single-use="true"
serializer="operationTwoSerializerDeserializer"
deserializer="operationTwoSerializerDeserializer" />
<int-ip:tcp-outbound-gateway id="operationTwoOutGateway"
request-channel="operationTwoChannel" connection-factory="operationTwoFactory"
request-timeout="50000" reply-timeout="50000" remote-timeout="50000" />
CustomGateway:
#Gateway(requestChannel="operationOneChannel")
OperationOneResponse sendOperationOne(OperationOneRequest request);
#Gateway(requestChannel="operationTwoChannel")
OperationTwoResponse sendOperationTwo(OperationTwo request);
You cannot have 2 server connection factories listening on the same port. TCP doesn't allow it - the network stack wouldn't know which server socket to route the request to.
There's no problem on the client side but, with a single socket, the server would have to understand how to deserialize both data types.
It's probably easier to combine the serializers/deserializers into one on both sides (add another header to the message so the deserializer knows what type of payload to decode).
I have got data from RSAQ_REMOTE_QUERY_CALL in xml data. I need to format that data in grid view. In that tag gives column value and tag gives Feild description respectively Below i have mentioned my xml data.
?xml version="1.0" encoding="UTF-8" ?>
TABLES>
FPAIRS>
item>
INDEX_A>0007</INDEX_A>
INDEX_U>0008 /INDEX_U>
TYPE>E/TYPE>
/item>
/FPAIRS>
LDATA>
item>
LINE>002:OR,004:0001,002:01,007:SCEM_02,000:, 002:PC;/</LINE>
/item>
/LDATA>
LISTDESC>
item>
FADD />
FDESC>Sales Organization</FDESC>
FNAME>VBAK-VKORG</FNAME>
FCOL>SOrg.</FCOL>
FNAMENEW>VBAK-VKORG</FNAMENEW>
FNAMEINT>VKORG</FNAMEINT>
FKEY />
FGTYP />
FNZERO />
FSUM />
FSONLY />
FSORT>00</FSORT>
FSODS />
FSUBT />
FLPOS>0002</FLPOS>
FNUMB>98</FNUMB>
FNUMBT />
FNOSUM />
FSONP />
/item>
item>
FADD />
FDESC>Distribution Channel</FDESC>
FNAME>VBAK-VTWEG</FNAME>
FCOL>DChl</FCOL>
FNAMENEW>VBAK-VTWEG</FNAMENEW>
FNAMEINT>VTWEG</FNAMEINT>
FKEY />
FGTYP />
FNZERO />
FSUM />
FSONLY />
FSORT>00</FSORT>
FSODS />
FSUBT />
FLPOS>0003</FLPOS>
FNUMB>98</FNUMB>
FNUMBT />
FNOSUM />
FSONP />
/item>
item>
FADD />
FDESC>Division</FDESC>
FNAME>VBAK-SPART</FNAME>
FCOL>Dv</FCOL>
FNAMENEW>VBAK-SPART</FNAMENEW>
FNAMEINT>SPART</FNAMEINT>
FKEY />
FGTYP />
FNZERO />
FSUM />
FSONLY />
FSORT>00</FSORT>
FSODS />
FSUBT />
FLPOS>0004</FLPOS>
FNUMB>98/FNUMB>
FNUMBT />
FNOSUM />
FSONP />
/item>
item>
FADD />
FDESC>Sold-to party/FDESC>
FNAME>VBAK-KUNNR/FNAME>
FCOL>Sold-to pt/FCOL>
FNAMENEW>VBAK-KUNNR/FNAMENEW>
FNAMEINT>KUNNR/FNAMEINT>
FKEY />
FGTYP />
FNZERO />
FSUM />
FSONLY />
FSORT>00</FSORT>
FSODS />
FSUBT />
FLPOS>0005</FLPOS>
FNUMB>98</FNUMB>
FNUMBT />
FNOSUM />
FSONP />
/item>
item>
FADD />
FDESC>Material Number Used by Customer/FDESC>
FNAME>VBAP-KDMAT/FNAME>
FCOL>Customer Material Number/FCOL>
FNAMENEW>VBAP-KDMAT/FNAMENEW>
FNAMEINT>KDMAT/FNAMEINT>
FKEY />
FGTYP />
FNZERO />
FSUM />
FSONLY />
FSORT>00</FSORT>
FSODS />
FSUBT />
FLPOS>0006</FLPOS>
FNUMB>98</FNUMB>
FNUMBT />
FNOSUM />
FSONP />
/item>
item>
FADD />
FDESC>Net Weight of the Item/FDESC>
FNAME>VBAP-NTGEW/FNAME>
FCOL>Net weight/FCOL>
FNAMENEW>VBAP-NTGEW/FNAMENEW>
FNAMEINT>NTGEW/FNAMEINT>
FKEY />
FGTYP />
FNZERO />
FSUM />
FSONLY />
FSORT>00</FSORT>
FSODS />
FSUBT />
FLPOS>0007</FLPOS>
FNUMB>98</FNUMB>
FNUMBT />
FNOSUM />
FSONP />
/item>
/LISTDESC>
SELECTION_TABLE />
/TABLES>
I need get output as like below format.
Output:
Sales Organization
Distribution Channel
Division
Sold-to party
Material Number Used by Customer
Net Weight of the Item
OR
0001
01
SCEM_02
null
PC
Please suggest me how to get this grid format from my xml data. Please reply as soon as possible.
Thanks in advance:)
Regards,
Joy
You didn't mention any language so i can't give you a concrete example, but basically every modern language has an XML parser, so just use the parser to get data from the xml and then you can put that data in wahtever format you like, including Grid format.
Update:
You need several things here:
If the xml's have a unified format (they all have the same
structure) you can get an XSD or write one (XSD Tutorials) and then
you can use a framework like XmlBeans to generate java objects from
the schema and work with them. That would be the easiest way.
The other option is to use the java DOM API. The API is a bit ugly
but once you get used to it it's not that hard. Problem is that you
need to take care of every xml structure manually.
what ever method you choose, once you parsed the XML you can access the data and do whatever you like with it.
Search for XML parser's, and you should be able to do the rest.
DOM should be able to do the trick for the above format