Keep your Wicket application in production - Presentation Transcript
Get your application
in production...
...and keep your
weekends free
Martijn Dashorst
Topicus
6 WAYS TO KEEP YOUR JOB
OUT OF YOUR WEEKEND
1. USE WICKET TESTER
WICKETTESTER
• Test components directly, or their markup
• Runs tests without starting server
• Ajax testing (server side)
• Runs in IDE, ant, maven builds
• Achieves high code coverage
HELLOWORLD TEST
@Test
public void labelContainsHelloWorld() {
}
HELLOWORLD TEST
@Test
public void labelContainsHelloWorld() {
WicketTester tester = new WicketTester();
}
HELLOWORLD TEST
@Test
public void labelContainsHelloWorld() {
WicketTester tester = new WicketTester();
tester.startPage(HelloWorld.class);
}
HELLOWORLD TEST
@Test
public void labelContainsHelloWorld() {
WicketTester tester = new WicketTester();
tester.startPage(HelloWorld.class);
tester.assertLabel(\"message\", \"Hello, World!\");
}
LINK TEST
@Test
public void countingLinkClickTest() {
}
LINK TEST
@Test
public void countingLinkClickTest() {
WicketTester tester = new WicketTester();
}
LINK TEST
@Test
public void countingLinkClickTest() {
WicketTester tester = new WicketTester();
tester.startPage(LinkCounter.class);
}
LINK TEST
@Test
public void countingLinkClickTest() {
WicketTester tester = new WicketTester();
tester.startPage(LinkCounter.class);
tester.assertModelValue(\"label\", 0);
}
LINK TEST
@Test
public void countingLinkClickTest() {
WicketTester tester = new WicketTester();
tester.startPage(LinkCounter.class);
tester.assertModelValue(\"label\", 0);
tester.clickLink(\"link\");
}
LINK TEST
@Test
public void countingLinkClickTest() {
WicketTester tester = new WicketTester();
tester.startPage(LinkCounter.class);
tester.assertModelValue(\"label\", 0);
tester.clickLink(\"link\");
tester.assertModelValue(\"label\", 1);
}
NAVIGATION TEST
@Test
public void navigateToSecondPage() {
}
NAVIGATION TEST
@Test
public void navigateToSecondPage() {
WicketTester tester = new WicketTester();
tester.startPage(new FirstPage());
}
NAVIGATION TEST
@Test
public void navigateToSecondPage() {
WicketTester tester = new WicketTester();
tester.startPage(new FirstPage());
tester.clickLink(\"link\");
}
NAVIGATION TEST
@Test
public void navigateToSecondPage() {
WicketTester tester = new WicketTester();
tester.startPage(new FirstPage());
tester.clickLink(\"link\");
tester.assertRenderedPage(SecondPage.class);
}
2. PAGE CHECK
PAGES IN EDUARTE
• Pages must have @PageInfo annotation
• Policy file must contain existing pages
• All secure pages must be in the policy file
PAGE INFO ANNOTATION
@PageInfo(
title = \"Intake stap 1 van 4\",
menu = {\"Deelnemer > intake\"}
)
public class IntakePersonalia extends IntakeWizardPage
{
...
}
Our build fails for any
of these problems...
3. ENTITY CHECKER
Storing Hibernate entities in
your pages is bad...
...mkay
WICKET SERIALIZABLE
CHECKER
• Runs when page is serialized
• Tries to find non-serializable objects attached to page
• Helpful stacktraces
EXAMPLE STACKTRACE
Unable to serialize class: nl.topicus.project.entities.personen.Persoon
Field hierarchy is:
2 [class=nl.topicus.project.SomePage, path=2]
nl.topicus.project.entities.personen.Persoon
nl.topicus.project.SomePage.persoon <----- Entity
WICKET SERIALIZER CHECK
public class TopicusRequestCycle extends WebRequestCycle {
public void onEndRequest() {
Page requestPage = getRequest().getPage();
testDetachedObjects(requestPage);
if (getRequestTarget() instanceof IPageRequestTarget) {
Page responsePage = getRequestTarget().getPage();
if (responsePage != requestPage) {
testDetachedObjects(responsePage);
}
}
}
}
WICKET SERIALIZER CHECK
if (!(obj instanceof Serializable) && (!Proxy.isProxyClass(cls))) {
throw new WicketNotSerializableException(/* .. */)
.toString(), exception);
}
if (obj instanceof IdObject) {
Serializable id = ((IdObject) obj).getIdAsSerializable();
if (id != null && !(id instanceof Long && ((Long) id) <= 0)) {
throw new WicketContainsEntityException(/* ... */);
}
}
... complicated stuff ...
To ensure developers
have to fix it immediately...
...an Ajax callback checks for these
errors and renders an ErrorPage
4. MARKUP VALIDATOR
VALID MARKUP...
• Nobody cares about valid markup
• XHTML is dead
INVALID MARKUP...
do care
• Browsers
• Subtle differences between browser DOM handling
• Ajax becomes a pain
WICKET STUFF HTML
VALIDATOR
• http://github.com/dashorst/wicket-stuff-markup-validator
• Based on: http://tuckey.org/validation
ADD DEPENDENCY TO POM
<dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>htmlvalidator</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
ADD FILTER TO WEBAPP
public class MyApplication extends WebApplication {
// ...
@Override
protected void init() {
// only enable the markup filter in DEVELOPMENT mode
if(DEVELOPMENT.equals(getConfigurationType())) {
getRequestCycleSettings()
.addResponseFilter(new HtmlValidationResponseFilter());
}
}
}
DEFINE PROPER DOCTYPE
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<title>Foo</title>
</head>
<body>
</body>
</html>
... AND ENDURE THE HORRORS
OF VALID MARKUP
5. REQUESTLOGGER
REQUEST LOGGER
• HTTPD logs are (mostly) useless for Wicket applications
• POST /vocus/app?wicket:interface=:4:lijst::IBehaviorListener...
• GET /vocus/app?wicket:interface=:1084::
• RequestLogger provides decoded information:
• Page, Listener, RequestTarget, SessionID, etc.
14:00:19 time=101,
event=Interface[
target:DefaultMenuLink(menu:personalia:dropitem
page: nl.topicus.gui.student.ToonPersonaliaPage(4)
interface: ILinkListener:onLinkClicked],
response=PageRequest[
nl.topicus.gui.student.ToonLeerlingRelatiesPage(6)]
sessioninfo=[
sessionId=D574D35FF49C047E4F290FE
clientInfo=ClientProperties{
remoteAddress=192.0.2.50,
browserVersionMajor=7,
browserInternetExplorer=true},
organization=Demo School
username=administrator],
sessionstart=Fri Dec 14 13:59:14 CET 2008,
requests=14,
totaltime=3314
REQUEST LOST PARSER
6. RABID MONITORING
NABAZTAG
• Availability of production applications
• Performance of production applications
• Hudson builds
• Issue tracker
1 comments
Comments 1 - 1 of 1 previous next Post a comment