@Entity public class Dept implements Serializable { @Id private Integer id; @Column(nullable = false) private String name; @OneToMany(mappedBy = "dept") private Collection<Employee> employees; ... @Entity public class Employee implements Serializable { @Id private Integer id; @Column(nullable = false) private String name; @JoinColumn(nullable = false) @ManyToOne private Dept dept; ...
Entries tagged [wildfly]
Arquillian Persistence Extension examples
TweetPosted on Wednesday Mar 18, 2015 at 05:47PM in Arquillian
The whole project can be obtained from GitHub. tested with WildFly 8.2.0.Final as remote container.
Implementation (test target)
Assume we have very simple 2 entities as follows:
Test target EJB:
@Stateless @LocalBean public class HumanResourcesBean { @PersistenceContext private EntityManager em; public void addEmployee(Employee employee, Integer deptId) { final Dept dept = em.find(Dept.class, deptId); dept.getEmployees().add(employee); employee.setDept(dept); em.persist(employee); } public void addDept(Dept dept, Employee employee) { Collection<Employee> employees = new ArrayList<>(); dept.setEmployees(employees); employees.add(employee); employee.setDept(dept); em.persist(dept); em.persist(employee); } }
addEmployee() testing
Test method of addEmployee():
@Test @UsingDataSet("input.xml") @ShouldMatchDataSet(value = "addEmployee-expected.xml", orderBy = "id") public void addEmployeeTest() throws Exception { Employee emp = new Employee(); emp.setId(2002); emp.setName("Todd"); humanResourcesBean.addEmployee(emp, 200); }
Initial entry data (input.xml):
<dataset> <Dept id="100" name="Sales"/> <Dept id="200" name="Finance"/> <Employee id="1000" name="Scott" dept_id="100"/> <Employee id="1001" name="Martin" dept_id="100"/> <Employee id="1002" name="Nick" dept_id="100"/> <Employee id="2000" name="Jordan" dept_id="200"/> <Employee id="2001" name="David" dept_id="200"/> </dataset>
Expected data (addEmployee-expected.xml):
<dataset> <Employee id="1000" name="Scott" dept_id="100"/> <Employee id="1001" name="Martin" dept_id="100"/> <Employee id="1002" name="Nick" dept_id="100"/> <Employee id="2000" name="Jordan" dept_id="200"/> <Employee id="2001" name="David" dept_id="200"/> <Employee id="2002" name="Todd" dept_id="200"/> <!-- Newly added --> </dataset>
addDept() testing
Test method of addDept():
@Test @UsingDataSet("input.xml") @ShouldMatchDataSet(value = "addDept-expected.xml", orderBy = "id") public void addDeptTest() throws Exception { Dept dept = new Dept(); dept.setId(300); dept.setName("Engineering"); Employee emp = new Employee(); emp.setId(3000); emp.setName("Carl"); humanResourcesBean.addDept(dept, emp); }
Initial entry data (input.xml) is the same to previous testing.
Expected data (addDept-expected.xml):
<dataset> <Dept id="100" name="Sales"/> <Dept id="200" name="Finance"/> <Dept id="300" name="Engineering"/> <!-- Newly added --> <Employee id="1000" name="Scott" dept_id="100"/> <Employee id="1001" name="Martin" dept_id="100"/> <Employee id="1002" name="Nick" dept_id="100"/> <Employee id="2000" name="Jordan" dept_id="200"/> <Employee id="2001" name="David" dept_id="200"/> <Employee id="3000" name="Carl" dept_id="300"/> <!-- Newly added --> </dataset>
It works well with multiple tables.
addDept() testing with DBUnit
Sometimes use of DBUnit directly is useful for complex assertion. in such case you need to care following conditions:
-
If you use JPA, force EntityManager to execute DMLs via invoking
em.flush()
before assertion -
Include test data to the Arquillian’s application archive so that DBUnit can load these data on the server side
The XML can be included via addAsResource()
method as follows:
@Deployment public static Archive<?> createDeploymentPackage() { final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") .addPackage(Dept.class.getPackage()) .addClass(HumanResourcesBean.class) .addAsResource("datasets/addDept-expected.xml") // to be loaded by DBUnit on the server side .addAsResource("test-persistence.xml", "META-INF/persistence.xml"); // System.out.println(webArchive.toString(true)); return webArchive; }
The test method of addDept() and related convenient methods:
@Test @UsingDataSet("input.xml") public void addDeptTestWithDbUnit() throws Exception { Dept dept = new Dept(); dept.setId(300); dept.setName("Engineering"); Employee emp = new Employee(); emp.setId(3000); emp.setName("Carl"); humanResourcesBean.addDept(dept, emp); em.flush(); // force JPA to execute DMLs before assertion final IDataSet expectedDataSet = getDataSet("/datasets/addDept-expected.xml"); assertTable(expectedDataSet.getTable("Dept"), "select * from dept order by id"); assertTable(expectedDataSet.getTable("Employee"), "select * from employee order by id"); } private static IDataSet getDataSet(String path) throws DataSetException { return new FlatXmlDataSetBuilder().build(HumanResourcesBeanIT.class.getResource(path)); } private void assertTable(ITable expectedTable, String sql) throws SQLException, DatabaseUnitException { try (Connection cn = ds.getConnection()) { IDatabaseConnection icn = null; try { icn = new DatabaseConnection(cn); final ITable queryTable = icn.createQueryTable(expectedTable.getTableMetaData().getTableName(), sql); Assertion.assertEquals(expectedTable, queryTable); } finally { if (icn != null) { icn.close(); } } } }
Disabling color escape sequences in WildFly's console logging for IDE
TweetPosted on Wednesday Mar 18, 2015 at 11:31AM in WildFly
I’m using IntelliJ IDEA for developing Java EE applications on WildFly. its built-in WildFly console appears as follows:
... [0m11:20:28,608 INFO [org.jboss.as.server] (Controller Boot Thread) JBAS015888: Creating http management service using socket-binding (management-http) [0m[0m11:20:28,625 INFO [org.xnio] (MSC service thread 1-9) XNIO version 3.3.0.Final [0m[0m11:20:28,631 INFO [org.xnio.nio] (MSC service thread 1-9) XNIO NIO Implementation Version 3.3.0.Final ...
You can see strange characters in the head of every lines. they are color escape sequences that works fine with terminal emulators but not for IntelliJ IDEA’s console output. to disable color escape sequences, issue following command in jboss-cli
:
/subsystem=logging/console-handler=CONSOLE:write-attribute(name=named-formatter, value=PATTERN)
Now strange characters disappeared from IntelliJ IDEA’s console as follows:
... 2015-03-18 11:26:11,800 INFO [org.jboss.as.server] (Controller Boot Thread) JBAS015888: Creating http management service using socket-binding (management-http) 2015-03-18 11:26:11,812 INFO [org.xnio] (MSC service thread 1-4) XNIO version 3.3.0.Final 2015-03-18 11:26:11,817 INFO [org.xnio.nio] (MSC service thread 1-4) XNIO NIO Implementation Version 3.3.0.Final ...
Testing a JBatch job using Arquillian on remote WildFly
TweetPosted on Thursday Mar 05, 2015 at 05:14PM in JBatch
I pushed entire project to https://github.com/lbtc-xxx/arquillian-jbatch .
While I prefer remote EJB way like my previous posting for JBatch testing, it works well for simple project. but little slower than remote EJB on my environment.
Tags: arquillian jbatch wildfly
Using Apache BatchEE's server API with JBeret
TweetPosted on Wednesday Mar 04, 2015 at 06:11PM in JBatch
Apache BatchEE is a fork of the JSR352 reference implementation with many additional features. it has useful REST APIs built on JAX-RS so we can manipulate (start, stop, restart, and so on) batches through REST API. fortunately, it is well modularized so we can use its REST API implementation with other JSR352 implementation such as JBeret.
I created an example project which works with WildFly 8.2.0.Final and its JSR352 implementation JBeret. after deploy, issue following command:
curl -H 'Content-Type: application/json' \ -d '{"entries": [ {"key": "myKey1", "value": "myValue1"}, {"key": "myKey2", "value": "myValue2"} ]}' \ http://localhost:8080/batcheetest/jbatch/batchee/execution/start/myjob
Then you’ll see following output in WildFly console:
17:57:18,608 INFO [stdout] (Batch Thread - 9) Hello world! 17:57:18,609 INFO [stdout] (Batch Thread - 9) Job Parameters: {myKey2=myValue2, myKey1=myValue1}
It’s much better than create a servlet which kicks the batch.
And I haven’t tested yet, it also have useful client API for that REST API. we can use JobOperator
transparently thanks to its proxy. for details of REST API and BatchEE, see following URLs:
UPDATE:
I added a test case which uses client API of BatchEE, but it doesn’t work with released version. you need to apply a patch by hand. for details refer https://issues.apache.org/jira/browse/BATCHEE-59
Also I created an example of a test class which uses Arquillian. this won’t work with 0.2-incubating but will work with future versions.
@RunWith(Arquillian.class) public class MyJobArquillianIT { @ArquillianResource private URL url; private JobOperator jobOperator; @Deployment(testable = false) public static Archive<?> war() { final File[] files = Maven.configureResolver() .loadPomFromFile("pom.xml") .resolve("org.apache.batchee:batchee-jaxrs-server") .withTransitivity() .asFile(); return ShrinkWrap.create(WebArchive.class) .addClass(HelloBatchlet.class) .addAsResource("META-INF/batch-jobs/myjob.xml") .addAsLibraries(files); } @Before public void before() { jobOperator = BatchEEJAXRSClientFactory.newClient(url.toExternalForm() + "jbatch"); } @Test public void test() { Properties jobParameters = new Properties(); jobParameters.setProperty("someKey", "someValue"); final JobExecution jobExecution = waitForFinish(jobOperator.start("myjob", jobParameters)); Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus()); } private static final Collection<BatchStatus> BATCH_END_STATUSES = EnumSet.of(BatchStatus.COMPLETED, BatchStatus.FAILED, BatchStatus.STOPPED, BatchStatus.ABANDONED); private JobExecution waitForFinish(long executionId) { JobExecution jobExecution; while (!BATCH_END_STATUSES.contains((jobExecution = jobOperator.getJobExecution(executionId)).getBatchStatus())) { try { Thread.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } return jobExecution; } }
Web frontend
Its web-frontend GUI (batchee-servlet-embedded
) works even against JBeret runtime as follows. you can view executions, jobs and its definition, and can start jobs with custom parameters.
It also exposes simple-rest
API which is more useful when issue the command by hand or some cases (e.g. cron job). in case of this example, you can start a job as follows:
$ curl 'http://localhost:8080/batcheetest/jbatch-gui/rest/start/myjob?param1=x¶m2=y' 5 OK
You can read its help as follows:
$ curl 'http://localhost:8080/batcheetest/jbatch-gui/rest/' -1 FAILURE Unknown command: The returned response if of MIME type text/plain and contains the following information {jobExecutionId} (or -1 if no executionId was detected)\n OK (or FAILURE)\n followed by command specific information Known commands are: * start/ - start a new batch job Sample: http://localhost:8080/myapp/jbatch/rest/start/myjobname?param1=x¶m2=y BatchEE will start the job and immediately return * status/ - query the current status Sample: http://localhost:8080/myapp/jbatch/rest/status/23 will return the state of executionId 23 * stop/ - stop the job with the given executionId Sample: http://localhost:8080/myapp/jbatch/rest/stop/23 will stop the job with executionId 23 * restart/ - restart the job with the given executionId Sample: http://localhost:8080/myapp/jbatch/rest/restart/23 will restart the job with executionId 23
Tags: arquillian batchee jbatch jberet wildfly
Deploying an application to WildFly with Ant + Cargo
TweetPosted on Wednesday Mar 04, 2015 at 04:49PM in WildFly
I created an Ant script which deploys an application to WildFly through ssh tunnel. it creates ssh tunnel using Ant’s sshtunnel
target. the script works well with a Jenkins job.