Defining enum maps in Spring beans - java

I am trying to define an enum map in my Spring beans xml, and I want it to populate in the xml, however when I try to define it like this
<bean class = "java.util.EnumMap">
<constructor-arg>
<util:map key-type="org.itemlist.products.stockitem">
<entry key="stockitem.SOAP">100</entry>
</util:map>
</constructor-arg>
UPDATE
Here is my beans configuration
<?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:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<bean class = "java.util.EnumMap">
<constructor-arg>
<util:map key-type="org.itemlist.products.stockitem">
<entry key="stockitem.SOAP">100</entry>
</util:map>
</constructor-arg>
</bean>
</beans>
When I add a value inside entry, this is now the error
cvc-complex-type.2.3: Element 'entry' cannot have character [children], because the type's content type is element-only.

Have you define those schema in the header:
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
And the namespace:
xmlns:util="http://www.springframework.org/schema/util"

You can define it like this :
<bean id="springBean" class="a.b.c.d.MyEnum">
<constructor-arg>
<util:map key-type="a.b.c.d.MyEnum" value-type="aa.b.c.d.Mya.b.c.d.MyVal">
<entry>
<key><value type="a.b.c.d.MyEnum">ENUM-VAL1</value></key>
<ref bean="myValBean1" />
</entry>
<entry>
<key><value type="a.b.c.d.MyEnum">ENUM-VAL1</value></key>
<ref bean="myValBean1" />
</entry>
</util:map>
</constructor-arg>
</bean>

That error message means that the entry element must be empty, i.e. contain no text or other elements. The syntax you want is:
<entry key="stockitem.SOAP" value="100"/>
The entry element also lets you pass a reference to another bean as the value, e.g.:
<entry key="stockitem.SOAP" value-ref="myOtherBean"/>
(which is of no use in your situation, I just mention it for completeness)

Related

Socks proxy failure with camel-box component

I've got the camel-box component working well via the corporate web proxy but it is very slow. I tried using the socks proxy instead, which works well for me for sftp transfers but it fails with almost no useful error message. Just an exception which I'll dig out and add to the question but didn't tell me anything. Can anyone spot anything wrong with my proxy configuration? This is equivalent to my applicationContext.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" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:p="http://www.springframework.org/schema/p" 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 http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd ">
<camelContext xmlns="http://camel.apache.org/schema/spring" id="boxtest">
<route id="getids">
<description>Fetch the names and Box unique ids for the root folder</description>
<from uri="jetty:http://0.0.0.0:/info"/>
<to uri="box://folders/getFolderItems?folderId=0&pagingRequest=#pr"/>
<to uri="bean:dump"/>
</route>
</camelContext>
<bean class="org.apache.camel.component.box.BoxComponent" id="box">
<property name="configuration" ref="cfg"/>
</bean>
<bean class="org.apache.camel.component.box.BoxConfiguration" id="cfg">
<property name="httpParams">
<map>
<entry key="http.route.socks-proxy" value="true"/>
<entry key="http.route.default-proxy">
<bean class="org.apache.http.HttpHost" id="proxy">
<constructor-arg index="0" value="my-socks-proxy"/>
<constructor-arg index="1" value="1085"/>
</bean>
</entry>
</map>
</property>
<property name="userName" value="j#b.com"/>
<property name="clientId" value="a83445cd422dbfc62ba9"/>
<property name="clientSecret" value="1701df702c00126783fc1701df702c00126783fc"/>
<property name="authSecureStorage" ref="auth"/>
</bean>
<bean id="auth" class="mypackage.Auth">
<property name="filename" value="box_credentials.properties"/>
</bean>
<bean id="pr" class="com.box.boxjavalibv2.requests.requestobjects.BoxPagingRequestObject"/>
</beans>
here is the exception: http://pastebin.com/GpBeHJiD
So to formally answer my question, the error in the config is that the socks parameter needs to be boolean as follows:
<entry key="http.route.socks-proxy">
<value type="java.lang.Boolean">true</value>
</entry>
But the real problem is that camel-box in Camel 2.14.1 only has socks support for the login process not for the restful client.
I've submitted a patch for this.
https://issues.apache.org/jira/browse/CAMEL-8272

Spring bean configuration list<map>

Im trying to create a bean configuration file for my
SettingsDto class:
public class SettingsDto {
private String administratorEmail;
private String gatekeeperAddress;
private String webRtcUrl;
private String userGuideUrl;
private String vmrFaqUrl;
private String lyncGuideUrl;
List<Map<String, String>> supportPhones;
List<String> audioCalls;
But Im having issues with how Im doing the supportPhones (List<Map<String, String>>)
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:component-scan base-package="sandbox.spring" />
<bean id="SettingsBean" class="com.dto.SettingsDto">
<property name="administratorEmail" value="v#.com" />
<property name="gatekeeperAddress" value="192.168.1.0" />
<property name="webRtcUrl" value="https://web.com" />
<property name="userGuideUrl"
value="url" />
<property name="vmrFaqUrl"
value="url" />
<property name="lyncGuideUrl"
value="url" />
<property name="audioCalls">
<util:list>
<value>+1 (000)000-0000</value>
<value>(000)000-0000</value>
</util:list>
</property>
<property name="supportPhones">
<util:list>
<ref bean="supportPhonesMapping1" />
<ref bean="supportPhonesMapping2" />
</util:list>
</property>
<util:map id="supportPhonesMapping1">
<entry key="name" value="North America" />
<entry key="phone" value-ref="+1 111-1111" />
</util:map>
<util:map id="supportPhonesMapping2">
<entry key="name" value="+11 111-1111" />
<entry key="phone" value-ref="International" />
</util:map>
</bean>
</beans>
The error I get is
Invalid content was found starting with element 'util:map'. No child
element is expected at this point
You cannot set value to util:map that way. value can only take a string. Define a util:map separately, then use ref to reference it.
For example:
<util:map id="myMap">
<entry key="name" value="..." />
</util:map>
<util:list>
<ref bean="myMap"/>
</util:list>
Also, value-ref should reference another bean - currently you have it as a string literal value, which you can simply use value for.
Maybe it's your beans schema. You have it slightly wrong. It should be:
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
so in the end there were a few issues.
first off my declaration was wrong
<entry key="phone" value-ref="International" />
needed to be
<entry key="phone" value="International" />
(no "-ref")
I also changed the xml to define my list and map outside of the bean then referenced it in the bean
<property name="supportPhones" ref="supportPhoneList" />

how can I use util:list in spring configuration file

I am trying to use spring's unmarshaller to automatically unmarshal request body from xml to an object. But I failed getting the error util prfeix unbind. Could you tell me how can I use util:list and where can I find reference for util:list.
I did spot that the official documentation leave out a closing > in </property and I correct that in my configuration.
I find configuration far more frustrating that just write the code.
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="stringHttpMessageConverter"/>
<ref bean="marshallingHttpMessageConverter"/>
</util:list>
</property
</bean>
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="castorMarshaller" />
<property name="unmarshaller" ref="castorMarshaller" />
</bean>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
You need to declare to util namespace; e.g.:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

Passing jobParameters to bean in Spring Batch

I read a problem from the link https://stackoverflow.com/q/15784984/814074 and tried the solution given in above link.
However, I got the following error while running the code:
Error creating bean with name 'JobArgs' defined in class path resource [pipelineJob.xml]:
Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '$Proxy2 implementing java.io.Serializable,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'com.test.genepanel.job.JobArguments' for property 'jobArguements'; nested exception is java.lang.IllegalStateException:
Cannot convert value of type [$Proxy2 implementing java.io.Serializable,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.test.genepanel.job.JobArguments] for property 'jobArguements': no matching editors or conversion strategy found
The xml contains
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<batch:job id="pipelineJob">
<batch:step id="initializationStep" next="CleanUPStep">
<batch:tasklet ref="initializationStepTasklet" />
</batch:step>
<batch:step id="CleanUPStep">
<batch:tasklet ref="cleanupTaskLet" />
</batch:step>
</batch:job>
<bean id="basicStep" class="com.test.mutation.steps.BasicStep" abstract="true">
<property name="testJobArgs" ref="JobArgs"/>
</bean>
<bean id="JobArgs" class="com.test.mutation.application.TestJobArguements">
<property name="jobArguements" ref="jobArg">
</property>
</bean>
<bean id="jobArg" class="com.test.genepanel.job.JobArguments" scope="step">
<constructor-arg value="#{jobParameters['jobOutputDir']}"/>
</bean>
<bean id="emptyTaskLet" class="com.test.mutation.steps.EmptyStep" scope="step" parent="basicStep" />
<bean id="cleanupTaskLet" class="com.test.mutation.steps.CleanUpStep" scope="step" parent="basicStep">
</bean>
<bean id="initializationStepTasklet" class="com.test.mutation.steps.InitializationStep" scope ="step" parent="basicStep">
</bean>
</beans>
Am I missing anything?
The easy way to use step scope is like this:
<bean id="myReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="resource" value="file:#{jobParameters['input.file']}" />
<property name="linesToSkip" value="0" />
<property name="recordSeparatorPolicy" ref="simpleRecordPolicy" />
<property name="lineMapper" ref="journalSicIemtLineMapper" />
</bean>
Placing the step scope on the beans will delay his creation until the step it his referred is about to start. This is what Late-binding means, so you could access variables in the the ExecutionContext.
As the docs in the StepScope states:
beans with the StepScope will be aop:scoped-proxy. This means a proxy goes around the real object.
So when you define a regular Spring Beans (like you did with jobArg) and put the scope=step on it. You will have to find a way to retrieve the object inside this proxy when you want to set it in another bean (JobArgs)
I have looked all over the Spring references and I have not seen late binding in the constructor arguments so I am not sure it works. I assume you are setting the jobParameters in the JobArgs, in which case it should have the same scope="step"

PropertyPlaceholderConfigurer inside routeContext. Can't set uri from property file

I have property file and I want to set uri in my route from this file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<import resource="TransactionsParserConfig.xml"/>
<bean id="transactionsValidator" class="com.class.TransactionsValidator"/>
<bean id="transactionsValidator123" name="${ftp.host}"/> <!--here I can use property-->
<routeContext id="transactionsRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="routeFTP">
<from uri="direct:start" />
<!--here I can NOT use property-->
<from uri="ftps://${ftp.host}/?securityProtocol=SSL"/>
etc...
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<array>
<value>classpath:/ftp.properties</value>
</array>
</property>
</bean>
</beans>
But looks like it's not allowed to set uri from property file. Because when I use ${ftp.host} outside the routexContext tag everething is fine. Also even Idea can't redirect me when I hit ctrl+mouseclick inside routeContext.
Why?
Camel cannot use PropertyPlaceholderConfigurer inside it's Spring DSL due to Spring restrictions. There are many ways to achieve what you want. Some of them are described by link.
You can use bean configuration mentioned below
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>file:/properties1.properties</value>
<value>file:/properties2.properties</value>
</list>
</property>
</bean>
Properties can be access in java classes like
#Value("${categories.insert.sql}")
private String insertQuery;
Properties can be accessed in camel context like
<setHeader headerName="signature">
<constant>{{api.secretkey}}</constant>
</setHeader>
Hope this works

Categories