Custom timeout configuration per operation using Spring - java

I am using a Soap WS and I have to customize timeout configuration per operation. The customization is actually done with cxf and its http-conf:conduit, which cannot be customized to the operation level.
My actual configuration is :
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.package.PortType" />
<property name="address" ref="URL_WS" />
</bean>
<bean id="URL_WS" class="java.lang.String">
<constructor-arg value="http://serveraddress/Service"/>
</bean>
<http-conf:conduit name="http://serveraddress/Service.*">
<http-conf:client ConnectionTimeout="10000" ReceiveTimeout="10000"/>
</http-conf:conduit>
With this configuration, all the timeout of this WS are up to 10000ms.
As explained above, I would like to customize it to the operation level, I have found this link and tried to follow the process, but I'm in front of a problem of implementation, but I only com.ibm.wsdl.util.xml.QNameUtils in my classpath which has for the factory-method :
public static QName newQName(Node paramNode), method which takes a org.w3c.dom.Node.
I tried to change the code with this implementation coming to:
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="delegate">
<jaxws:client serviceClass="com.package.PortType" address="URL_WS" >
<jaxws:outInterceptors>
<bean class="com.package.CustomTimeoutInterceptor">
<property name="receiveTimeoutByOperationName">
<map key-type="javax.xml.namespace.QName" value-type="java.lang.Long">
<entry value="10">
<key>
<bean class="com.ibm.wsdl.util.xml.QNameUtils" factory-method="newQName">
<!-- I don't know what to put here -->
</bean>
</key>
</entry>
</map>
</property>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
</property>
</bean>
The Node's implementation I have is com.sun.org.apache.xerces.internal.dom.NodeImpl. I don't know which NodeImpl' subclass I have to use and how to create it to make it working in a bean way, I'm kinda losing myself in the documentation with these different implementations and these different dom Levels.
I just would like to create an Object subClass of Node which would work in this QNameUtils method
OR
find a different way to customize my configuration

I finally solved this problem, here is the working solution:
I kept the CustomTimeoutInterceptor of the link, mixed the solution with the help of this link.
I also kept my initial configuration, and I found that the javax.xml.namespace.QName had a factory method. I just added this part to my configuration:
<!-- Creation of the bean for the interceptor -->
<bean id="timeoutSetter" class="com.package.CustomTimeoutInterceptor">
<property name="receiveTimeoutByOperationName">
<map key-type="javax.xml.namespace.QName" value-type="java.lang.Long">
<entry value="20000">
<key>
<bean class="javax.xml.namespace.QName" factory-method="valueOf">
<constructor-arg value="{http://serveraddress/Service}Operation1" />
</bean>
</key>
</entry>
</map>
</property>
</bean>
<!-- I had the interceptor the list of outInterceptors -->
<cxf:bus>
<cxf:outInterceptors>
<ref bean="timeoutSetter"/>
</cxf:outInterceptors>
</cxf:bus>

Related

Is ConcurrentMapCacheFactoryBean a distributed cache?

I wasn't able to identify if ConcurrentMapCacheFactoryBean would provide a distributed cache. Intuition says no because the docs mentioned "used within a Spring container" but I would like to confirm because the configuration for it seems to be the simplest!
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.html
FYI I have the following bean in my xml
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
name="testCache"/>
</set>
</property>
</bean>

Is it possible call a properties file to instance a user and password in Apache CXF Blueprint for a Web Service?

I'm relative new with Fuse and WebServices.
I did a SOAP WebService with a BasicAuthAuthorizationInterceptor, this is the actual context and it's working:
<cxf:cxfEndpoint address="/SampleEp" id="insertSomethingToDB" serviceClass="com.example.sample_ep.SampleEp" wsdlURL="wsdl/SampleEP.wsdl">
<cxf:inInterceptors>
<ref component-id="securityInterceptor"/>
</cxf:inInterceptors>
</cxf:cxfEndpoint>
<bean
class="com.example.middleware.BasicAuthAuthorizationInterceptor" id="securityInterceptor">
<property name="users">
<map>
<entry key="user" value="password"/>
</map>
</property>
</bean>
So, to add more security, I'll tried to put the users in a properties file outside the project, this is the idea:
<cxf:cxfEndpoint address="/SampleEp" id="insertSomethingToDB" serviceClass="com.example.sample_ep.SampleEp" wsdlURL="wsdl/SampleEP.wsdl">
<cxf:inInterceptors>
<ref component-id="securityInterceptor"/>
</cxf:inInterceptors>
</cxf:cxfEndpoint>
<bean
class="com.example.middleware.BasicAuthAuthorizationInterceptor" id="securityInterceptor">
<property name="users">
<map>
<entry key="${cxf.user}" value="${cxf.password}"/>
</map>
</property>
</bean>
<bean> add some code to add a *.properties file outside the project </bean>
It is that possible?
Or I'm really bad with this?
Ok, I tried a few of things with Jasypt, JAAS and get the solution:
<ext:property-placeholder>
<ext:location>file:/this/is/your/path/to/your/propertie/file/cxf.properties
</ext:location>
</ext:property-placeholder>
<cxf:cxfEndpoint address="/SampleEp" id="insertSomethingToDB"
serviceClass="com.example.sample_ep.SampleEp" wsdlURL="wsdl/SampleEP.wsdl">
<cxf:inInterceptors>
<ref component-id="securityInterceptor" />
</cxf:inInterceptors>
</cxf:cxfEndpoint>
<bean class="com.example.middleware.BasicAuthAuthorizationInterceptor"
id="securityInterceptor">
<property name="users">
<map>
<entry key="${cxf.user}" value="${cxf.password}" />
</map>
</property>
</bean>
Just only add to your Blueprint header:
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
And voilĂ , it's working with a secure user/pass validation outside your project :D
And the most important thing, the properties file needs this format:
#cxf.properties
cxf.user=administrator
cxf.password=password

Broadleaf Commerce - My workflow activities are being executed twice

It seems that the built in workflow activities are being executed twice. I am testing the checkout workflow and the DecrementInventoryActivity is removing the quantity from the sku twice.
Is this a known bug or am I doing something wrong?
I created the workflow like so:
<!-- Checkout Workflow Configuration -->
<bean id="blCheckoutWorkflow" class="org.broadleafcommerce.core.workflow.SequenceProcessor">
<property name="processContextFactory">
<bean class="org.broadleafcommerce.core.checkout.service.workflow.CheckoutProcessContextFactory"/>
</property>
<property name="activities">
<list>
<bean p:order="6000" id="blDecrementInventoryActivity" class="org.broadleafcommerce.core.checkout.service.workflow.DecrementInventoryActivity">
<property name="rollbackHandler" ref="blDecrementInventoryRollbackHandler" />
</bean>
<bean p:order="7000" id="blCompleteOrderActivity" class="org.broadleafcommerce.core.checkout.service.workflow.CompleteOrderActivity">
<property name="rollbackHandler" ref="blCompleteOrderRollbackHandler" />
</bean>
<bean p:order="9999999" class="com.mycompany.workflow.checkout.NotifyExternalInventorySystem" />
</list>
</property>
<property name="defaultErrorHandler">
<bean class="org.broadleafcommerce.core.workflow.DefaultErrorHandler">
<property name="unloggedExceptionClasses">
<list>
<value>org.broadleafcommerce.core.inventory.service.InventoryUnavailableException</value>
</list>
</property>
</bean>
</property>
</bean>
Starting with Broadleaf 4.0, the DecrementInventoryActivity was added by default to the blCheckoutWorkflow. See the 3.1.10-4.0.0 migration notes at http://www.broadleafcommerce.com/docs/core/4.0/migration-notes/3.1-to-4.0-migration/3.1.10-to-4.0-migration, in the section "Inventory Management".
This also goes for the defaultErrorHandler, and you can remove the blCompleteOrderActivity (that has always been managed in the framework). Basically, your customized blCheckoutWorkflow bean should change to:
<bean id="blCheckoutWorkflow" class="org.broadleafcommerce.core.workflow.SequenceProcessor">
<property name="activities">
<list>
<bean p:order="9999999" class="com.mycompany.workflow.checkout.NotifyExternalInventorySystem" />
</list>
</property>
</bean>
Starting with Broadleaf 3.0, any modifications to the blCheckoutWorkflow bean undergo the Broadleaf XML merging processing (which merges bean ids like blCheckoutWorkflow's list of activities). In your case, since the DecrementInventoryActivity is already defined in the core framework XML file and your definition of blCheckoutWorkflow merges with it, the final result is 2 instances of the DecrementInventoryActivity.

Java - Spring - put entries in map based on some condition

In a Java app which uses Spring (Spring version 3.2.3),
I have something like this:
<bean id="pm" class="com.test.PropertyManager">
<property name="targets">
<map>
<entry key="key01" value-ref="obj01" />
<entry key="key02" value-ref="obj02" />
<entry key="key03" value-ref="obj03" />
<entry key="key04" value-ref="obj04" />
<entry key="key05" value-ref="obj05" />
<entry key="key06" value-ref="obj06" />
</map>
</property>
</bean>
Is there any way to tell Spring to not put all entries in this map
but only some of them based on some property whose value can be
different for different environments the app is built for, and running in.
I mean, I am looking for something like:
<bean id="pm" class="com.test.PropertyManager">
<property name="targets">
<map>
<entry key="key01" value-ref="obj01" if="${env1}"/>
<entry key="key02" value-ref="obj02" if="${env1}"/>
<entry key="key03" value-ref="obj03" unless="${env1}"/>
<entry key="key04" value-ref="obj04" unless="${env1}"/>
<entry key="key05" value-ref="obj05" />
<entry key="key06" value-ref="obj06" />
</map>
</property>
</bean>
So e.g. I want two entries to be added when the app is in environment env1, two other entries to be added when the app is running in another env2, and yet two others to be always added.
Is that possible and if not, what are my alternatives?
There are different options:
If you need a different bean configuration per environment you could use profiles:
<beans profile="dev">
<bean id="pm" class="com.test.PropertyManager">
<property name="targets">
...
</property>
</bean>
</beans>
<beans profile="production">
<bean id="pm" class="com.test.PropertyManager">
<property name="targets">
...
</property>
</bean>
</beans>
More on XML profiles: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-definition-profiles-xml
If you need more flexibility use a factory (with Java config, that's straightforward):
public class PropertyManagerFactory {
public static PropertyManager getInstance() {
// Your initialization code (check env vars to build the map...)
}
}
Bean definition (notice the factory-method):
<bean id="propertyManager" class="com.test.PropertyManagerFactory" factory-method="getInstance" />
Usage (what's returned by the getInstance method will be injected here):
<bean id="accountService" class="com.test.AccountServiceImpl">
<property name="propertyManager" ref="propertyManager"/>
</bean>
More info on using factory methods: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-class-static-factory-method

Marshalling Different Classes with Spring MVC and JIBX

We are trying to build some RESTful services with Spring MVC. We will be providing several representations: XML, HTML, & JSON. We would like to use JiBX as the OXM technology.
We are currently having difficulty figuring out how to wire up Spring with JiBX. If we want to wire up a single class, for example Customer, we simply define a JibxMarshaller, an XML MarshallingView, and add it too our ContentNegotiatingViewResolver. This works great.
The problem is we aren't sure how to wire up marshalling of multiple classes, for example, Customer and User. Each JibxMarshaller can support only one class (unlike the Jaxb2Marshaller which can support many). We tried declaring a marshaller for each class, but the MarshallingView only support one marshaller. Declaring multiple MarshallingViews does not work (it appears only the first one works).
Your advice is appreciated. Thanks.
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<util:map>
<entry key="xml" value="application/xml"/>
</util:map>
</property>
<property name="defaultViews">
<util:list>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="userMarshaller"/>
</bean>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="customerMarshaller"/>
</bean>
</util:list>
</property>
</bean>
<bean id="userMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass" value="com.mycompany.User"/>
</bean>
<bean id="customerMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass" value="com.mycompany.Customer"/>
</bean>
Update based on Ritesh's answer below:
It turns out that I was thrown off by the targetClass property of the JibxMarshaller. I thought it meant the marshaller would only work for a single class, however, it appears to just uses the target class as a way of finding all related bindings. So, the solution is to use just a single marshaller, using an arbitrary target class from your set of classes you have bindings for. For example:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<util:map>
<entry key="xml" value="application/xml"/>
</util:map>
</property>
<property name="defaultViews">
<util:list>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="jibxMarshaller"/>
</bean>
</util:list>
</property>
</bean>
<bean id="jibxMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass" value="com.mycompany.User"/>
</bean>
JiBX binding compiler adds JiBX_bindingList field to class files. At run time, the 'targetClass' (any compiled class with JiBX_bindingList field) is used to build a BindingFactory. It is the getMappedClasses() of IBindingFactory which is used by JibxMarshaller
in supports() method to check if marshaller can marshal a class.
Please also see JiBX runtime usage.

Categories

Resources