pass message to producer through jms - jms

How to pass a message to producer(a method defined to sent message to activemq) through spring integration.
Actual requirement is, i need insert data to database and that data to be moved to a queue in activemq,both the operations need to be happened parallely. How can i do it.
<jms:message-driven-channel-adapter id="helloWorldJMSAdapater" destination="helloWorldJMSQueue" connection-factory="jmsConnectionFactory"
channel="postChannel" />
<int:channel id="requestChannel" />
<int:channel id="outputChannel" />
<int-http:inbound-gateway request-channel="requestChannel"
reply-channel="outputChannel" supported-methods="GET" path="/register"
view-name="register">
<int-http:request-mapping />
</int-http:inbound-gateway>
<int-http:inbound-gateway request-channel="postChannel"
reply-channel="outputChannel" supported-methods="POST" path="/registerNew"
error-channel="errorChannel" view-name="login">
</int-http:inbound-gateway>
<int-jdbc:outbound-channel-adapter
query="insert into user_registration (USER_FSTNAME,USER_ADDRESS,USER_STATE,USER_CITY,USER_OCCUPATION,USER_EMAIL,USER_CONTACT,USER_PASSWORD)
values (:fstName,:addrss,:state,:city,:occupation,:email,:contact,:password)"
channel="postChannel" data-source="dataSource" id="sample" sql-parameter-source-factory="spelSource" />
<int:service-activator ref="userService" input-channel="requestChannel"
output-channel="outputChannel" method="message"/>
<bean id="spelSource"
class="org.springframework.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory">
<property name="parameterExpressions">
<map>
<entry key="fstName" value="payload[firstName]" />
<entry key="lstName" value="payload[lastName]" />
<entry key="addrss" value="payload[address]" />
<entry key="state" value="payload[state]" />
<entry key="city" value="payload[city]" />
<entry key="occupation" value="payload[occupation]" />
<entry key="email" value="payload[email]"/>
<entry key="contact" value="payload[contact]"/>
<entry key="password" value="payload[password]"/>
</map>
</property>
</bean>

Use a <publish-subscribe-channel/> and subscribe both endpoints to it. They will be executed serially by default, or in parallel if you add a task-executor to the channel.

Related

How to use expression advice or error channel for exception handling?

I am new to spring integration. I have to handle few exceptions using spring integration.
we are using xml files for spring integration.
<int:chain id="sample-chain" input-channel="callTestChannel" output-channel="testResponseChannel">
<int:header-enricher>
<int:header name="Content-Type" value="application/json"/>
<int:header name="Accept" value="application/json"/>
</int:header-enricher>
<int-http:outbound-gateway id="testGateway"
url-expression="headers.externalUrl"
http-method="GET"
expected-response-type="com.example.test.TestProject"
charset="UTF-8"
request-factory="httpComponentClientRequestFactory"
mapped-request-headers="Content-Type,Accept"
reply-timeout="5000">
<int-http:uri-variable name="testId" expression="payload" />
<int-http:request-handler-advice-chain>
<bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="recoveryCallback">
<bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
<constructor-arg ref="retryErrorChannel" />
</bean>
</property>
<property name="retryTemplate" ref="retryLoadTemplate" />
</bean>
</int-http:request-handler-advice-chain>
</int-http:outbound-gateway>
<int:transformer ref="fetchDetailsTransformer" method="processServiceDetails" />
</int:chain>
<int:channel id="retryErrorChannel"/>
<int:transformer input-channel="retryErrorChannel" output-channel="markErrorChannel"
expression="payload.getFailedMessage()"/>
<int:transformer input-channel="markErrorChannel" output-channel="tmsResponseChannel"
expression="'this Id :' + payload + ' could not find.'"/>
<bean id="retryLoadTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="4" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="1000" />
<property name="multiplier" value="5" />
</bean>
</property>
</bean>
Can someone please help how to create error channel for handling different exceptions? can I use some property on int-http:outbound-gateway?
I have read at some places to use expression advice but did not find any examples about using it in xml files or how to use them at all? or if there is any easy way to handle exceptions?
The documentation for that advice is here: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#message-handler-advice-chain
Over here you can find some samples how to configure those advices: https://github.com/spring-projects/spring-integration-samples/tree/main/intermediate/retry-and-more

Spring Integration exception always not reaching errorChannel

<bean id="triggerFileScanner" class="abc.xyz">
<property name="triggerFile" value="value1" />
</bean>
<int-file:inbound-channel-adapter id="fileInbound" directory="somepath/directory" filter="acceptallFilter" scanner="triggerFileScanner"
auto-startup="true" channel="fileChannel">
<int:poller max-messages-per-poll="10" time-unit="SECONDS" fixed-delay="10" receive-timeout="30000" />
</int-file:inbound-channel-adapter>
<int:header-enricher id="headerEnricher" input-channel="fileChannel" output-channel="processChannel">
<int:header name="flowName" value="Name" />
<int:header name="flowID" method="uuidgenerate" ref="headerEnricherBean" />
<int:header name="flowStartTime" method="generateTimeString" ref="headerEnricherBean"></int:header>
<int:header name="fileName" method="deriveFileName" ref="headerEnricherBean" />
</int:header-enricher>
<int:channel id="processChannel">
<int:interceptors>
<int:wire-tap channel="copyChannel" id="copyTap" />
</int:interceptors>
</int:channel>
<int:channel id="copyChannel"></int:channel>
<int-file:outbound-channel-adapter id="fileCopier" channel="copyChannel" delete-source-files="false" filename-generator="dateSuffixFileNameGenerator"
directory="copy.path">
</int-file:outbound-channel-adapter>
<int:filter id="formatcheckFilter" ref="formatValidator" method="validateFile" input-channel="processChannel" output-channel="processDataChannel"
discard-channel="errorChannel" auto-startup="true">
</int:filter>
<int:service-activator id="converter" input-channel="processDataChannel" method="convert" ref="fileToQueryConverter" auto-startup="true"
output-channel="impChannel" />
<bean id="importer" class="testbean.import">
<property name="errorpath" value="path1" />
<property name="sourcepath" value="path2" />
</bean>
<int:service-activator input-channel="impChannel" ref="impeximporter" id="importProcess" method="import" auto-startup="true"
output-channel="archiveChannel" />
<int:channel id="archiveChannel">
<int:interceptors>
<int:wire-tap channel="logChannel" id="completionLogger" />
</int:interceptors>
</int:channel>
<int:channel id="logChannel"></int:channel>
<int-file:outbound-channel-adapter id="fileArchiver" channel="archiveChannel" delete-source-files="true" filename-generator="dateSuffixFileNameGenerator"
directory="archive.path">
</int-file:outbound-channel-adapter>
<int:service-activator id="flowLogger" input-channel="logChannel" ref="messageLogger" method="logMessage">
</int:service-activator>
Sometimes the exceptions from service activator are going to the error channel, however some times they are not going.
I have the error channel defined as below:
<int:channel id="errorChannel" />
<bean id="exceptionHandler" class=my.custom.ExceptionHandler">
</bean>
<int:service-activator id="errorLogger" input-channel="errorChannel" method="handle" ref="exceptionHandler">
</int:service-activator>
I have this error channel being used in many integrations and in my service activators i am just doing a throw Exception("Message")

How to convert this Apache CXF endpoint definition to work in spring-ws

I have an old CXF application that I am trying to convert to spring-ws. Here's the endpoint:
<!-- The service endpoint-->
<jaxws:endpoint id="storeService"
implementor="#storeServiceImpl"
address="/store">
<!--interceptor for basic security. -->
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action"
value="UsernameToken"/>
<entry key="passwordType"
value="PasswordText"/>
<entry key="passwordCallbackRef"
value-ref="storeCallback"/>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
<jaxws:properties>
<entry key="security.enable.nonce.cache" value="false" />
<entry key="security.enable.timestamp.cache" value="false" />
<entry key="security.timestamp.timeToLive" value="600000000" />
<entry key="ws-security.must-understand" value="false" />
</jaxws:properties>
</jaxws:endpoint>
I get how to setup spring-security so that I do not have to use the old security interceptor.
The issue I am running into is: How do I configure the end point in spring-ws to use properties that I define?
The mustUnderstand property in particular is crucial to using spring-ws. I am getting the so-called "famous" mustUnderstand error which is described in:
Spring-WS WSA header contains hardcoded mustUnderstand attribute
Any help will be appreciated!
PS Partial payload being sent to the service:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="http://example.com/" xmlns:req="http://xmlns.example.com/salesforce/notifications/request">
<soap:Header />
<soap:Body>
<ser:setStore>
<PayloadRequest xmlns:ns2="http://xmlns.example.com/salesforce/notifications/request" xmlns:ns3="urn:sobject.enterprise.soap.sforce.com">
<req:metadata>
<ns2:Version_Number__c>1.0</ns2:Version_Number__c>
<ns2:Time_Stamp__c>2015-11-09T23:41:01.753Z</ns2:Time_Stamp__c>
</req:metadata>
<req:payload>
...
</req:payload>
</ser:setStore>
</soap:setStore>
</soap:Envelope>

Envers doesn't insert records

I'm trying to integrate Envers in my project. I'm using Hibernate-envers 3.5.5-Final, Hibernate-core 3.5.5-Final, spring 3.0.7.RELEASE.
For DAO Layer, I'm using a GenericDaoHibernate class.
My applicationContext.xml contains:
<property name="eventListeners">
<map>
<entry key="post-insert" >
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-remove">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-collection-recreate">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
</map>
</property>
The audit tables for the annotated classes are created, but by adding or updating a row in the entity table, no row is inserted in the _AUD tables or in the REVINFO.
So, I added a new listener org.hibernate.ejb.event.EJB3PostInsertEventListener as :
<property name="eventListeners">
<map>
<entry key="post-insert" >
<list>
<bean class="org.hibernate.envers.event.AuditEventListener" />
<bean class="org.hibernate.ejb.event.EJB3PostInsertEventListener" />
</list>
</entry>
<entry key="post-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-remove">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-collection-recreate">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
</map>
</property>
The problem persists, and now no record is inserted in the entity tables.
Any suggestion is welcome.
Thanks.
OK.
I solved the problem.
Firstibale, it seems that with the Hibernate-core 3.5.5-Final, we don't need org.hibernate.ejb.event.EJB3PostInsertEventListener, so in our ApplicationContext-config.xml we should have just this config :
<property name="eventListeners">
<map>
<entry key="post-insert" >
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-remove">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-collection-recreate">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
</map>
</property>
Secondly, in our case our project uses two transction managers, so for the services annotated #Transactionnal we have to mention the name of the proper transaction manager used, that means that all services should be annotated as #Transactionnal(value="NAME_TX_MANAGER"). The source of this problem is that Envers doesn't work properly if we have an auto-commit (If I understood well its documentation).
I hope that may be helpful for the other visitors if the face the same difficulties.

Spring ldap multiple group bases in authoritiespopulator

Is there any way in Spring to set it up such that an authoritiespopulator will look in more than one location?
<bean id="authoritiesPopulator" class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<constructor-arg value="CN=Users" />
<property name="groupRoleAttribute" value="CN" />
<property name="searchSubtree" value="true" />
<property name="rolePrefix" value="" />
<property name="convertToUpperCase" value="false" />
</bean>
This is the general idea, but there are also groups in CN=OtherGroups, and right now they don't get loaded (obviously). However, setting the groupsearchbase (the 2nd constructor arg) to value="" results in an error:
Unprocessed Continuation Reference(s); remaining name ''
Any ideas?
Answer: set referral to follow.
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
....
<property name="baseEnvironmentProperties">
<map>
<entry key="java.naming.referral" value="follow" />
</map>
</property>
</bean>

Resources