This tutorial covers extending an existing application with new functionality and support for new event types. The reader
should be proficient in Java, maven, git, Spring and have completed the first lottery tutorial before starting
this tutorial.
Our goal is to demonstrate how Fluxtion code generation makes it easy and cost-effective to add new functionality to
an existing application with confidence.
At the end of this tutorial you should understand:
How to add new event types and behaviours to user functions
How to re-generate the container with new functionality
We will extend the lottery game to include a power lottery game and some additional reporting interfaces the application
can use. The new java classes are built in the same style as previous tutorials with annotations marking the
callbacks. To bind the new classes into the event processor we update the spring config file and run the build
to regenerate the LotteryProcessor
Processing logic
Our design sketches show what we intend to integrate into our system
publicinterfaceGameResultStore{booleanisTicketSuccessful(Ticketticket,Consumer<Boolean>responseReceiver);booleanpublishReport(Consumer<String>reportReceiver);}publicrecordWinningTicketReport(TicketpowerLotteryTicket,intwinningNumbers){}@Slf4jpublicclassPowerLotteryMachineextendsLotteryMachineNodeimplements@ExportServiceLotteryMachine{publicPowerLotteryMachine(Supplier<Ticket>ticketSupplier){super(ticketSupplier);}@OverridepublicvoidselectWinningTicket(){//removed for clarity...}}publicclassGameReportNodeimplements@ExportServiceGameResultStore,@ExportServiceLotteryMachine{privatefinalLotteryMachineNodelotteryMachine;privatefinalPowerLotteryMachinepowerLotteryMachine;privateConsumer<String>resultPublisher;privateintgameCount;publicGameReportNode(@AssignToField("lotteryMachine")LotteryMachineNodelotteryMachine,@AssignToField("powerLotteryMachine")PowerLotteryMachinepowerLotteryMachine){this.lotteryMachine=lotteryMachine;this.powerLotteryMachine=powerLotteryMachine;}@OverridepublicbooleanisTicketSuccessful(Ticketticket,Consumer<Boolean>responseReceiver){//removed for clarity}@OverridepublicbooleanpublishReport(Consumer<String>reportReceiver){//removed for clarity}@OverridepublicvoidselectWinningTicket(){// store results}@OverridepublicvoidsetResultPublisher(Consumer<String>resultPublisher){//publish report}@OverridepublicvoidnewGame(){gameCount++;}}
Extended application
Now the new functionality and services are bound in to the generated event processor, the application can be extended
to use the new features in the sample main. Client code is completely hidden from the updates and the new wiring
that has been generated. All the previous functionality works as before and the application behaviour is extended reliably
and with teh minimum of effort.
publicclassLotteryApp{privatestaticLotteryMachinelotteryMachine;privatestaticTicketStoreticketStore;privatestaticGameResultStoreresultStore;publicstaticvoidmain(String[]args){start(LotteryApp::ticketReceipt,LotteryApp::lotteryResult);lotteryMachine.newGame();ticketStore.openStore();//open store and buy ticketTicketmyGoldenTicket=newTicket(12_65_56);ticketStore.buyTicket(myGoldenTicket);ticketStore.buyTicket(newTicket(36_58_58));ticketStore.buyTicket(newTicket(73_00_12));//run the lotterylotteryMachine.selectWinningTicket();//our new functionalityresultStore.isTicketSuccessful(myGoldenTicket,b->System.out.println("\n"+myGoldenTicket+" is a "+(b?"WINNER :)\n":"LOSER :(\n")));resultStore.publishReport(System.out::println);}publicstaticvoidstart(Consumer<String>ticketReceiptHandler,Consumer<String>resultsPublisher){varlotteryEventProcessor=newLotteryProcessor();lotteryEventProcessor.init();//get service interfaceslotteryMachine=lotteryEventProcessor.getExportedService();ticketStore=lotteryEventProcessor.getExportedService();resultStore=lotteryEventProcessor.getExportedService();//register listeners via service interfacelotteryMachine.setResultPublisher(resultsPublisher);ticketStore.setTicketSalesPublisher(ticketReceiptHandler);//start the processorlotteryEventProcessor.start();}publicstaticvoidticketReceipt(Stringreceipt){System.out.println(receipt);}publicstaticvoidlotteryResult(Stringreceipt){System.out.println(receipt);}}
Running the application
Executing the application produces the following output:
good luck with Ticket[number=126556, id=c5ad2b74-f9cf-4bbb-92d7-4ac9eb76e129]
good luck with Ticket[number=365858, id=a4f3dfa7-2e6d-4689-94e3-72678be3c68b]
good luck with Ticket[number=730012, id=ea6f5b9c-8571-4547-93f7-8752ee6b19df]
winning numbers:730012
POWER-LOTTERY winning numbers:126556
Ticket[number=126556, id=c5ad2b74-f9cf-4bbb-92d7-4ac9eb76e129] is a WINNER :)
GAME REPORT gameNumber:1
lottery winner:Ticket[number=730012, id=ea6f5b9c-8571-4547-93f7-8752ee6b19df]
POWER-LOTTERY winner:Ticket[number=126556, id=c5ad2b74-f9cf-4bbb-92d7-4ac9eb76e129]
Process finished with exit code 0
Conclusion
Hopefully you have learnt that extending an application with Fluxtion is simple and saves a lot of developer time.
Existing behaviour is left untouched the automated generation removes many potential errors. All the developer effort
is focused on the adding business logic and creating value.
Comparing the previous generated version with the new version gives the developer to validate the new application
classes are wired in as expected.