JSR352 decide next step based on return parameter from Decider - batch-processing

I would like to implement a Decider that returns the ID of the next step that needs to be executed. (This question is related to my other question here if you would like to know why I'm trying to do this: JEE Batch Job Specification with many optional Steps)
<decision id="decider1" ref="skipNextStepDecider">
<properties>
<property name="condition" value="isExecuteSteps"/>
</properties>
<next on="*" to="STEP_ID_RETURNED_BY_DECIDER"/>
<end on="SKIP"/>
</decision>
Is there any way to do this?
I am using JSR352 with Websphere Liberty in case this is relevant.
UPDATE
My intent was to avoid the following:
<decision id="decider1" ref="skipNextStepDecider">
<properties>
<property name="condition" value="isExecuteSteps"/>
</properties>
<next on="STEP1" to="step1"/>
<next on="STEP2" to="step2"/>
<next on="STEP3" to="step3"/>
<end on="SKIP"/>
</decision>

To do this you'd need to know the possible target steps ahead of time...
The JSL gets parsed up front (mostly) so there's nothing you can put in the 'to' value that would resolve with a result from the step/decider processing.
Might be an interesting spec update possibility.

Related

Can the order in which broker's plugins execute be defined?

I need to implement 2 filters that fit in the amq:discardingDLQBrokerPlugin category, and I need one to be executed before the other.
I can implement the two filter's logic in one class, but since the business logic is very different, I would prefer two.
I add the filters using two different plugins: com.filter.FilterAPlugin and com.filter.FilterBPlugin. The filter execution order follows a "last defined first executed" logic.
Example: In this broker configuration
<amq:broker useJmx="false" persistent="false" schedulerSupport="true">
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:0" />
</amq:transportConnectors>
<amq:plugins>
<amq:discardingDLQBrokerPlugin dropAll="true" dropTemporaryTopics="true" dropTemporaryQueues="true" />
<bean xmlns="http://www.springframework.org/schema/beans" class="com.filter.FilterAPlugin" />
<bean xmlns="http://www.springframework.org/schema/beans" class="com.filter.FilterBPlugin" />
</amq:plugins>
</amq:broker>
Filter added in com.filter.FilterBPlugin is executed first.
Does the order in which the beans are declared defines the order of execution of the filters? I can't find documentation about this in the apache MQ web
BrokerService uses Chain of Responsibility pattern, so execution order is defined by the object initialization order.

CAS LDAP Search Subtree

I'm using last version of Jasig CAS server (4.0.0) with an LDAP server.
Users are stored under this LDAP structure : ou=Users,ou=SSOTEST,dc=mycompany,dc=com
What I want is to search an user from a top level (example : ou=SSOTEST,dc=mycompany,dc=com).
CAS server has an LdapPersonAttributeDao bean which is looking for an object matching a search filter. Here is the code for this bean :
<bean id="ldapPersonAttributeDao"
class="org.jasig.cas.persondir.LdapPersonAttributeDao"
p:connectionFactory-ref="searchPooledLdapConnectionFactory"
p:baseDN="ou=SSOTEST,dc=company,dc=com"
p:searchControls-ref="searchControls"
p:searchFilter="uid={0}">
<property name="resultAttributeMapping">
<map>
<!--
| Key is LDAP attribute name, value is principal attribute name.
-->
<entry key="memberOf" value="userMemberOf" />
<entry key="cn" value="userCn" />
</map>
</property>
</bean>
And now the searchControls bean which do a lookup at SUBTREE_SCOPE (2) level (according toSearchControls scope level values).
<bean id="searchControls"
class="javax.naming.directory.SearchControls"
p:searchScope="2"
p:countLimit="10" />
When I run my CAS server and I try to authenticate, everything works but there are no extra attributes returned.
I think the problem comes from searchScope, which don't seems to be set to wanted value.
Here is output log from the server :
<execute request=[org.ldaptive.SearchRequest#-1312441815::baseDn=ou=SSOTEST,dc=mycompany,dc=com, searchFilter=[org.ldaptive.SearchFilter#-3391
91059::filter=uid={0}, parameters={0=myuser}], returnAttributes=[], searchScope=null, timeLimit=0, sizeLimit=10 [...]
I know its been some time since this question was asked. But I managed to fix this problem by adding:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
to deployerConfigContext.xml.
The cause of this issue was that the initalize method in LdapPersonAttributeDao was not being invoked because the #PostConstruct annotation wasn't being executed. For this reason the searchScope variable was never set.

XPath for web.config applicationSettings webdeploy parameters.xml file is not correct

I use webdeploy to deploy my web site project with a parameters.xml file I have been using a for a while. So far the parameters I've added are all element attributes and it all works well. But I am trying to get the xpath right to update an applicationSettings element value (not attributes) and am failing, badly, to work out if its my poor xpath skills to blame or a misunderstanding of the way the parameters file works.
When I do a deployment the field is not updated, it compiles fine and no errors\warnings during deployment. I want to be able to set this to True or False.
So I have following parameters field
<parameter name="ShowExceptionCallStackOnErrorView" description="Display a call stack on the UI Error view - true for debug only." defaultValue="False" tags="">
<parameterEntry kind="XmlFile" scope="\\web.config$" match="/configuration/applicationSettings/abc.123.Properties.Settings/setting[#name='ShowExceptionCallStackOnErrorView']/value" />
</parameter>
trying to match to the following application settings section
<configuration>
<applicationSettings>
<abc.123.Properties.Settings>
<setting name="ShowExceptionCallStackOnErrorView" serializeAs="String">
<value>True</value>
Any help would be much appreciated!
It's not giving you an error because it is simply not finding a match to replace. You need to add /text() to the end of your match tag if you want it to replace the contents of the value tag. As follows...
<parameter name="ShowExceptionCallStackOnErrorView" description="Display a call stack on the UI Error view - true for debug only." defaultValue="False" tags="">
<parameterEntry kind="XmlFile" scope="\\web.config$" match="/configuration/applicationSettings/abc.123.Properties.Settings/setting[#name='ShowExceptionCallStackOnErrorView']/value/text()" />
</parameter>

EclipseLink very slow on inserting data

I'm using the latest EclipseLink version with MySQL 5.5 (table type InnoDB). I'm inserting about 30900 records (which could be also more) at a time.
The problem is, that the insert performance is pretty poor: it takes about 22 seconds to insert all records (compared with JDBC: 7 seconds). I've read that using batch writing should help - but doesn't!?
#Entity
public class TestRecord {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public int test;
}
The code to insert the records:
factory = Persistence.createEntityManagerFactory("xx_test");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
for(int i = 0; i < 30900; i++) {
TestRecord record = new TestRecord();
record.test = 21;
em.persist(record);
}
em.getTransaction().commit();
em.close();
And finally my EclipseLink configuration:
<persistence-unit name="xx_test" transaction-type="RESOURCE_LOCAL">
<class>com.test.TestRecord</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/xx_test" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="test" />
<property name="eclipselink.jdbc.batch-writing" value="JDBC" />
<property name="eclipselink.jdbc.cache-statements" value="true"/>
<property name="eclipselink.ddl-generation.output-mode" value="both" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.logging.level" value="INFO" />
</properties>
</persistence-unit>
What I'm doing wrong? I've tried several setting, but nothing seems the help.
Thanks in advance for helping me! :)
-Stefan
Another thing is to add ?rewriteBatchedStatements=true to the data URL used by the connector.
This caused executing about 120300 inserts down to about 30s which was about 60s before.
JDBC Batch writing improves performance drastically; please try it
Eg: property name="eclipselink.jdbc.batch-writing" value="JDBC"
#GeneratedValue(strategy = GenerationType.IDENTITY)
Switch to TABLE sequencing, IDENTITY is never recommended and a major performance issue.
See,
http://java-persistence-performance.blogspot.com/2011/06/how-to-improve-jpa-performance-by-1825.html
I seem to remember that MySQL may not support batch writing without some database config as well, there was another post on this, I forget the url but you could probably search for it.
Probably the biggest difference besides the mapping conversion is the caching. By default EclipseLink is placing each of the entities into the persistence context (EntityManager) and then during the finalization of the commit it needs to add them all to the cache.
One thing to try for now is:
measure how long an em.flush() call takes after the loop but before the commit. Then if you want you could call em.clear() after the flush so that the newly inserted entities are not merged into the cache.
Doug

How do I set the xmlns attribute when using XMLFile in Wix 3

I am adding elements to an XML file during installation using the XmlFile element:
<util:XmlFile Id="SetOracleDialectProperty"
Action="createElement"
ElementPath="//hibernate-configuration/session-factory"
Name="property"
Sequence="9"
File="[INSTALLLOCATION]Config\hibernate.config"
Value="NHibernate.Dialect.Oracle10gDialect"/>
The empty file I am writing to looks like this:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
</session-factory>
</hibernate-configuration>
After running the installer I end up with this:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property xmlns="">NHibernate.Dialect.Oracle10gDialect</property>
</session-factory>
</hibernate-configuration>
The problem is that the empty xmlns attribute is overriding the xmlns specified in the root node of the file so the property element is not recognised correctly by nhibernate.
How can I either set the value to match the root node or remove the xmlns attribute?
I have spent some time searching for an answer and the closest I've found is "do what you would do in MSXML" which doesn't help me as it doesn't say how to do it in WiX (e.g. what attribute on XmlFile to use).
EDIT
To explain Rob's answer slightly, in a place where I can use nice formatting:
You add a document fragment by setting Node="document" on the XmlConfig element.
You have to explicitly set the namespace otherwise you get the default one again.
Also although you're adding a "document" it doesn't seem to work if you specify more than one element. You get a mysterious and thoroughly unhelpful "Setup wizard ended prematurely" runtime error.
So my fixed code looks like this:
<util:XmlConfig Id="MsSqlDialect"
Action="create"
ElementPath="//hibernate-configuration/session-factory"
File="[INSTALLLOCATION]Config\hibernate.config"
Node="document">
<![CDATA[
<property xmlns="urn:nhibernate-configuration-2.2" name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
]]>
</util:XmlConfig>
I know this is years later but if anyone else comes across this I think the true solution is this:
<util:XmlFile Id="SetOracleDialectProperty"
Action="createElement"
ElementPath="//hibernate-configuration/session-factory"
Name="urn:nhibernate-configuration-2.2:property"
Sequence="9"
File="[INSTALLLOCATION]Config\hibernate.config"
Value="NHibernate.Dialect.Oracle10gDialect"/>
change is from Name="property" to Name="urn:nhibernate-configuration-2.2:property" - when config is written it will apprear as just as it will recognize it is the default namespace. I had the same problem adjusting manifest files and this approach sorted it.
The problem here is that MSXML states that createElement will always give you the default namespace (just as you are seeing). I think you'll need to switch to the more complex but more powerful XmlConfig. In this case, try using a document fragment to add the entire element with correct namespace instead of depending on MSXML to create it for you.