Hi, thanks for your reply.
I have check MessageHandlerChain code. Yes, you are right, jump to another chain is absolutely impossible, but this really happen now.
ErrorChannel only redirect to one transformers.
Code:
<transformer input-channel="error" method="getErrorCode"
output-channel="reply" ref="HeaderUnwrapper">
</transformer>
I am not doing manual bridging from 'avm.getApplicableAVM' or 'error' channel to 'fi.transaction.validate.submit.sell' channel.
I have try your recommendation to inspect every message in my SI.
Code:
<gateway id="avantradeGateway"
service-interface="jatis.avantrade.foundation.model.integration.AvantradeGateway"
default-request-channel="request" default-reply-channel="reply" />
<channel id="request">
<interceptors>
<wire-tap channel="logger"/>
<ref bean="JatisChannelInterceptor"/>
</interceptors>
</channel>
<channel id="reply">
<interceptors>
<wire-tap channel="logger"/>
<ref bean="JatisChannelInterceptor"/>
</interceptors>
</channel>
<channel id="error">
<interceptors>
<wire-tap channel="logger"/>
<ref bean="JatisChannelInterceptor"/>
</interceptors>
</channel>
<logging-channel-adapter id="logger" level="DEBUG" log-full-message="true"/>
I print every payload and message header using interceptor 'JatisChannelInterceptor'
Code:
public class JatisChannelInterceptor extends ChannelInterceptorAdapter {
private static final Logger logger = LogManager
.getLogger(JatisChannelInterceptor.class);
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
logger.info("start interceptor (preSend) at : " + new Date());
logger.info("preSend message : " + parseMessage(message));
logger.info("preSend channel : " + channel);
return super.preSend(message, channel);
}
@Override
public void postSend(Message<?> message, MessageChannel channel,
boolean sent) {
logger.info("start interceptor (postSend) at : " + new Date());
logger.info("postSend message : " + parseMessage(message));
logger.info("postSend channel : " + channel);
super.postSend(message, channel, sent);
}
@Override
public boolean preReceive(MessageChannel channel) {
logger.info("start interceptor (preReceive) at : " + new Date());
logger.info("preReceive channel : " + channel);
return super.preReceive(channel);
}
@Override
public Message<?> postReceive(Message<?> message, MessageChannel channel) {
logger.info("start interceptor (postReceive) at : " + new Date());
logger.info("postReceive message : " + parseMessage(message));
logger.info("postReceive channel : " + channel);
return super.postReceive(message, channel);
}
private String parseMessage(Message<?> message) {
StringBuilder sb = new StringBuilder();
sb.append("payload : " + message.getPayload());
sb.append("message header : " + message.getHeaders());
return sb.toString();
}
}
Also, I put interceptor in my customerContext.xml :
Code:
<channel id="customer.validate.insert">
<interceptors>
<ref bean="JatisChannelInterceptor" />
</interceptors>
</channel>
<channel id="customer.validate.delete">
<interceptors>
<ref bean="JatisChannelInterceptor" />
</interceptors>
</channel>
<chain input-channel="customer.validate.delete" output-channel="avm.getApplicableAVM">
<header-enricher>
<header name="ERROR_CODE" ref="customerEngine" method="checkDataVersion"
overwrite="true" />
</header-enricher>
<filter
expression="headers['ERROR_CODE'] == T(jatis.avantrade.foundation.model.constant.ReturnCode).VALID_DATA_VERSION"
discard-channel="error" />
<header-enricher>
<header name="ERROR_CODE" ref="customerEngine" method="checkPendingRecord"
overwrite="true" />
</header-enricher>
<filter
expression="headers['ERROR_CODE'] == T(jatis.avantrade.foundation.model.constant.ReturnCode).DATA_NOT_EXISTS_IN_PENDING_APPROVAL"
discard-channel="error" />
<header-enricher>
<header name="ERROR_CODE" ref="customerEngine" method="checkReferensialIntegrity"
overwrite="true" />
</header-enricher>
<filter
expression="headers['ERROR_CODE'] == T(jatis.avantrade.foundation.model.constant.ReturnCode).DATA_NOT_REFERENCED"
discard-channel="error" />
</chain>
Last day, this problem is happen again when I delete the customer.
Code:
2011-07-05 09:30:30,884 INFO [jatis.avantrade.foundation.model.integration.JatisChannelInterceptor] [t] - start interceptor (preSend) at : Tue Jul 05 09:30:30 WIT 2011
2011-07-05 09:30:30,884 INFO [jatis.avantrade.foundation.model.integration.JatisChannelInterceptor] [t] - preSend message : payload : jatis.avantrade.foundation.model.domain.Customer@31dd31ddmessage header : {MESSAGE_HEADER=jatis.avantrade.foundation.model.integration.MessageHeader@4a104a10, timestamp=1309833030715, replyChannel=org.springframework.integration.core.MessagingTemplate$TemporaryReplyChannel@4f244f24, id=cf46a551-5408-4af1-a014-3181238c7eaf, errorChannel=org.springframework.integration.core.MessagingTemplate$TemporaryReplyChannel@4f244f24, TRX_TYPE=DELETE_CUSTOMER}
2011-07-05 09:30:30,884 INFO [jatis.avantrade.foundation.model.integration.JatisChannelInterceptor] [t] - preSend channel : customer.validate.delete
2011-07-05 09:30:30,885 INFO [jatis.avantrade.foundation.model.engine.CustomerEngine] [t] - check version date
2011-07-05 09:30:30,885 DEBUG [java.sql.Connection ] [t] - ooo Connection Opened
2011-07-05 09:30:30,885 DEBUG [java.sql.PreparedStatement] [t] - ==> Executing: select LAST_VERSION_DATE from MST_CUSTOMERS where CUSTOMER_ID = ?
2011-07-05 09:30:30,885 DEBUG [java.sql.PreparedStatement] [t] - ==> Parameters: [B@4fc84fc8(byte[])
2011-07-05 09:30:30,886 DEBUG [java.sql.ResultSet ] [t] - <== Columns: LAST_VERSION_DATE
2011-07-05 09:30:30,886 DEBUG [java.sql.ResultSet ] [t] - <== Row: 2011-04-26 11:29:11.64
2011-07-05 09:30:30,886 DEBUG [java.sql.Connection ] [t] - xxx Connection Closed
2011-07-05 09:30:30,886 DEBUG [jatis.avantrade.foundation.model.dao.CustomerDAO] [t] - [getCustomerVersionDate] customerId:3fa523aa-f55a-4ebe-a97d-e55d5a138761 result:Tue Apr 26 11:29:11 WIT 2011
2011-07-05 09:30:30,886 INFO [jatis.avantrade.foundation.model.engine.CustomerEngine] [t] - date : Tue Apr 26 11:29:11 WIT 2011 prVersionDate : Tue Apr 26 11:29:11 WIT 2011
// this is checkPendingRecord log
2011-07-05 09:30:30,887 DEBUG [java.sql.Connection ] [t] - ooo Connection Opened
2011-07-05 09:30:30,887 DEBUG [java.sql.PreparedStatement] [t] - ==> Executing: select count(DATA_ID) from COM_RESERVED_CODES where DATA_ID = ? and ROWNUM = 1
// this should be checkReferensialIntegrity
2011-07-05 09:30:30,912 ERROR [jatis.avantrade.foundation.model.engine.CustomerEngine] [t] - org.springframework.integration.MessagingException: failed to transform message headers
org.springframework.integration.transformer.MessageTransformationException: org.springframework.integration.MessagingException: failed to transform message headers
at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:73)
.......// truncated
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 8): Method call: Method checkRemainingInventory(jatis.avantrade.foundation.model.domain.Customer) cannot be found on jatis.avantrade.fi.model.engine.IPOOrderEngine$$EnhancerByCGLIB$$13daefe4 type
at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:185)
It's jump to another chain :
Code:
<channel id="fi.transaction.validate.submit.ipo">
<interceptors>
<ref bean="JatisChannelInterceptor" />
</interceptors>
</channel>
<chain input-channel="fi.transaction.validate.submit.ipo"
output-channel="avm.getApplicableAVM">
<header-enricher>
<header name="ERROR_CODE" ref="IPOOrderEngine" method="checkOfferingPeriod"
overwrite="true" />
</header-enricher>
<filter
expression="headers['ERROR_CODE'] == T(jatis.avantrade.foundation.model.constant.ReturnCode).FI_IPO_IN_OFFERING_PERIOD"
discard-channel="error" />
<header-enricher>
<header name="ERROR_CODE" ref="IPOOrderEngine" method="checkRemainingInventory"
overwrite="true" />
</header-enricher>
<filter
expression="headers['ERROR_CODE'] == T(jatis.avantrade.foundation.model.constant.ReturnCode).FI_TRANSACTION_REMAINING_INVENTORY_VALID"
discard-channel="error" />
</chain>
No log for 'fi.transaction.validate.submit.ipo' channel because it seem 'customer.validate.delete' jump to checkRemainingInventory directly.
For this suggestion : trace the state of the Message going into 'fi.transaction.validate.submit.sell' channel.
Any suggestion how can I do that ?
I have no idea to trace message in that channel because from my explanation above, it's jump to another chain (no logger from my interceptor for that channel)
customer.validate.insert => checkDuplicateRecord => checkDuplicatePendingRecord => checkRemainingFaceValue
not
customer.validate.insert => checkDuplicateRecord => checkDuplicatePendingRecord => fi.transaction.validate.submit.sell => checkRemainingFaceValue
Thanks!