Keep your Wicket application in production

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

1 comments

Comments 1 - 1 of 1 previous next Post a comment

Post a comment
Embed Video
Edit your comment Cancel

1 Favorite

Keep your Wicket application in production - Presentation Transcript

  1. Get your application in production... ...and keep your weekends free Martijn Dashorst Topicus
  2. 6 WAYS TO KEEP YOUR JOB OUT OF YOUR WEEKEND
  3. 1. USE WICKET TESTER
  4. 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
  5. HELLOWORLD TEST @Test public void labelContainsHelloWorld() { }
  6. HELLOWORLD TEST @Test public void labelContainsHelloWorld() { WicketTester tester = new WicketTester(); }
  7. HELLOWORLD TEST @Test public void labelContainsHelloWorld() { WicketTester tester = new WicketTester(); tester.startPage(HelloWorld.class); }
  8. HELLOWORLD TEST @Test public void labelContainsHelloWorld() { WicketTester tester = new WicketTester(); tester.startPage(HelloWorld.class); tester.assertLabel(\"message\", \"Hello, World!\"); }
  9. LINK TEST @Test public void countingLinkClickTest() { }
  10. LINK TEST @Test public void countingLinkClickTest() { WicketTester tester = new WicketTester(); }
  11. LINK TEST @Test public void countingLinkClickTest() { WicketTester tester = new WicketTester(); tester.startPage(LinkCounter.class); }
  12. LINK TEST @Test public void countingLinkClickTest() { WicketTester tester = new WicketTester(); tester.startPage(LinkCounter.class); tester.assertModelValue(\"label\", 0); }
  13. LINK TEST @Test public void countingLinkClickTest() { WicketTester tester = new WicketTester(); tester.startPage(LinkCounter.class); tester.assertModelValue(\"label\", 0); tester.clickLink(\"link\"); }
  14. 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); }
  15. NAVIGATION TEST @Test public void navigateToSecondPage() { }
  16. NAVIGATION TEST @Test public void navigateToSecondPage() { WicketTester tester = new WicketTester(); tester.startPage(new FirstPage()); }
  17. NAVIGATION TEST @Test public void navigateToSecondPage() { WicketTester tester = new WicketTester(); tester.startPage(new FirstPage()); tester.clickLink(\"link\"); }
  18. NAVIGATION TEST @Test public void navigateToSecondPage() { WicketTester tester = new WicketTester(); tester.startPage(new FirstPage()); tester.clickLink(\"link\"); tester.assertRenderedPage(SecondPage.class); }
  19. 2. PAGE CHECK
  20. PAGES IN EDUARTE • Pages must have @PageInfo annotation • Policy file must contain existing pages • All secure pages must be in the policy file
  21. PAGE INFO ANNOTATION @PageInfo( title = \"Intake stap 1 van 4\", menu = {\"Deelnemer > intake\"} ) public class IntakePersonalia extends IntakeWizardPage { ... }
  22. Our build fails for any of these problems...
  23. 3. ENTITY CHECKER
  24. Storing Hibernate entities in your pages is bad... ...mkay
  25. WICKET SERIALIZABLE CHECKER • Runs when page is serialized • Tries to find non-serializable objects attached to page • Helpful stacktraces
  26. 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
  27. 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); } } } }
  28. WICKET SERIALIZER CHECK if (page == null || page.isErrorPage()) { return; } try { checker = new EntityAndSerializableChecker( new NotSerializableException()); checker.writeObject(page); } catch (Exception e) { log.error(\"Couldn't serialize: \" + page + \", error: \" + ex); }
  29. WICKET SERIALIZER CHECK private void check(Object obj) { Class cls = obj.getClass(); nameStack.add(simpleName); traceStack.add(new TraceSlot(obj, fieldDescription)); if (!(obj instanceof Serializable) && (!Proxy.isProxyClass(cls))) { throw new WicketNotSerializableException(/* ... */); } ... complicated stuff ... }
  30. 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 ...
  31. To ensure developers have to fix it immediately... ...an Ajax callback checks for these errors and renders an ErrorPage
  32. 4. MARKUP VALIDATOR
  33. VALID MARKUP... • Nobody cares about valid markup • XHTML is dead
  34. INVALID MARKUP... do care • Browsers • Subtle differences between browser DOM handling • Ajax becomes a pain
  35. WICKET STUFF HTML VALIDATOR • http://github.com/dashorst/wicket-stuff-markup-validator • Based on: http://tuckey.org/validation
  36. ADD DEPENDENCY TO POM <dependency> <groupId>org.wicketstuff</groupId> <artifactId>htmlvalidator</artifactId> <version>1.0</version> <scope>test</scope> </dependency>
  37. 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()); } } }
  38. 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>
  39. ... AND ENDURE THE HORRORS OF VALID MARKUP
  40. 5. REQUESTLOGGER
  41. 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.
  42. 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
  43. REQUEST LOST PARSER
  44. 6. RABID MONITORING
  45. NABAZTAG • Availability of production applications • Performance of production applications • Hudson builds • Issue tracker
  46. THANK YOU!

+ Martijn DashorstMartijn Dashorst, 7 months ago

custom

1868 views, 1 favs, 1 embeds more stats

More info about this document

© All Rights Reserved

Go to text version

  • Total Views 1868
    • 1867 on SlideShare
    • 1 from embeds
  • Comments 1
  • Favorites 1
  • Downloads 64
Most viewed embeds
  • 1 views on http://vangunst.blogspot.com

more

All embeds
  • 1 views on http://vangunst.blogspot.com

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories