├── .gitignore ├── LICENSE.txt ├── README.txt ├── camel ├── jms2rest │ ├── ReadMe.txt │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── camel │ │ │ │ └── jms2rest │ │ │ │ ├── Jms2RestRoute.java │ │ │ │ └── Jms2RestStarter.java │ │ └── resources │ │ │ ├── OSGI-INF │ │ │ ├── blueprint │ │ │ │ └── blueprint.xml │ │ │ └── metatype │ │ │ │ └── jms2rest.xml │ │ │ └── log4j.properties │ │ └── test │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── karaf │ │ │ └── camel │ │ │ └── jms2rest │ │ │ └── Jms2RestAdapterTest.java │ │ └── resources │ │ ├── person1.xml │ │ └── person2jms.cfg ├── order │ ├── ReadMe.txt │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── camel │ │ │ │ └── order │ │ │ │ ├── GetVendorMail.java │ │ │ │ ├── OrderRouteBuilder.java │ │ │ │ └── Starter.java │ │ └── resources │ │ │ ├── OSGI-INF │ │ │ ├── blueprint │ │ │ │ └── blueprint.xml │ │ │ └── metatype │ │ │ │ └── config.xml │ │ │ ├── log4j.properties │ │ │ ├── mailtemplate.txt │ │ │ └── sampleconfig.properties │ │ └── test │ │ └── resources │ │ └── order1.xml ├── pom.xml ├── simple-blueprint │ ├── ReadMe.txt │ └── simple-camel-blueprint.xml └── tutorial part 5 - camel.txt ├── cameljpa ├── Karaf Tutorial Part 7.txt ├── jpa2jms │ ├── ReadMe.txt │ ├── connectionfactory-default.xml │ ├── localhost-broker.xml │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── camel │ │ │ │ └── jpa2jms │ │ │ │ ├── ExceptionDecider.java │ │ │ │ ├── Jpa2JmsRoute.java │ │ │ │ ├── Jpa2JmsStarter.java │ │ │ │ └── model │ │ │ │ └── Person.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── persistence.xml │ │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint.xml │ │ └── test │ │ └── resources │ │ ├── log4j.properties │ │ └── person1.xml └── pom.xml ├── configadmin ├── configadmin-features │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── ConfigApp.cfg │ │ └── features.xml ├── configapp-blueprint │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── configadmin │ │ │ └── MyApp.java │ │ └── resources │ │ └── OSGI-INF │ │ └── blueprint │ │ └── context.xml ├── configapp │ ├── osgi.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── configadmin │ │ │ ├── Activator.java │ │ │ └── MyApp.java │ │ └── resources │ │ └── OSGI-INF │ │ └── metatype │ │ └── configapp.xml ├── pom.xml └── readme.md ├── cxf ├── karaf_tutorial_part_4_cxf.txt ├── personservice-rest │ ├── ReadMe.txt │ ├── model │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── karaf │ │ │ └── cxf │ │ │ └── personrest │ │ │ └── model │ │ │ ├── Person.java │ │ │ └── PersonService.java │ ├── pom.xml │ ├── proxy-rest │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── resources │ │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint.xml │ ├── server │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── net │ │ │ │ │ └── lr │ │ │ │ │ └── tutorial │ │ │ │ │ └── karaf │ │ │ │ │ └── cxf │ │ │ │ │ └── personrest │ │ │ │ │ └── impl │ │ │ │ │ ├── PersonServiceImpl.java │ │ │ │ │ └── PersonServiceStarter.java │ │ │ └── resources │ │ │ │ └── OSGI-INF │ │ │ │ └── blueprint │ │ │ │ └── blueprint.xml │ │ │ └── test │ │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── cxf │ │ │ │ └── personservice │ │ │ │ └── impl │ │ │ │ └── PersonServiceRestTest.java │ │ │ └── resources │ │ │ ├── log4j.properties │ │ │ └── person1.xml │ └── webui │ │ ├── pom.xml │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── cxf │ │ │ │ └── personrest │ │ │ │ └── webui │ │ │ │ └── PersonServlet.java │ │ └── resources │ │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint.xml │ │ └── test │ │ └── resources │ │ ├── log4j.properties │ │ └── person1.xml ├── personservice │ ├── ReadMe.txt │ ├── bnd.bnd │ ├── model │ │ ├── bnd.bnd │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── karaf │ │ │ └── cxf │ │ │ └── personservice │ │ │ └── model │ │ │ ├── ObjectFactory.java │ │ │ ├── Person.java │ │ │ └── PersonService.java │ ├── pom.xml │ ├── proxy-rest │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── resources │ │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint.xml │ ├── proxy │ │ ├── bnd.bnd │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── resources │ │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint.xml │ ├── server │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── net │ │ │ │ │ └── lr │ │ │ │ │ └── tutorial │ │ │ │ │ └── karaf │ │ │ │ │ └── cxf │ │ │ │ │ └── personservice │ │ │ │ │ └── impl │ │ │ │ │ ├── PersonServiceImpl.java │ │ │ │ │ └── PersonServiceStarter.java │ │ │ └── resources │ │ │ │ └── OSGI-INF │ │ │ │ └── blueprint │ │ │ │ └── blueprint.xml │ │ │ └── test │ │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── cxf │ │ │ │ └── personservice │ │ │ │ └── impl │ │ │ │ └── PersonServiceSOAPTest.java │ │ │ └── resources │ │ │ ├── log4j.properties │ │ │ └── person1.xml │ └── webui │ │ ├── pom.xml │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── cxf │ │ │ │ └── personservice │ │ │ │ └── webui │ │ │ │ └── PersonServlet.java │ │ └── resources │ │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint.xml │ │ └── test │ │ └── resources │ │ ├── log4j.properties │ │ └── person1.xml └── pom.xml ├── db ├── README.md ├── examplejdbc │ ├── ReadMe.txt │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── karaf │ │ │ └── db │ │ │ └── example │ │ │ └── DbExample.java │ │ └── test │ │ └── java │ │ └── net │ │ └── lr │ │ └── tutorial │ │ └── karaf │ │ └── db │ │ └── example │ │ └── DbExampleTest.java ├── examplejpa │ ├── ReadMe.txt │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── karaf │ │ │ │ └── db │ │ │ │ └── examplejpa │ │ │ │ ├── Person.java │ │ │ │ ├── PersonService.java │ │ │ │ ├── command │ │ │ │ └── PersonCommands.java │ │ │ │ └── impl │ │ │ │ └── PersonServiceImpl.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── persistence.xml │ │ └── test │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── karaf │ │ │ └── db │ │ │ └── examplejpa │ │ │ ├── PersonServiceImplTest.java │ │ │ └── TestTemplate.java │ │ └── resources │ │ ├── META-INF │ │ └── persistence.xml │ │ └── log4j.xml ├── org.ops4j.datasource-person.cfg └── pom.xml ├── dbng ├── README.md ├── features │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ └── features.xml ├── migrator │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── db │ │ │ │ └── migration │ │ │ │ └── Migrator.java │ │ └── resources │ │ │ └── changesets.xml │ │ └── test │ │ └── java │ │ └── net │ │ └── lr │ │ └── tutorial │ │ └── db │ │ └── MigrateTest.java ├── org.ops4j.datasource-person.cfg ├── pom.xml └── service │ ├── pom.xml │ └── src │ └── main │ └── java │ └── net │ └── lr │ └── tutorial │ └── db │ └── service │ ├── Person.java │ ├── PersonCommand.java │ └── PersonRepo.java ├── docs ├── 10 │ └── index.md ├── 11 │ └── index.md ├── 01 │ └── index.md ├── 02 │ └── index.md ├── 03 │ ├── config-detail-typed.png │ ├── config-detail-untyped.png │ ├── config-fileinstall.png │ ├── config-list.png │ └── index.md ├── 04 │ ├── Overview.png │ ├── Overview.xml │ └── index.md ├── 05 │ ├── index.md │ ├── jms2rest.png │ ├── jms2rest.xml │ ├── order.png │ └── order.xml ├── 06 │ └── index.md ├── 07 │ ├── index.md │ ├── jpa2jms.png │ └── jpa2jms.xml ├── 08 │ ├── deployment.png │ ├── deployment.xml │ ├── dosgi-details.png │ ├── dosgi-details.xml │ └── index.md ├── 09 │ ├── index.md │ └── tasks.png ├── _config.yml ├── _includes │ ├── head.html │ └── sidebar.html ├── _layouts │ └── default.html ├── _sass │ ├── jekyll-theme-cayman.scss │ ├── normalize.scss │ ├── rouge-github.scss │ └── variables.scss ├── assets │ └── css │ │ └── style.scss ├── ds-hints.md └── index.md ├── dosgi └── README.txt ├── jms └── command │ ├── ReadMe.txt │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── karaf │ │ │ └── jms │ │ │ ├── command │ │ │ ├── BrowseCommand.java │ │ │ ├── DeleteCommand.java │ │ │ ├── JmsConnectionFactoryNameCompleter.java │ │ │ ├── JmsQueueNameCompleter.java │ │ │ ├── ListQueueCommand.java │ │ │ ├── MoveCommand.java │ │ │ ├── SelectCommand.java │ │ │ ├── SendCommand.java │ │ │ └── ShellTable.java │ │ │ ├── service │ │ │ ├── DummyExtJmsService.java │ │ │ ├── ExtJmsService.java │ │ │ ├── ExtJmsServiceFactory.java │ │ │ ├── ExtJmsServiceOsgiFactory.java │ │ │ ├── JmsInfo.java │ │ │ ├── JmsMessage.java │ │ │ ├── JmsMessageIterator.java │ │ │ ├── JmsSelect.java │ │ │ ├── JmsService.java │ │ │ ├── QueueInfo.java │ │ │ └── activemq │ │ │ │ ├── ActiveMQJmsService.java │ │ │ │ └── ActiveMQJmsServiceFactory.java │ │ │ └── template │ │ │ ├── JmsTemplate.java │ │ │ ├── SessionExecutor.java │ │ │ └── VoidSessionExecutor.java │ └── resources │ │ ├── OSGI-INF │ │ └── blueprint │ │ │ └── blueprint.xml │ │ └── log4j.properties │ └── test │ └── java │ └── net │ └── lr │ └── karaf │ └── jms │ └── service │ └── JmsServiceTest.java ├── liquibase ├── README.md ├── features │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ └── features.xml ├── org.ops4j.datasource-person.cfg ├── pom.xml ├── service │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── lr │ │ │ │ └── tutorial │ │ │ │ └── db │ │ │ │ └── service │ │ │ │ ├── Migrator.java │ │ │ │ ├── Person.java │ │ │ │ ├── PersonCommand.java │ │ │ │ └── PersonRepo.java │ │ └── resources │ │ │ └── db │ │ │ └── changesets.xml │ │ └── test │ │ └── java │ │ └── net │ │ └── lr │ │ └── tutorial │ │ └── db │ │ └── service │ │ └── PersonRepoTest.java └── tutorial.md ├── osgitemplate ├── pom.xml ├── readme.txt └── src │ └── main │ ├── java │ └── net │ │ └── lr │ │ └── tut │ │ └── karaf │ │ └── command │ │ └── SimpleServlet.java │ └── resources │ └── OSGI-INF │ └── blueprint │ └── context.xml ├── pom.xml ├── tasklist-blueprint-cdi ├── README.md ├── angular-ui │ ├── .gitignore │ ├── osgi.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── app.js │ │ └── index.html ├── features │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ └── features.xml ├── model │ ├── .gitignore │ ├── osgi.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tasklist │ │ │ └── model │ │ │ ├── Task.java │ │ │ └── TaskService.java │ │ └── resources │ │ └── META-INF │ │ └── persistence.xml ├── org.ops4j.datasource-tasklist.cfg ├── persistence │ ├── osgi.bnd │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── lr │ │ │ └── tasklist │ │ │ └── persistence │ │ │ └── impl │ │ │ ├── InitHelper.java │ │ │ └── TaskServiceImpl.java │ │ └── test │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tasklist │ │ │ └── persistence │ │ │ └── impl │ │ │ └── TaskServiceImplTest.java │ │ └── resources │ │ ├── META-INF │ │ └── persistence.xml │ │ └── log4j.xml ├── pom.xml ├── tasklist-service │ ├── osgi.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tasklist │ │ │ └── service │ │ │ └── impl │ │ │ └── TaskServiceRest.java │ │ └── resources │ │ └── OSGI-INF │ │ └── blueprint │ │ └── rest.xml └── ui │ ├── osgi.bnd │ ├── pom.xml │ └── src │ └── main │ └── java │ └── net │ └── lr │ └── tasklist │ └── ui │ └── TaskListServlet.java ├── tasklist-ds ├── .gitignore ├── README.md ├── app │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ └── etc │ │ └── org.ops4j.datasource-tasklist.cfg ├── features │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ └── features.xml ├── index │ └── pom.xml ├── model │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tasklist │ │ │ └── model │ │ │ ├── Task.java │ │ │ └── TaskService.java │ │ └── resources │ │ └── META-INF │ │ └── persistence.xml ├── org.ops4j.datasource-tasklist.cfg ├── persistence │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── lr │ │ │ └── tasklist │ │ │ └── persistence │ │ │ └── impl │ │ │ ├── InitHelper.java │ │ │ └── TaskServiceImpl.java │ │ └── test │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tasklist │ │ │ └── persistence │ │ │ └── impl │ │ │ ├── SimpleJpaTemplate.java │ │ │ └── TaskServiceImplTest.java │ │ └── resources │ │ ├── META-INF │ │ └── persistence.xml │ │ └── log4j.xml ├── pom.xml ├── service │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── lr │ │ └── tasklist │ │ └── service │ │ └── TaskServiceRest.java └── ui │ ├── bnd.bnd │ ├── pom.xml │ └── src │ └── main │ └── java │ └── net │ └── lr │ └── tasklist │ └── ui │ ├── TaskListServlet.java │ └── TaskUIConfig.java ├── tasklist ├── README.md ├── pom.xml ├── tasklist-command │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── lr │ │ └── tasklist │ │ └── command │ │ └── TaskCommands.java ├── tasklist-features │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ └── features.xml ├── tasklist-index │ ├── README.md │ ├── pom.xml │ └── tasklist.bndrun ├── tasklist-itests │ ├── pom.xml │ └── src │ │ └── test │ │ └── java │ │ └── net │ │ └── lr │ │ └── tasklist │ │ └── itests │ │ └── KarafTest.java ├── tasklist-model │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── lr │ │ └── tasklist │ │ └── model │ │ ├── Task.java │ │ └── TaskService.java ├── tasklist-persistence │ ├── bnd.bnd │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── lr │ │ └── tasklist │ │ └── persistence │ │ └── impl │ │ └── TaskServiceImpl.java └── tasklist-ui │ ├── bnd.bnd │ ├── pom.xml │ └── src │ └── main │ └── java │ └── net │ └── lr │ └── tasklist │ └── ui │ └── TaskListServlet.java ├── vaadin ├── README.txt ├── pom.xml ├── tasklist-ui-vaadin │ ├── .gitignore │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── karaf │ │ │ └── vaadin │ │ │ ├── ExampleAppFactory.java │ │ │ └── ExampleApplication.java │ │ └── resources │ │ └── OSGI-INF │ │ └── blueprint │ │ └── context.xml ├── tasklist-vaadin-features │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ └── features.xml └── vaadinbridge │ ├── README.txt │ ├── pom.xml │ └── src │ └── main │ └── java │ └── org │ └── example │ └── utils │ └── vaadinbridge │ ├── ApplicationFactory.java │ └── internal │ ├── ApplicationFactoryServlet.java │ ├── ApplicationFactoryTracker.java │ ├── BundleContentHttpContext.java │ ├── HttpServiceTracker.java │ ├── LogTracker.java │ ├── TargetBundleHttpContext.java │ └── VaadinBridgeActivator.java └── voting ├── README.txt ├── command ├── pom.xml └── src │ └── main │ ├── java │ └── net │ │ └── lr │ │ └── tutorial │ │ └── karaf │ │ └── vote │ │ └── command │ │ └── impl │ │ ├── VoteAdd.java │ │ └── VoteStats.java │ └── resources │ └── OSGI-INF │ └── blueprint │ └── command.xml ├── features ├── pom.xml └── src │ └── main │ └── resources │ └── features.xml ├── model ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── lr │ │ └── tutorial │ │ └── karaf │ │ └── vote │ │ └── model │ │ ├── Vote.java │ │ ├── VoteService.java │ │ ├── VoteStats.java │ │ ├── Voting.java │ │ ├── VotingLink.java │ │ └── VotingLinks.java │ └── test │ └── java │ └── net │ └── lr │ └── tutorial │ └── karaf │ └── vote │ └── model │ └── VotingTest.java ├── pom.xml ├── service ├── pom.xml └── src │ └── main │ ├── java │ └── net │ │ └── lr │ │ └── tutorial │ │ └── karaf │ │ └── vote │ │ └── service │ │ └── MemoryVoteService.java │ └── resources │ └── OSGI-INF │ └── blueprint │ └── context.xml ├── twitter-adapter ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── lr │ │ │ └── tutorial │ │ │ └── karaf │ │ │ └── vote │ │ │ └── adapter │ │ │ ├── IrcConverter.java │ │ │ ├── TwitterConverter.java │ │ │ ├── VotingRoutes.java │ │ │ └── VotingStarter.java │ └── resources │ │ └── OSGI-INF │ │ └── blueprint │ │ └── blueprint.xml │ └── test │ ├── java │ └── net │ │ └── lr │ │ └── tutorial │ │ └── karaf │ │ └── vote │ │ └── adapter │ │ └── TwitterConverterTest.java │ └── resources │ └── log4j.properties ├── ui ├── pom.xml └── src │ └── main │ ├── java │ └── net │ │ └── lr │ │ └── karaf │ │ └── tutorial │ │ └── vote │ │ └── ui │ │ └── VoteChartServlet.java │ └── resources │ ├── OSGI-INF │ └── blueprint │ │ └── context.xml │ └── index.html └── voting-ui2 ├── bin ├── pom.xml └── src │ └── main │ └── java │ └── my │ └── MyServlet.class ├── pom.xml └── src └── main └── java └── my └── MyServlet.java /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .project 3 | .classpath 4 | .settings 5 | in 6 | generated/ 7 | .DS_store 8 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Tutorial Series about writing OSGi applications using the Apache Karaf server. 2 | 3 | For the full textual tutorials see: 4 | 5 | http://cschneider.github.io/Karaf-Tutorial/ 6 | 7 | The tutorials show OSGi standards like ConfigAdmin Service or Blueprint as well Karaf specific implementations like features. The main idea is that 8 | each tutorial shows one specific concept and can be easily tested and extended. Each tutorial should not take more than 30 minutes to read and test. 9 | 10 | Join the chat at https://gitter.im/cschneider/Karaf-Tutorial 11 | 12 | -------------------------------------------------------------------------------- /camel/jms2rest/bnd.bnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/camel/jms2rest/bnd.bnd -------------------------------------------------------------------------------- /camel/jms2rest/src/main/resources/OSGI-INF/metatype/jms2rest.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /camel/jms2rest/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /camel/jms2rest/src/test/resources/person1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1001 4 | Christian Schneider 5 | http://www.liquid-reality.de 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /camel/jms2rest/src/test/resources/person2jms.cfg: -------------------------------------------------------------------------------- 1 | personServiceUri=http://localhost:8586/cxf/person 2 | -------------------------------------------------------------------------------- /camel/order/bnd.bnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/camel/order/bnd.bnd -------------------------------------------------------------------------------- /camel/order/src/main/java/net/lr/tutorial/karaf/camel/order/GetVendorMail.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.tutorial.karaf.camel.order; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | import org.apache.camel.language.XPath; 23 | 24 | /** 25 | * Resolves the mail address of a vendor by extracting the vendor name from the 26 | * message and mapping it to a mail address. 27 | * 28 | * This shows how to use a java bean in a camel route and how to map parts of the 29 | * message to input parameters. 30 | * 31 | */ 32 | public class GetVendorMail { 33 | Map mailMap = new HashMap(); 34 | 35 | public GetVendorMail(String testMailAdress) { 36 | mailMap.put("vendor1", testMailAdress); 37 | } 38 | 39 | public String getMail(@XPath("/item/@vendor") String vendor) { 40 | return mailMap.get(vendor); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /camel/order/src/main/java/net/lr/tutorial/karaf/camel/order/Starter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.tutorial.karaf.camel.order; 18 | 19 | import org.apache.camel.CamelContext; 20 | import org.apache.camel.component.properties.PropertiesComponent; 21 | import org.apache.camel.impl.DefaultCamelContext; 22 | 23 | /** 24 | * Starter for the Jms2RestAdpter to run it easily from Eclipse 25 | */ 26 | public class Starter { 27 | 28 | public void run() throws Exception { 29 | CamelContext context = new DefaultCamelContext(); 30 | context.addComponent("properties", new PropertiesComponent("sampleconfig.properties")); 31 | context.addRoutes(new OrderRouteBuilder()); 32 | context.start(); 33 | System.in.read(); 34 | context.stop(); 35 | } 36 | 37 | public static void main(String[] args) throws Exception { 38 | new Starter().run(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /camel/order/src/main/resources/OSGI-INF/metatype/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /camel/order/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /camel/order/src/main/resources/mailtemplate.txt: -------------------------------------------------------------------------------- 1 | Order from ${headers.customer} 2 | 3 | Count: ${headers.count}, Article: ${headers.name} 4 | -------------------------------------------------------------------------------- /camel/order/src/main/resources/sampleconfig.properties: -------------------------------------------------------------------------------- 1 | # This is just for the Starter class to work 2 | mailserver=mail.die-schneider.net 3 | -------------------------------------------------------------------------------- /camel/order/src/test/resources/order1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Christian Schneider 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /camel/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 4.0.0 23 | 24 | net.lr.tutorial.karaf.camel 25 | camel-tutorial-parent 26 | 1.0-SNAPSHOT 27 | pom 28 | 29 | 30 | jms2rest 31 | order 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /camel/simple-blueprint/ReadMe.txt: -------------------------------------------------------------------------------- 1 | SimpleCamel 2 | =========== 3 | 4 | This example just contains a blueprint file with a camel context and a route. 5 | 6 | Run in Karaf 7 | ------------ 8 | 9 | feature:repo-add camel 2.16.2 10 | feature:install camel-blueprint camel-stream 11 | 12 | Copy the file simple-camel-blueprint.xml into the deploy folder of karaf 13 | 14 | > list 15 | 16 | Should show something like that: 17 | [ 168] [Active ] [Created ] [ ] [ 60] simplecamel.xml (0.0.0) 18 | 19 | You will see "Hello World" printed to the karaf console every 5 seconds. 20 | 21 | Test 22 | ---- 23 | 24 | As karaf listens to changes to the files in the deploy folder you can change the file and save to update it in karaf. 25 | Open the file simplecamel.xml in the deploy folder using a text editor. 26 | 27 | Change "stream:out" to "log:simplecamel" and save the file. 28 | 29 | Now the the console should not show any more Hello World and instead the lines should go to the karaf log. 30 | 31 | > log:display 32 | 33 | Should show lines like: 34 | 2011-12-29 16:26:48,104 | INFO | simple | simplecamel | ache.camel.processor.CamelLogger 87 | 84 - org.apache.camel.camel-core - 2.8.2 | Exchange[ExchangePattern:InOnly, BodyType:String, Body:Hello World] 35 | 36 | -------------------------------------------------------------------------------- /camel/simple-blueprint/simple-camel-blueprint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Hello World 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /cameljpa/jpa2jms/src/main/java/net/lr/tutorial/karaf/camel/jpa2jms/ExceptionDecider.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.camel.jpa2jms; 2 | 3 | import net.lr.tutorial.karaf.camel.jpa2jms.model.Person; 4 | 5 | public class ExceptionDecider { 6 | public void decideException(Person person) { 7 | if ("error".equals(person.getName())) { 8 | throw new RuntimeException("Exception to check if transactions and redelivery work"); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /cameljpa/jpa2jms/src/main/java/net/lr/tutorial/karaf/camel/jpa2jms/model/Person.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.camel.jpa2jms.model; 2 | 3 | import javax.persistence.Entity; 4 | import javax.xml.bind.annotation.XmlRootElement; 5 | import javax.xml.bind.annotation.XmlType; 6 | 7 | @Entity 8 | @XmlType 9 | @XmlRootElement 10 | public class Person { 11 | private String name; 12 | private String twitterName; 13 | 14 | public Person() { 15 | } 16 | 17 | public Person(String name, String twitterName) { 18 | super(); 19 | this.name = name; 20 | this.twitterName = twitterName; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | public String getTwitterName() { 30 | return twitterName; 31 | } 32 | public void setTwitterName(String twitterName) { 33 | this.twitterName = twitterName; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /cameljpa/jpa2jms/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | 25 | osgi:service/javax.sql.XADataSource/(osgi.jndi.service.name=jdbc/derbydsxa) 26 | net.lr.tutorial.karaf.camel.jpa2jms.model.Person 27 | true 28 | 29 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /cameljpa/jpa2jms/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /cameljpa/jpa2jms/src/test/resources/person1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1001 4 | Christian Schneider 5 | http://www.liquid-reality.de 6 | 7 | -------------------------------------------------------------------------------- /cameljpa/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 4.0.0 23 | 24 | net.lr.tutorial.karaf.cameljpa 25 | camel-tutorial-parent 26 | 1.0-SNAPSHOT 27 | pom 28 | 29 | 30 | jpa2jms 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /configadmin/configadmin-features/src/main/resources/ConfigApp.cfg: -------------------------------------------------------------------------------- 1 | title=My Title 2 | 3 | -------------------------------------------------------------------------------- /configadmin/configadmin-features/src/main/resources/features.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | mvn:net.lr.tutorial.configadmin/configapp/${pom.version} 8 | mvn:net.lr.tutorial.configadmin/configapp-blueprint/${pom.version} 9 | mvn:net.lr.tutorial.configadmin/configadmin-features/${pom.version}/cfg 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /configadmin/configapp-blueprint/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | net.lr.tutorial.configadmin 7 | configapp-blueprint 8 | 1.0 9 | bundle 10 | 11 | 12 | 13 | 14 | org.osgi 15 | org.osgi.compendium 16 | 4.2.0 17 | 18 | 19 | org.osgi 20 | org.osgi.core 21 | 4.2.0 22 | 23 | 24 | 25 | 26 | ${project.artifactId} 27 | 28 | 29 | org.apache.maven.plugins 30 | maven-compiler-plugin 31 | 2.3.2 32 | 33 | 1.6 34 | 1.6 35 | 36 | 37 | 38 | org.apache.felix 39 | maven-bundle-plugin 40 | 2.3.5 41 | true 42 | 43 | 44 | ${project.artifactId} 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /configadmin/configapp-blueprint/src/main/java/net/lr/tutorial/configadmin/MyApp.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.configadmin; 2 | 3 | public class MyApp { 4 | String title; 5 | 6 | public void setTitle(String title) { 7 | this.title = title; 8 | System.out.println("setting title=" + title); 9 | } 10 | 11 | public void refresh() { 12 | System.out.println("Configuration updated using blueprint (title=" + title + ")"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /configadmin/configapp-blueprint/src/main/resources/OSGI-INF/blueprint/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /configadmin/configapp/osgi.bnd: -------------------------------------------------------------------------------- 1 | #----------------------------------------------------------------- 2 | # Use this file to add customized Bnd instructions for the bundle 3 | #----------------------------------------------------------------- 4 | 5 | Bundle-Activator: ${bundle.namespace}.internal.ExampleActivator 6 | -------------------------------------------------------------------------------- /configadmin/configapp/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | net.lr.tutorial.configadmin 7 | configapp 8 | 1.0 9 | bundle 10 | 11 | 12 | 13 | org.osgi 14 | org.osgi.compendium 15 | 4.2.0 16 | 17 | 18 | org.osgi 19 | org.osgi.core 20 | 4.2.0 21 | 22 | 23 | 24 | 25 | ${project.artifactId} 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-compiler-plugin 30 | 2.3.2 31 | 32 | 1.6 33 | 1.6 34 | 35 | 36 | 37 | org.apache.felix 38 | maven-bundle-plugin 39 | 2.3.5 40 | true 41 | 42 | 43 | ${project.artifactId} 44 | net.lr.tutorial.configadmin.Activator 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /configadmin/configapp/src/main/java/net/lr/tutorial/configadmin/Activator.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.configadmin; 2 | 3 | import java.util.Dictionary; 4 | import java.util.Hashtable; 5 | 6 | import org.osgi.framework.BundleActivator; 7 | import org.osgi.framework.BundleContext; 8 | import org.osgi.framework.Constants; 9 | import org.osgi.framework.ServiceRegistration; 10 | import org.osgi.service.cm.ConfigurationException; 11 | import org.osgi.service.cm.ManagedService; 12 | 13 | public class Activator implements BundleActivator { 14 | private static final String CONFIG_PID = "ConfigApp"; 15 | private ServiceRegistration serviceReg; 16 | private MyApp app; 17 | 18 | @Override 19 | public void start(BundleContext context) throws Exception { 20 | Hashtable properties = new Hashtable(); 21 | properties.put(Constants.SERVICE_PID, CONFIG_PID); 22 | serviceReg = context.registerService(ManagedService.class.getName(), new ConfigUpdater() , properties); 23 | } 24 | 25 | @Override 26 | public void stop(BundleContext context) throws Exception { 27 | serviceReg.unregister(); 28 | } 29 | 30 | /** 31 | * Updates the configuration in the application. Of course your class can also directly implement ManagedService but this 32 | * way you can work with pojos 33 | */ 34 | private final class ConfigUpdater implements ManagedService { 35 | @SuppressWarnings("rawtypes") 36 | @Override 37 | public void updated(Dictionary config) throws ConfigurationException { 38 | if (config == null) { 39 | return; 40 | } 41 | if (app == null) { 42 | app = new MyApp(); 43 | } 44 | app.setTitle((String)config.get("title")); 45 | app.refresh(); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /configadmin/configapp/src/main/java/net/lr/tutorial/configadmin/MyApp.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.configadmin; 2 | 3 | 4 | public class MyApp { 5 | String title; 6 | 7 | public void setTitle(String title) { 8 | this.title = title; 9 | } 10 | 11 | public void refresh() { 12 | System.out.println("Configuration updated (title=" + title + ")"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /configadmin/configapp/src/main/resources/OSGI-INF/metatype/configapp.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /configadmin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | net.lr.tutorial 7 | configadmin 8 | 1.0 9 | pom 10 | 11 | 12 | configapp 13 | configapp-blueprint 14 | configadmin-features 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /configadmin/readme.md: -------------------------------------------------------------------------------- 1 | # Tutorial 2: Using the config admin service 2 | 3 | This tutorial will show how to use the config admin service in general as well as the special features Karaf provides for it. 4 | Please also read the tutorial article on my blog: 5 | 6 | 7 | ## Content 8 | 9 | - app: A little application that uses the config admin service to read config and be notified of config changes 10 | - app-blueprint: The same as above but now using blueprint to abstract away from the details of the config admin service 11 | 12 | ## Build 13 | 14 | mvn clean install 15 | 16 | ## Prerequiries 17 | Since Karaf 4.2.x the blueprint feature is not install automatically, you have to install it before. 18 | 19 | feature:install aries-blueprint 20 | 21 | ## Installation 22 | 23 | There is only an automated installation for the blueprint case. 24 | 25 | feature:repo-add mvn:net.lr.tutorial.configadmin/configadmin-features/1.0/xml 26 | feature:install tutorial-configadmin 27 | -------------------------------------------------------------------------------- /cxf/karaf_tutorial_part_4_cxf.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/cxf/karaf_tutorial_part_4_cxf.txt -------------------------------------------------------------------------------- /cxf/personservice-rest/model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 4.0.0 23 | 24 | personrest-model 25 | bundle 26 | 27 | 28 | net.lr.tutorial.karaf.cxf.personrest 29 | personrest-parent 30 | 1.0-SNAPSHOT 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /cxf/personservice-rest/model/src/main/java/net/lr/tutorial/karaf/cxf/personrest/model/Person.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.tutorial.karaf.cxf.personrest.model; 18 | 19 | import javax.xml.bind.annotation.XmlRootElement; 20 | 21 | @XmlRootElement 22 | public class Person { 23 | String id; 24 | String name; 25 | String url; 26 | 27 | public String getId() { 28 | return id; 29 | } 30 | public void setId(String id) { 31 | this.id = id; 32 | } 33 | public String getName() { 34 | return name; 35 | } 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | public String getUrl() { 40 | return url; 41 | } 42 | public void setUrl(String url) { 43 | this.url = url; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /cxf/personservice-rest/model/src/main/java/net/lr/tutorial/karaf/cxf/personrest/model/PersonService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.cxf.personrest.model; 2 | 3 | import javax.ws.rs.GET; 4 | import javax.ws.rs.POST; 5 | import javax.ws.rs.PUT; 6 | import javax.ws.rs.Path; 7 | import javax.ws.rs.PathParam; 8 | import javax.ws.rs.Produces; 9 | import javax.ws.rs.core.MediaType; 10 | 11 | @Produces(MediaType.APPLICATION_XML) 12 | public interface PersonService { 13 | @GET 14 | @Path("/") 15 | public Person[] getAll(); 16 | 17 | @GET 18 | @Path("/{id}") 19 | public Person getPerson(@PathParam("id") String id); 20 | 21 | @PUT 22 | @Path("/{id}") 23 | public void updatePerson(@PathParam("id") String id, Person person); 24 | 25 | @POST 26 | @Path("/") 27 | public void addPerson(Person person); 28 | } 29 | -------------------------------------------------------------------------------- /cxf/personservice-rest/server/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /cxf/personservice-rest/server/src/test/resources/person1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1001 4 | Christian Schneider 5 | http://www.liquid-reality.de 6 | 7 | -------------------------------------------------------------------------------- /cxf/personservice-rest/webui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 4.0.0 23 | 24 | personrest-webui 25 | bundle 26 | 27 | 28 | net.lr.tutorial.karaf.cxf.personrest 29 | personrest-parent 30 | 1.0-SNAPSHOT 31 | 32 | 33 | 34 | 35 | javax.servlet 36 | servlet-api 37 | 2.5 38 | 39 | 40 | ${project.groupId} 41 | personrest-model 42 | ${project.version} 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /cxf/personservice-rest/webui/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /cxf/personservice-rest/webui/src/test/resources/person1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1001 4 | Christian Schneider 5 | http://www.liquid-reality.de 6 | 7 | -------------------------------------------------------------------------------- /cxf/personservice/bnd.bnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/cxf/personservice/bnd.bnd -------------------------------------------------------------------------------- /cxf/personservice/model/bnd.bnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/cxf/personservice/model/bnd.bnd -------------------------------------------------------------------------------- /cxf/personservice/model/src/main/java/net/lr/tutorial/karaf/cxf/personservice/model/ObjectFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.tutorial.karaf.cxf.personservice.model; 18 | 19 | import javax.xml.bind.JAXBElement; 20 | import javax.xml.bind.annotation.XmlElementDecl; 21 | import javax.xml.bind.annotation.XmlRegistry; 22 | import javax.xml.namespace.QName; 23 | 24 | @XmlRegistry 25 | public class ObjectFactory { 26 | private final static QName _PERSON_QNAME = new QName("http://person.jms2rest.camel.karaf.tutorial.lr.net", "person"); 27 | 28 | @XmlElementDecl(namespace = "http://person.jms2rest.camel.karaf.tutorial.lr.net", name = "person") 29 | public JAXBElement createPerson(Person person) { 30 | return new JAXBElement(_PERSON_QNAME, Person.class, person); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cxf/personservice/model/src/main/java/net/lr/tutorial/karaf/cxf/personservice/model/Person.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.tutorial.karaf.cxf.personservice.model; 18 | 19 | import javax.xml.bind.annotation.XmlRootElement; 20 | 21 | @XmlRootElement 22 | public class Person { 23 | String id; 24 | String name; 25 | String url; 26 | 27 | public String getId() { 28 | return id; 29 | } 30 | public void setId(String id) { 31 | this.id = id; 32 | } 33 | public String getName() { 34 | return name; 35 | } 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | public String getUrl() { 40 | return url; 41 | } 42 | public void setUrl(String url) { 43 | this.url = url; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /cxf/personservice/model/src/main/java/net/lr/tutorial/karaf/cxf/personservice/model/PersonService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.cxf.personservice.model; 2 | 3 | import javax.jws.WebService; 4 | 5 | @WebService 6 | public interface PersonService { 7 | public Person[] getAll(); 8 | public Person getPerson(String id); 9 | public void updatePerson(String id, Person person); 10 | public void addPerson(Person person); 11 | } 12 | -------------------------------------------------------------------------------- /cxf/personservice/proxy/bnd.bnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/cxf/personservice/proxy/bnd.bnd -------------------------------------------------------------------------------- /cxf/personservice/server/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /cxf/personservice/server/src/test/resources/person1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1001 4 | Christian Schneider 5 | http://www.liquid-reality.de 6 | 7 | -------------------------------------------------------------------------------- /cxf/personservice/webui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 4.0.0 23 | 24 | personservice-webui 25 | bundle 26 | 27 | 28 | net.lr.tutorial.karaf.cxf.personservice 29 | personservice-parent 30 | 1.0-SNAPSHOT 31 | 32 | 33 | 34 | 35 | javax.servlet 36 | servlet-api 37 | 2.5 38 | 39 | 40 | ${project.groupId} 41 | personservice-model 42 | ${project.version} 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /cxf/personservice/webui/src/main/resources/OSGI-INF/blueprint/blueprint.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /cxf/personservice/webui/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /cxf/personservice/webui/src/test/resources/person1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1001 4 | Christian Schneider 5 | http://www.liquid-reality.de 6 | 7 | -------------------------------------------------------------------------------- /cxf/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | net.lr.tutorial.karaf.cxf 7 | karaf-tutorial-cxf 8 | 1.0 9 | pom 10 | 11 | 12 | personservice 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /db/README.md: -------------------------------------------------------------------------------- 1 | Karaf Tutorial 6 - Database access 2 | ================================== 3 | 4 | See [Karaf Tutorial 6 on the web](http://cschneider.github.io/Karaf-Tutorial/06/). 5 | 6 | Installing Database drivers 7 | =========================== 8 | 9 | H2 10 | -- 11 | 12 | feature:install pax-jdbc-h2 13 | 14 | Derby 15 | ----- 16 | 17 | feature:install pax-jdbc-derby 18 | 19 | HSQL 20 | ---- 21 | 22 | feature:install pax-jdbc-hsqldb 23 | 24 | Oracle 25 | ------ 26 | 27 | As Oracle does not publish the driver in the maven repo we will first have to install the driver in our local maven repo. 28 | You will have eventually have to adjust the path and version. The command below is for windows and Oracle 11 Express. 29 | 30 | mvn install:install-file -Dfile="C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib\ojdbc6.jar" -DgroupId=ojdbc -DartifactId=ojdbc -Dversion=11.2.0.2.0 -Dpackaging=jar 31 | 32 | Then we can install the driver in Karaf. As it is no bundle we use the wrap protocol to create a suitable Manifest on the fly: 33 | 34 | install -s wrap:mvn:ojdbc/ojdbc/11.2.0.2.0 35 | feature:install pax-jdbc-oracle 36 | 37 | Postgresql 38 | ---------- 39 | 40 | Postgres does not build their driver as a bundle so we have to use the war protocol. 41 | 42 | install -s wrap:mvn:postgresql/postgresql/9.1-901-1.jdbc4 43 | feature:install pax-jdbc-postgresql 44 | 45 | DB2 46 | --- 47 | 48 | As IBM does not publish the driver in the maven repo we will first have to install the driver in our local maven repo. 49 | 50 | mvn install:install-file -DgroupId=com.ibm.db2.jdbc -DartifactId=db2jcc -Dversion=9.7 -Dpackaging=jar -Dfile="C:\Program Files (x86)\IBM\SQLLIB\java\db2jcc.jar" 51 | 52 | Then we can install the driver in Karaf. As it is no bundle we use the wrap protocol to create a suitable Manifest on the fly: 53 | 54 | install -s wrap:mvn:com.ibm.db2.jdbc/db2jcc/9.7 55 | feature:install pax-jdbc-db2 56 | -------------------------------------------------------------------------------- /db/examplejdbc/ReadMe.txt: -------------------------------------------------------------------------------- 1 | dbexample 2 | --------- 3 | 4 | Example how to access a DataSource using OSGi services and jdbc. 5 | 6 | Build 7 | ----- 8 | mvn clean install 9 | 10 | Installation 11 | ------------ 12 | 13 | feature:repo-add pax-jdbc 1.3.0 14 | feature:install scr transaction jndi pax-jdbc-h2 pax-jdbc-pool-dbcp2 pax-jdbc-config 15 | 16 | cat https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/master/db/org.ops4j.datasource-person.cfg | tac etc/org.ops4j.datasource-person.cfg 17 | install -s mvn:net.lr.tutorial.karaf.db/db-examplejdbc/1.0-SNAPSHOT 18 | 19 | Test 20 | ---- 21 | 22 | The example creates and populates a table on startup, queries it and outputs the result 23 | 24 | The output should look like this: 25 | ------------------------------------------- 26 | Using datasource H2, URL jdbc:h2:~/test 27 | Christian Schneider, @schneider_chris, 28 | ------------------------------------------- 29 | -------------------------------------------------------------------------------- /db/examplejdbc/src/test/java/net/lr/tutorial/karaf/db/example/DbExampleTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.tutorial.karaf.db.example; 18 | 19 | import org.h2.jdbcx.JdbcDataSource; 20 | import org.junit.Test; 21 | 22 | public class DbExampleTest { 23 | 24 | @Test 25 | public void test() throws Exception { 26 | JdbcDataSource ds = new JdbcDataSource(); 27 | ds.setURL("jdbc:h2:mem:person"); 28 | DbExample example = new DbExample(); 29 | example.setDataSource(ds); 30 | example.test(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /db/examplejpa/ReadMe.txt: -------------------------------------------------------------------------------- 1 | dbexample 2 | --------- 3 | 4 | Example how to access a DataSource using jpa and declarative services. 5 | In a real world application you might want to split into an API bundle, an service bundle and a UI bundle. 6 | For this example we keep all these in one bundle. 7 | 8 | Build 9 | ----- 10 | 11 | mvn clean install 12 | 13 | Installation 14 | ------------ 15 | 16 | feature:install scr transaction jndi pax-jdbc-h2 pax-jdbc-config pax-jdbc-pool-dbcp2 jpa hibernate/5.4.2.Final 17 | cat https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/master/db/org.ops4j.datasource-person.cfg | tac etc/org.ops4j.datasource-person.cfg 18 | install -s mvn:net.lr.tutorial.karaf.db/db-examplejpa/1.0-SNAPSHOT 19 | 20 | The commands above are tested with karaf 4.2.5. For other karaf versions you might need to change the versions above to the ones available. 21 | 22 | Test 23 | ---- 24 | 25 | The bundle installs two Karaf shell commands: 26 | 27 | person:add 'Christian Schneider' @schneider_chris 28 | 29 | karaf@root> person:list 30 | Christian Schneider, @schneider_chris 31 | -> Lists all persisted Persons 32 | -------------------------------------------------------------------------------- /db/examplejpa/bnd.bnd: -------------------------------------------------------------------------------- 1 | Import-Package: \ 2 | org.hibernate.proxy,\ 3 | javassist.util.proxy,\ 4 | * 5 | Meta-Persistence: META-INF/persistence.xml 6 | -------------------------------------------------------------------------------- /db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/Person.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.db.examplejpa; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.Id; 5 | 6 | @Entity 7 | public class Person { 8 | @Id 9 | private String name; 10 | private String twitterName; 11 | 12 | public Person() { 13 | } 14 | 15 | public Person(String name, String twitterName) { 16 | super(); 17 | this.name = name; 18 | this.twitterName = twitterName; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | public String getTwitterName() { 28 | return twitterName; 29 | } 30 | public void setTwitterName(String twitterName) { 31 | this.twitterName = twitterName; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/PersonService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.db.examplejpa; 2 | 3 | import java.util.List; 4 | 5 | public interface PersonService { 6 | void add(Person person); 7 | void deleteAll(); 8 | List getAll(); 9 | } 10 | -------------------------------------------------------------------------------- /db/examplejpa/src/main/java/net/lr/tutorial/karaf/db/examplejpa/impl/PersonServiceImpl.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.db.examplejpa.impl; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.aries.jpa.template.JpaTemplate; 6 | import org.osgi.service.component.annotations.Component; 7 | import org.osgi.service.component.annotations.Reference; 8 | 9 | import net.lr.tutorial.karaf.db.examplejpa.Person; 10 | import net.lr.tutorial.karaf.db.examplejpa.PersonService; 11 | 12 | @Component 13 | public class PersonServiceImpl implements PersonService { 14 | private JpaTemplate jpa; 15 | 16 | @Reference(target = "(osgi.unit.name=person)") 17 | public void setJpa(JpaTemplate jpa) { 18 | this.jpa = jpa; 19 | } 20 | 21 | @Override 22 | public void add(Person person) { 23 | jpa.tx(em -> { 24 | em.persist(person); 25 | em.flush(); 26 | }); 27 | } 28 | 29 | public void deleteAll() { 30 | jpa.tx(em -> { 31 | em.createQuery("delete from Person").executeUpdate(); 32 | em.flush(); 33 | }); 34 | } 35 | 36 | @Override 37 | public List getAll() { 38 | return jpa.txExpr(em -> em.createQuery("select p from Person p", Person.class).getResultList()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /db/examplejpa/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | 25 | org.hibernate.jpa.HibernatePersistenceProvider 26 | osgi:service/javax.sql.DataSource 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /db/examplejpa/src/test/java/net/lr/tutorial/karaf/db/examplejpa/PersonServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.db.examplejpa; 2 | 3 | import java.util.List; 4 | 5 | import javax.persistence.EntityManager; 6 | import javax.persistence.EntityManagerFactory; 7 | import javax.persistence.Persistence; 8 | 9 | import net.lr.tutorial.karaf.db.examplejpa.impl.PersonServiceImpl; 10 | 11 | import org.apache.aries.jpa.template.JpaTemplate; 12 | import org.junit.Assert; 13 | import org.junit.Test; 14 | 15 | /** 16 | * To test a persistence class we need to create and inject the EntityManager and 17 | * we need to manage the transaction by hand. 18 | */ 19 | public class PersonServiceImplTest { 20 | 21 | @Test 22 | public void testWriteRead() throws Exception { 23 | PersonServiceImpl personService = new PersonServiceImpl(); 24 | EntityManagerFactory emf = Persistence.createEntityManagerFactory("person", System.getProperties()); 25 | EntityManager em = emf.createEntityManager(); 26 | JpaTemplate jpaTemplate = new TestTemplate(em); 27 | personService.setJpa(jpaTemplate); 28 | personService.deleteAll(); 29 | personService.add(new Person("Christian Schneider", "@schneider_chris")); 30 | 31 | List persons = personService.getAll(); 32 | Assert.assertEquals(1, persons.size()); 33 | Assert.assertEquals("Christian Schneider", persons.get(0).getName()); 34 | Assert.assertEquals("@schneider_chris", persons.get(0).getTwitterName()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /db/examplejpa/src/test/java/net/lr/tutorial/karaf/db/examplejpa/TestTemplate.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.db.examplejpa; 2 | 3 | import javax.persistence.EntityManager; 4 | 5 | import org.apache.aries.jpa.template.EmConsumer; 6 | import org.apache.aries.jpa.template.EmFunction; 7 | import org.apache.aries.jpa.template.JpaTemplate; 8 | import org.apache.aries.jpa.template.TransactionType; 9 | 10 | public class TestTemplate implements JpaTemplate { 11 | 12 | private EntityManager em; 13 | 14 | public TestTemplate(EntityManager em) { 15 | this.em = em; 16 | } 17 | 18 | @Override 19 | public R txExpr(TransactionType type, EmFunction code) { 20 | em.getTransaction().begin(); 21 | try { 22 | R result = code.apply(em); 23 | em.getTransaction().commit(); 24 | return result; 25 | } catch (RuntimeException e) { 26 | em.getTransaction().rollback(); 27 | throw e; 28 | } 29 | } 30 | 31 | @Override 32 | public void tx(TransactionType type, EmConsumer code) { 33 | txExpr(type, em -> {code.accept(em); return null;}); 34 | } 35 | 36 | @Override 37 | public R txExpr(EmFunction code) { 38 | return txExpr(TransactionType.Required, code); 39 | } 40 | 41 | @Override 42 | public void tx(EmConsumer code) { 43 | tx(TransactionType.Required, code); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /db/examplejpa/src/test/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | 25 | org.hibernate.jpa.HibernatePersistenceProvider 26 | net.lr.tutorial.karaf.db.examplejpa.Person 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /db/examplejpa/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /db/org.ops4j.datasource-person.cfg: -------------------------------------------------------------------------------- 1 | osgi.jdbc.driver.name=H2 2 | pool=dbcp2 3 | xa=true 4 | url=jdbc:h2:mem:test 5 | dataSourceName=person 6 | -------------------------------------------------------------------------------- /db/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 4.0.0 23 | 24 | net.lr.tutorial.karaf.db 25 | db-parent 26 | 1.0-SNAPSHOT 27 | pom 28 | 29 | 30 | 1.2.16 31 | 1.7.4 32 | 33 | 34 | 35 | examplejdbc 36 | examplejpa 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /dbng/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Example for the "Karaf Tutorial 11 - Database next gen - liquibase and query dsl" 4 | 5 | # Structure 6 | 7 | * migrator - Migration logic for the database schema based on liquibase and ops4j PreHook 8 | * service - Repository and gogo command accessing the db using query dsl 9 | 10 | # Build 11 | 12 | Make sure to use JDK 8. 13 | 14 | mvn clean install 15 | 16 | # Installation 17 | 18 | Make sure you use JDK 8. 19 | Download and extract Karaf 4.1.1. 20 | 21 | Start karaf and execute the commands below 22 | 23 | ```Shell 24 | cat https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/master/dbng/org.ops4j.datasource-person.cfg | tac -f etc/org.ops4j.datasource-person.cfg 25 | feature:repo-add mvn:net.lr.tutorial.dbng/dbng/1.0.0-SNAPSHOT/xml/features 26 | feature:install example-dbng 27 | ``` 28 | 29 | # Test 30 | 31 | In gogo shell 32 | 33 | ```Shell 34 | person:list 35 | ``` 36 | -------------------------------------------------------------------------------- /dbng/features/src/main/resources/features.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | mvn:org.ops4j.pax.jdbc/pax-jdbc-features/1.1.0/xml/features 4 | 5 | 6 | scr 7 | pax-jdbc-h2 8 | pax-jdbc-config 9 | mvn:org.yaml/snakeyaml/1.17 10 | mvn:org.liquibase/liquibase-osgi/3.4.2 11 | mvn:${groupId}/net.lr.tutorial.dbng.migrator/${pom.version} 12 | mvn:${groupId}/net.lr.tutorial.dbng.service/${pom.version} 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /dbng/migrator/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | net.lr.tutorial.dbng 6 | dbng-parent 7 | 1.0.0-SNAPSHOT 8 | .. 9 | 10 | net.lr.tutorial.dbng.migrator 11 | 12 | 13 | 14 | org.liquibase 15 | liquibase-core 16 | 3.4.2 17 | 18 | 19 | org.ops4j.pax.jdbc 20 | pax-jdbc-pool-common 21 | 1.1.0 22 | 23 | 24 | com.h2database 25 | h2 26 | 1.4.191 27 | test 28 | 29 | 30 | -------------------------------------------------------------------------------- /dbng/migrator/src/main/resources/changesets.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 1 18 | Chris 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /dbng/migrator/src/test/java/net/lr/tutorial/db/MigrateTest.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | 7 | import org.h2.jdbcx.JdbcDataSource; 8 | import org.junit.Assert; 9 | import org.junit.Test; 10 | 11 | import net.lr.tutorial.db.migration.Migrator; 12 | 13 | 14 | public class MigrateTest { 15 | 16 | @Test 17 | public void testMigrate() throws SQLException { 18 | JdbcDataSource ds = new JdbcDataSource(); 19 | ds.setUrl("jdbc:h2:mem:person;DB_CLOSE_DELAY=-1"); 20 | new Migrator().prepare(ds); 21 | try (Connection con = ds.getConnection()) { 22 | testQuery(con); 23 | } 24 | } 25 | 26 | private void testQuery(Connection con) throws SQLException { 27 | try (ResultSet rs = con.createStatement().executeQuery("select id, name, age from person")) { 28 | rs.next(); 29 | Assert.assertEquals(1, rs.getInt(1)); 30 | Assert.assertEquals("Chris", rs.getString(2)); 31 | Assert.assertEquals(29, rs.getInt(3)); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dbng/org.ops4j.datasource-person.cfg: -------------------------------------------------------------------------------- 1 | osgi.jdbc.driver.name=H2 2 | url=jdbc:h2:mem:person;DB_CLOSE_DELAY=-1 3 | dataSourceName=person 4 | ops4j.preHook=mydb 5 | 6 | -------------------------------------------------------------------------------- /dbng/service/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | net.lr.tutorial.dbng 6 | dbng-parent 7 | 1.0.0-SNAPSHOT 8 | 9 | net.lr.tutorial.dbng.service 10 | 11 | 12 | 13 | org.apache.felix 14 | org.apache.felix.gogo.runtime 15 | 0.16.2 16 | 17 | 18 | -------------------------------------------------------------------------------- /dbng/service/src/main/java/net/lr/tutorial/db/service/Person.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db.service; 2 | 3 | public class Person { 4 | private long id; 5 | private String name; 6 | 7 | public long getId() { 8 | return id; 9 | } 10 | 11 | public void setId(long id) { 12 | this.id = id; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return String.format("%d: %s", id, name); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dbng/service/src/main/java/net/lr/tutorial/db/service/PersonCommand.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db.service; 2 | 3 | import org.osgi.service.component.annotations.Component; 4 | import org.osgi.service.component.annotations.Reference; 5 | 6 | @Component(service=PersonCommand.class, 7 | property={"osgi.command.scope=person", 8 | "osgi.command.function=list"}) 9 | public class PersonCommand { 10 | 11 | @Reference 12 | PersonRepo persons; 13 | 14 | public void list() { 15 | System.out.println("Persons"); 16 | persons.list().stream().map(Person::toString).forEach(System.out::println); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dbng/service/src/main/java/net/lr/tutorial/db/service/PersonRepo.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db.service; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import javax.sql.DataSource; 10 | 11 | import org.osgi.service.component.annotations.Component; 12 | import org.osgi.service.component.annotations.Reference; 13 | 14 | @Component(service=PersonRepo.class) 15 | public class PersonRepo { 16 | @Reference 17 | DataSource ds; 18 | 19 | public List list() { 20 | try (Connection con = ds.getConnection()) { 21 | ArrayList persons = new ArrayList(); 22 | ResultSet rs = con.createStatement().executeQuery("select id, name from person"); 23 | while (rs.next()) { 24 | persons.add(read(rs)); 25 | } 26 | return persons; 27 | } catch (SQLException e) { 28 | throw new RuntimeException(e.getMessage(), e); 29 | } 30 | } 31 | 32 | private Person read(ResultSet rs) throws SQLException { 33 | Person person = new Person(); 34 | person.setId(rs.getInt("id")); 35 | person.setName(rs.getString("name")); 36 | return person; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/03/config-detail-typed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/03/config-detail-typed.png -------------------------------------------------------------------------------- /docs/03/config-detail-untyped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/03/config-detail-untyped.png -------------------------------------------------------------------------------- /docs/03/config-fileinstall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/03/config-fileinstall.png -------------------------------------------------------------------------------- /docs/03/config-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/03/config-list.png -------------------------------------------------------------------------------- /docs/04/Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/04/Overview.png -------------------------------------------------------------------------------- /docs/05/jms2rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/05/jms2rest.png -------------------------------------------------------------------------------- /docs/05/jms2rest.xml: -------------------------------------------------------------------------------- 1 | 5VnbbuM2EP0aA7sPMUhdrUc7m7QFdoG0adHdR9miZHYpUaXoW7++Q4rUxZIDJ3GLrOMHWzwih+TozMwxNXFv8/1PIi7XX3hC2MRByX7ifpo4DsYYwY9CDjUyC50ayARNTKcWeKT/EAOacdmGJqTqdZScM0nLPrjiRUFWsofFQvBdv1vKWX/WMs7IAHhcxWyI/kkTuTa7cMIW/5nQbG1nxkFU31nGq++Z4JvCzDdx3FR/6tt5bG2ZjVbrOOG7DuTeTdxbwbmsr/L9LWHKt9Zt9bj7E3ebdQtSyHMGuGYZ8mC3Disq1WVKGSPJXaIctaik4N8bVzgNcssZF3qcW3/gjhpo8YIX9fBYyLl6LoDxkhQWu4e+ACHbNkwIoE2KxI4wVgDp9IdWp7d2OUnMvbXMVTcMlwVzFsLAGaNpevhF9QqVBdjbo9k4F3LNM17E7K5FF2RP5Vc1eOqb1jdjtnYbSQY0ah1voIpvxMr2cptHDKFDeE6kOECfXcsxS6R1l141JAiLJd32Z4wN07PGWjPBA6ewFgfZqAydqes7URTMnACHeDarLZgQDfDUw57nI+RFUYSw17dfb8OY7BLqeBaknNU17AdT7AVg0/Uj7KJZ0DcMjz0jcmAYLjouaiHN33EumxVvY7YhNvoCBj5cJHTbI3nw90YF2KJ3lZlfPaIq42J0SMoLeVNp4s2xU+4tlMY5ZbDQ+VzQGFa4WNUhMBfZ8gPEIKwe2Z+PeiLEaEFu7HOeA1Bwkeuxw3X9lVd2aeCGenX9FQOst2nRo7CWZC9PRwaLl4QtmtzVCWuTvU6O3BIhKSTOOaMZhPWnnCaJjp3YACsICCJql65okX0mqdQhhVrsN8P1oyDFQbMTNQ3Zn4y1E3H10oixXXiaVuS1tAyum5aOIJV8HTdtyVnxvIRUrx5qQx+m6XJEHlcRoymdaFCg8FEZ6vJ4ULgQiiJ9h6s5pMpaKok9UUcuzvndmkryCLjywg4k1VEcoHPjAI/HgRngRV4vMzvjmblTjTBCw3IUoNOB1IuTJ4Ii/P91Rxc7T3cYpXJJ3YEdbQK89bUhhG5+a2WGaj4QQcGpxJoYVyItLwZKpC6rvQz0enFi+XN5ceJZorVq5CnRcEKNvCA7z647O79D0RCemyzDNywaoiumJeS2ihePRGwp5J4fWjmoz5tWDu5llEMwi47+1Z2hHVz/v9EO9pDo/YkHr6ME8NTqgo50gNZAOTxfbJyQFF2xEAxVRnQ2qbqKwp+OsOS5muJs5uArTqtrKcuJOu67h++HP35/h6V/dna2Q+PMfBO1HztXzNIvpKrU4fvzyHktuy+19MHvdPcf9jn7eBnBV3Cp63FdTPUByY+n6m7wS2Wd/0pZZ0WcP51FT4q4aOR1BPw39y9Qi92RLHdK3h+AZon24JhnOo9lWUuqz0sLCC4ho3P1FKILHaM5s74UvsGudUjHc86YrvEuIX+H7zl+3RC4hD3o9HJGLb+EF7z+iU0Yjjhh9PzQfb4ToNm+E61Lavvi2b37Fw== -------------------------------------------------------------------------------- /docs/05/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/05/order.png -------------------------------------------------------------------------------- /docs/05/order.xml: -------------------------------------------------------------------------------- 1 | 7VpLb+M2EP41BtpDApHU82g7yW6BLrpoDm2PjETJxFKiStGx3V/foUS9bLnrxEaQOquLxdE8yJlvHpY9I8t8+0nRcvVFJkzMsJNsZ+RuhjFCyIEPQ9k1lDDADSFTPLFMPeGR/8Ms0cpla56wasSopRSal2NiLIuCxXpEo0rJzZgtlWJstaQZOyA8xlQcUv/giV7ZU+Cgp39mPFu1lpEfNU+eaPwtU3JdWHszTNL6ah7ntNVlD1qtaCI3AxK5n5GlklI3d/l2yYTxbeu2Ru7hyNNu34oV+hQBG5ZnKtas3bEvQHSR8GezP72zPvH/XptNLUZ3mf2sJaqSFpMiqSz0TVUHeY5wuW1JKc25AITM54pTAdRYCqlgrbKnn2DfS9DWfvxcG3IEL9jNyrp+DoRCqryWPdzXbyphynhDyZhVFS+ydqfgj2az4wMAuT51S8Wj02CIVWluY5mXsqgdvKCCZwXQBEutC2Kw82u9uiO+IbURdsxCK/mtgxQyjuBCLJtj3/VgaTkHTxwniuon0tjQJrGQ49warSudC6uuEHihrLFnpjQHTM/tHnOeJOYs3aZjOAN4aH/bjVJL+92i3JA2K67ZI9CNFzaQ+UDLBE/T3S8GTrhzmrHMtkchiTqgQwFhMmda7YDFCmDP5oatHW5wi72GsulzEYWWazXIQ9/SqE3/rFPepwDc2CyYzghyxRkhTUag2y3A5SKZUEht8NQcBOB4Ubib6y3gfoNeiXdyJt5bfIcH4I6iCWyjW+98dLtHY2kiw5L7JGMHgcNTAWquvZAWUBdrZqr03PThPdoDNzuz2IC17fymTrIiaSVkyYqGMuCH1YC7brEssc+OIGIQK6/WAM76sytw9fKveukRcDlcmASO73gd81emOLiYtQob57Fkb3iAk2RMjxrqCeEfFjNvophZ5YoJqvnz2OIUBKyFr5KD4a6aRlELGwu3IOrKaaulkmsVMyvYYwnCQXcDttIwVMdN7RduY8nkMSGeHxFohmOcNup71HauOQnI3hWXacgodl6Bhmqkj+eFoE9MLLpJdaoev9VIMUhRhE6tp+50Qr02U1oWmaYV07P9avoyXPpXjMuEK/NlCw6rWf5jirjMFBFcZmr23HHxRTh6w7EiuGLUf6Fc1O8f6hAVCaj+AfuzYR9eCvb4DWEeXt30jE6aniOjYcu1GZ6bgJuVnZ3tan9W/o9p2wkNPJEPRcr1ifvCabuZVkfT9nAAD06G0HAAR/gQM67/mgn8pVOzS/am5u51x8MxidA/U4Kg70l0eTWQcKF+Ol4QhYREoXvRaT664v4BozhTBRV9+zASL+og1+KKvG6lH+6LzckvRsN3/MWm/WnmwzU/1Pa7/0P381/X/SZeP4XkvXY/70wJ5Dvfb3/OoYjpfy6JXI+gsfjZ7Q+hK+5/3VuDhAnAkfHJR+1/H/TF3uk/lDizd9MAYdn/DN+w9/91IPf/Ag== -------------------------------------------------------------------------------- /docs/07/jpa2jms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/07/jpa2jms.png -------------------------------------------------------------------------------- /docs/08/deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/08/deployment.png -------------------------------------------------------------------------------- /docs/08/deployment.xml: -------------------------------------------------------------------------------- 1 | 7Vrdb9s2EP9rDGwPDUTqy36006QbsGHBPKDd00BbtExUFjWKju399TuKpPXpxI1UN63jF4lHnni8+90dj/TIvd3sPwiSrX/nEU1G2In2I/f9CGOEkAMPRTloyjjEmhALFplBJWHO/qOGaPjiLYtoXhsoOU8ky+rEJU9TupQ1GhGC7+rDVjypz5qRmLYI8yVJ2tSPLJJrswoclvRfKIvXdmYUTHTPgiw/x4JvUzPfCLur4qe7N8R+yyw0X5OI7yok927k3grOpX7b7G9ponRr1ab57k/0HuUWNJXnMBiz5PJglw4SZep1uV3AY5Zr24Bh3FnEBCib8RQIOd+qpcyOC1ADcin456PGEFBWLEluecJF8XGrCzuy0uMUP+jhGVkyeSjmdG4UJU7YanX4VUkM+plpiR+pkHR/ctXoqEvAKOUbKsUBhuxKY7rY1WzriiGxZxRCDIDiI2+pRHgxeuzWqft96dTtqVPD4AYG0sbl8U3oa0JV6Z7fpXTnxu+vds8sgiRbap0vSGSh48eaPYJ/t8q/ZrW32DwLjjwjaSfLiqfynbbfFOFsb0krsmEJrHw6FYyAhLOlNsNUxIufQDEgvWMfPxcTOQlL6TurhykQUi42BW9bLohzksB48Q+xIoI6tJR1yYFcLNdSG0gE+yr6Wm4Sg6Y0wTNhsHaCrHDBIDhOExYrnG5YFKkPzoghLAEjVGi9LVka/0ZXyrYaaob2pzG4Iu3WTNI50JVUO0ghdUR6wyAyQHVA+riFR+Q7HXgcAIz+VYBxcQVg9IcBo+eNG2j0LofG4GJo3FkILYot17eCaEYFyyVNwaa9EGoTt9pAFphSws9NPyrx9BfPbEKXZGGTtWfax60i8jThgefM5PykQGeZ8lEr5eOBUv4r8adgGH8Kw5o7eWHbm5wObwoH8KbwNEzATDS6i2LauXE7ba2qfVOeanYi5FTVMg3aPVOSmb0htE31pPRK08hy8IymmlIZD615Ze9Z1Ck0Mp0RyddFQ+8x9++hbVqq64FIgIECxBgsjx3c3EeGagJYunUPLuSaxzwlyV1JNaanUaP+gq2vWNJatIK1xdSYbfKSHT7qCKbGdoImRLLHugxdmCgmAJ2SQ2VAxlkq88r8D4pQYhPhOjiRKbPuzx3v+mZDfDaHN2kgWMtc4vmoorMgPr62hLFlb4nilSWK8UAbr9CrZ4rgcplicm1utNEngW+e9Ko8aTLQlivozDkX8SR7MPzmSm+u9C1dqVDSV8hKyB48X8SZ0GmoXHMFg9BQJcy4XcLYCNa/hkGXqGF83AComeFURdIa76JnapgWh1erknrXMOj03RYMZFmubKkOiuCbKkJY6kNJeuompiOwHZ3hhTcxqO/11t4ipF4dht5N+yrGXv3VoDXA7Rc6ff31RHDBXVrTv68SXAzHqeAStGJL1UxKJLpn8pNqFEZUrb+LtOKbVgVF5tugx0/HzFM0NYfn+woc4DDIdTAa+7a7+Ykz4k7H0Yl1gy+LO15H6rlI3EGNg72x90wYaYJdMYBvgSbdABzPHAwOFlS8y6dOkwifQjdyesK7d+r0hkqdFq9VDI9fAmHsdt01XwLD2J3UIfnccZ7rBzZC92Bxn2Fp7jmbDP2d40e+9fxj/oHBiDkVj6zvtdJ3cfGJBrr5RH7jrNrpKHUGuvmEZvnfKY3g8g9q7t3/ -------------------------------------------------------------------------------- /docs/08/dosgi-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/08/dosgi-details.png -------------------------------------------------------------------------------- /docs/09/tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/docs/09/tasks.png -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | site.title: Tutorials for Apache Karaf 2 | theme: jekyll-theme-cayman 3 | plugins: 4 | - jekyll-mentions 5 | - jemoji 6 | - jekyll-redirect-from 7 | - jekyll-sitemap 8 | - jekyll-feed 9 | avatar: https://avatars1.githubusercontent.com/u/484584?s=96 10 | -------------------------------------------------------------------------------- /docs/_includes/head.html: -------------------------------------------------------------------------------- 1 | Head 2 | -------------------------------------------------------------------------------- /docs/_includes/sidebar.html: -------------------------------------------------------------------------------- 1 | Test 2 | -------------------------------------------------------------------------------- /docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% seo %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 |
22 | {{ content }} 23 | 24 |
25 | Back to Tutorials 26 |
27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/_sass/variables.scss: -------------------------------------------------------------------------------- 1 | // Breakpoints 2 | $large-breakpoint: 64em !default; 3 | $medium-breakpoint: 42em !default; 4 | 5 | // Headers 6 | $header-heading-color: #fff !default; 7 | $header-bg-color: #159957 !default; 8 | $header-bg-color-secondary: #155799 !default; 9 | 10 | // Text 11 | $section-headings-color: #159957 !default; 12 | $body-text-color: #606c71 !default; 13 | $body-link-color: #1e6bb8 !default; 14 | $blockquote-text-color: #819198 !default; 15 | 16 | // Code 17 | $code-bg-color: #f3f6fa !default; 18 | $code-text-color: #567482 !default; 19 | 20 | // Borders 21 | $border-color: #dce6f0 !default; 22 | $table-border-color: #e9ebec !default; 23 | $hr-border-color: #eff0f1 !default; 24 | -------------------------------------------------------------------------------- /docs/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import 'jekyll-theme-cayman'; 5 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Karaf Tutorials 2 | 3 | * [1 - Installation and First application](01) 4 | * [2 - Using the Configuration Admin Service](02) 5 | * [3 - Improving configuration editing using the OSGI Metatype Service and the Felix WebconsoleMetatype](03) 6 | * [4 - CXF Services in OSGi](04) 7 | * [5 - Apache Camel integrations in OSGi](05) 8 | * [6 - Database Access](06) 9 | * [7 - Camel JPA and JTA transactions](07) 10 | * [8 - Distributed OSGi](08) 11 | * [9 - Annotation based blueprint and JPA](09) 12 | * [10 - Declarative services](10) 13 | * [11 - Managing database schema with liquibase](11) 14 | -------------------------------------------------------------------------------- /jms/command/ReadMe.txt: -------------------------------------------------------------------------------- 1 | JMS commands for the Karaf shell 2 | -------------------------------- 3 | 4 | Allows to browse the defined connection factories and do commands on them 5 | 6 | Build 7 | ----- 8 | 9 | mvn clean install 10 | 11 | Installation 12 | ------------ 13 | 14 | The easiest way to test this is with activemq as it is easily installable in Apache Karaf. 15 | 16 | Install ActiveMQ 17 | > features:addurl mvn:org.apache.activemq/activemq-karaf/5.5.1/xml/features 18 | > features:install activemq activemq-spring activemq-blueprint 19 | 20 | Create and start a broker instance and a Connection Factory 21 | > activemq:create-broker 22 | 23 | Install the jms commands 24 | > install -s mvn:net.lr.karaf.jms/jms-command/1.0-SNAPSHOT 25 | 26 | Now you can use the commands on the installed activemq connection factory named localhost 27 | > jms:select localhost 28 | > jms:send testqueue "Some content" 29 | > jms:listqueues 30 | > jms:browse testqueue 31 | > jms:delete -a testqueue 32 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/command/DeleteCommand.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.command; 2 | 3 | import net.lr.karaf.jms.service.JmsService; 4 | 5 | import org.apache.felix.gogo.commands.Action; 6 | import org.apache.felix.gogo.commands.Argument; 7 | import org.apache.felix.gogo.commands.Command; 8 | import org.apache.felix.gogo.commands.Option; 9 | import org.apache.felix.service.command.CommandSession; 10 | 11 | @Command(scope = "jms", name = "delete", description = "delete one or more messages from a queue") 12 | public class DeleteCommand implements Action { 13 | @Argument(index = 0, name = "queueName", required = true, description = "queue name", multiValued = false) 14 | String queueName; 15 | 16 | @Argument(index = 1, name = "messageId", required = false, description = "Message ID", multiValued = false) 17 | String messageId; 18 | 19 | @Option(name = "-s", description = "JMS Selector for the messages to delete") 20 | String selector; 21 | 22 | @Option(name = "-a", description = "Delete all messages") 23 | boolean all; 24 | 25 | private JmsService jmsService; 26 | 27 | @Override 28 | public Object execute(CommandSession session) throws Exception { 29 | if (all) { 30 | selector = ""; 31 | } else if (messageId != null) { 32 | selector = String.format("JMSMessageID = '%s'", messageId); 33 | } else if (selector == null){ 34 | throw new RuntimeException("You have to use either -all, -sel or a message id"); 35 | } 36 | int numDeleted = jmsService.deleteMessages(queueName, selector); 37 | System.out.println(numDeleted + " messages deleted from queue " + queueName + " using selector " + selector); 38 | return null; 39 | } 40 | 41 | public void setJmsService(JmsService jmsService) { 42 | this.jmsService = jmsService; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/command/JmsConnectionFactoryNameCompleter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.karaf.jms.command; 18 | 19 | import java.util.List; 20 | 21 | import net.lr.karaf.jms.service.JmsSelect; 22 | 23 | import org.apache.karaf.shell.console.Completer; 24 | import org.apache.karaf.shell.console.completer.StringsCompleter; 25 | 26 | public class JmsConnectionFactoryNameCompleter implements Completer { 27 | private JmsSelect jmsSelect; 28 | 29 | public void setJmsSelect(JmsSelect jmsSelect) { 30 | this.jmsSelect = jmsSelect; 31 | } 32 | 33 | @Override 34 | public int complete(String buffer, int cursor, List candidates) { 35 | StringsCompleter delegate = new StringsCompleter(jmsSelect.getConnectionFactoryNames()); 36 | return delegate.complete(buffer, cursor, candidates); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/command/JmsQueueNameCompleter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.karaf.jms.command; 18 | 19 | import java.util.List; 20 | 21 | import net.lr.karaf.jms.service.JmsService; 22 | 23 | import org.apache.karaf.shell.console.Completer; 24 | import org.apache.karaf.shell.console.completer.StringsCompleter; 25 | 26 | public class JmsQueueNameCompleter implements Completer { 27 | private JmsService jmsService; 28 | 29 | @Override 30 | public int complete(String buffer, int cursor, List candidates) { 31 | StringsCompleter delegate = new StringsCompleter(jmsService.listQueues()); 32 | return delegate.complete(buffer, cursor, candidates); 33 | } 34 | 35 | public void setJmsService(JmsService jmsService) { 36 | this.jmsService = jmsService; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/command/ListQueueCommand.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.command; 2 | 3 | import java.util.List; 4 | 5 | import net.lr.karaf.jms.service.JmsService; 6 | import net.lr.karaf.jms.service.QueueInfo; 7 | 8 | import org.apache.felix.gogo.commands.Action; 9 | import org.apache.felix.gogo.commands.Command; 10 | import org.apache.felix.service.command.CommandSession; 11 | 12 | @Command(scope = "jms", name = "list-queue", description = "List queues") 13 | public class ListQueueCommand implements Action { 14 | private JmsService jmsService; 15 | 16 | public void setJmsService(JmsService jmsService) { 17 | this.jmsService = jmsService; 18 | } 19 | 20 | @Override 21 | public Object execute(CommandSession session) throws Exception { 22 | ShellTable table = new ShellTable(); 23 | table.header.add("Name"); 24 | table.header.add("Messages"); 25 | List queues = this.jmsService.listQueues(); 26 | for (String name : queues) { 27 | List row = table.addRow(); 28 | QueueInfo qi = jmsService.getQueueInfo(name); 29 | row.add(name); 30 | row.add("" + qi.getNumPendingMessages()); 31 | } 32 | table.print(); 33 | return null; 34 | } 35 | 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/command/SendCommand.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.command; 2 | 3 | import net.lr.karaf.jms.service.JmsService; 4 | 5 | import org.apache.felix.gogo.commands.Action; 6 | import org.apache.felix.gogo.commands.Argument; 7 | import org.apache.felix.gogo.commands.Command; 8 | import org.apache.felix.gogo.commands.Option; 9 | import org.apache.felix.service.command.CommandSession; 10 | 11 | @Command(scope = "jms", name = "send", description = "send a message to a queue") 12 | public class SendCommand implements Action { 13 | @Argument(index = 0, name = "queueName", required = true, description = "queue name", multiValued = false) 14 | String queueName; 15 | 16 | @Argument(index = 1, name = "body", required = true, description = "body", multiValued = false) 17 | String body; 18 | 19 | @Option(name = "-r", aliases="--replyTo", description = "Destination name to send the reply to") 20 | String replyTo; 21 | 22 | private JmsService jmsService; 23 | 24 | public void setJmsService(JmsService jmsService) { 25 | this.jmsService = jmsService; 26 | } 27 | 28 | @Override 29 | public Object execute(CommandSession session) throws Exception { 30 | this.jmsService.send(queueName, body, replyTo); 31 | return null; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/DummyExtJmsService.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.service; 2 | 3 | import java.util.List; 4 | 5 | public class DummyExtJmsService implements ExtJmsService { 6 | 7 | private RuntimeException getNotSupportedException() throws RuntimeException { 8 | return new RuntimeException("No extended jms service available for this jms provider so this method is not supported"); 9 | } 10 | 11 | @Override 12 | public void deleteQueue(String queueName) { 13 | getNotSupportedException(); 14 | } 15 | 16 | @Override 17 | public List listTopics() { 18 | throw getNotSupportedException(); 19 | } 20 | 21 | @Override 22 | public List listQueues() { 23 | throw getNotSupportedException(); 24 | } 25 | 26 | @Override 27 | public QueueInfo getQueueInfo(String queueName) { 28 | throw getNotSupportedException(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/ExtJmsService.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.service; 2 | 3 | import java.util.List; 4 | 5 | public interface ExtJmsService { 6 | void deleteQueue(final String queueName); 7 | 8 | List listTopics(); 9 | 10 | List listQueues(); 11 | 12 | QueueInfo getQueueInfo(final String queueName); 13 | } 14 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/ExtJmsServiceFactory.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.service; 2 | 3 | import javax.jms.Connection; 4 | 5 | public interface ExtJmsServiceFactory { 6 | ExtJmsService create(final Connection connection); 7 | boolean canHandle(final Connection connection); 8 | } 9 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/ExtJmsServiceOsgiFactory.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.service; 2 | 3 | import javax.jms.Connection; 4 | 5 | import org.osgi.framework.BundleContext; 6 | import org.osgi.framework.InvalidSyntaxException; 7 | import org.osgi.framework.ServiceReference; 8 | 9 | public class ExtJmsServiceOsgiFactory implements ExtJmsServiceFactory { 10 | 11 | BundleContext bundleContext; 12 | 13 | @Override 14 | public ExtJmsService create(Connection connection) { 15 | ServiceReference[] refs; 16 | try { 17 | refs = bundleContext.getServiceReferences(ExtJmsServiceFactory.class.getName(), null); 18 | } catch (InvalidSyntaxException e) { 19 | throw new RuntimeException(e.getMessage(), e); 20 | } 21 | for (ServiceReference ref : refs) { 22 | ExtJmsServiceFactory factory = (ExtJmsServiceFactory)bundleContext.getService(ref); 23 | if (factory.canHandle(connection)) { 24 | return factory.create(connection); 25 | } 26 | } 27 | return new DummyExtJmsService(); 28 | } 29 | 30 | @Override 31 | public boolean canHandle(Connection connection) { 32 | return true; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/JmsInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.karaf.jms.service; 18 | 19 | public class JmsInfo { 20 | public boolean selected; 21 | public String name; 22 | public String product; 23 | public String version; 24 | public String url; 25 | } 26 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/JmsMessageIterator.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.service; 2 | 3 | import java.util.Enumeration; 4 | 5 | import javax.jms.JMSException; 6 | import javax.jms.Message; 7 | import javax.jms.Session; 8 | 9 | public class JmsMessageIterator implements Enumeration { 10 | Session session; 11 | private Enumeration messageEnum; 12 | 13 | public JmsMessageIterator(Session session, Enumeration messageEnum) { 14 | this.session = session; 15 | this.messageEnum = messageEnum; 16 | } 17 | 18 | @Override 19 | public boolean hasMoreElements() { 20 | boolean more = this.messageEnum.hasMoreElements(); 21 | if (!more) { 22 | try { 23 | session.close(); 24 | } catch (JMSException e) { 25 | // Ignore 26 | } 27 | } 28 | return more; 29 | } 30 | 31 | @Override 32 | public JmsMessage nextElement() { 33 | Message message = this.messageEnum.nextElement(); 34 | return new JmsMessage(message); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/QueueInfo.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.service; 2 | 3 | public class QueueInfo { 4 | private String name; 5 | private int numPendingMessages; 6 | private int numConsumers; 7 | 8 | public String getName() { 9 | return name; 10 | } 11 | public void setName(String name) { 12 | this.name = name; 13 | } 14 | public int getNumPendingMessages() { 15 | return numPendingMessages; 16 | } 17 | public void setNumPendingMessages(int numPendingMessages) { 18 | this.numPendingMessages = numPendingMessages; 19 | } 20 | public int getNumConsumers() { 21 | return numConsumers; 22 | } 23 | public void setNumConsumers(int numConsumers) { 24 | this.numConsumers = numConsumers; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/service/activemq/ActiveMQJmsServiceFactory.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.service.activemq; 2 | 3 | import javax.jms.Connection; 4 | 5 | import org.apache.activemq.ActiveMQConnection; 6 | import org.apache.activemq.pool.PooledConnection; 7 | 8 | import net.lr.karaf.jms.service.ExtJmsService; 9 | import net.lr.karaf.jms.service.ExtJmsServiceFactory; 10 | 11 | public class ActiveMQJmsServiceFactory implements ExtJmsServiceFactory { 12 | 13 | @Override 14 | public ExtJmsService create(final Connection connection) { 15 | return new ActiveMQJmsService(connection); 16 | } 17 | 18 | @Override 19 | public boolean canHandle(Connection connection) { 20 | return (connection instanceof PooledConnection) || (connection instanceof ActiveMQConnection); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/template/SessionExecutor.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.template; 2 | 3 | import javax.jms.JMSException; 4 | import javax.jms.Session; 5 | 6 | public interface SessionExecutor { 7 | T execute(Session session) throws JMSException; 8 | } 9 | -------------------------------------------------------------------------------- /jms/command/src/main/java/net/lr/karaf/jms/template/VoidSessionExecutor.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.jms.template; 2 | 3 | import javax.jms.JMSException; 4 | import javax.jms.Session; 5 | 6 | public interface VoidSessionExecutor { 7 | void execute(Session session) throws JMSException; 8 | } 9 | -------------------------------------------------------------------------------- /jms/command/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /liquibase/README.md: -------------------------------------------------------------------------------- 1 | # Karaf Tutorial 11 - Managing database schemas with liquibase 2 | 3 | One typical pain point in deployments is the database schema and contents. The database schema changes over time and can not be deployed like bundles. Sometimes even the database contents have to be adapted when the schema changes. In a mordern deployment pipeline we of course also want to automate this part of the deployment. 4 | 5 | This tutorial builds upon the db tutorial. We assume familiarity with how to create DataSources using pax-jdbc-config and declarative services. 6 | 7 | # Structure 8 | 9 | * migrator - Migration logic for the database schema based on liquibase and ops4j PreHook 10 | * service - Repository and gogo command accessing the db using simple jdbc4 11 | 12 | # Build 13 | 14 | Make sure to use JDK 8. 15 | 16 | mvn clean install 17 | 18 | # Installation 19 | 20 | Make sure you use JDK 8. 21 | Download and extract Karaf 4.1.1. 22 | 23 | Start karaf and execute the commands below 24 | 25 | ```Shell 26 | cat https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/master/liquibase/org.ops4j.datasource-person.cfg | tac etc/org.ops4j.datasource-person.cfg 27 | feature:repo-add mvn:net.lr.tutorial.lb/lb/1.0.0-SNAPSHOT/xml/features 28 | feature:install example-lb 29 | ``` 30 | 31 | # Test 32 | 33 | In gogo shell 34 | 35 | ```Shell 36 | person:list 37 | ``` 38 | -------------------------------------------------------------------------------- /liquibase/features/src/main/resources/features.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | mvn:org.ops4j.pax.jdbc/pax-jdbc-features/1.1.0/xml/features 4 | 5 | 6 | scr 7 | pax-jdbc-h2 8 | pax-jdbc-config 9 | mvn:org.yaml/snakeyaml/1.17 10 | mvn:org.liquibase/liquibase-core/3.5.3 11 | mvn:${groupId}/net.lr.tutorial.lb.service/${pom.version} 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /liquibase/org.ops4j.datasource-person.cfg: -------------------------------------------------------------------------------- 1 | osgi.jdbc.driver.name=H2 2 | url=jdbc:h2:data/person;create=true 3 | dataSourceName=person 4 | ops4j.preHook=persondb 5 | -------------------------------------------------------------------------------- /liquibase/service/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | net.lr.tutorial.lb 6 | lb-parent 7 | 1.0.0-SNAPSHOT 8 | 9 | net.lr.tutorial.lb.service 10 | 11 | 12 | 13 | com.h2database 14 | h2 15 | 16 | 17 | org.liquibase 18 | liquibase-core 19 | 3.5.3 20 | 21 | 22 | org.ops4j.pax.jdbc 23 | pax-jdbc-pool-common 24 | 1.1.0 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /liquibase/service/src/main/java/net/lr/tutorial/db/service/Person.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db.service; 2 | 3 | /** 4 | * Very simple model class. This already contains the age property 5 | * to make the tutorial steps simpler. 6 | */ 7 | public class Person { 8 | 9 | public long id; 10 | public String name; 11 | public int age; 12 | 13 | @Override 14 | public String toString() { 15 | return id + ":" + name + ":" + age; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquibase/service/src/main/java/net/lr/tutorial/db/service/PersonCommand.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db.service; 2 | 3 | import org.osgi.service.component.annotations.Component; 4 | import org.osgi.service.component.annotations.Reference; 5 | 6 | /** 7 | * Felix gogo shell command that lists all persons using the injected PersonRepo 8 | * and print their properties to the console. 9 | */ 10 | @Component(service=PersonCommand.class, 11 | property={"osgi.command.scope=person", 12 | "osgi.command.function=list"}) 13 | public class PersonCommand { 14 | 15 | @Reference 16 | PersonRepo persons; 17 | 18 | public void list() { 19 | System.out.println("Persons"); 20 | persons.list().stream().map(Person::toString).forEach(System.out::println); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /liquibase/service/src/main/java/net/lr/tutorial/db/service/PersonRepo.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db.service; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import javax.sql.DataSource; 10 | 11 | import org.osgi.service.component.annotations.Component; 12 | import org.osgi.service.component.annotations.Reference; 13 | 14 | /** 15 | * Read data from person table in the db. The commented out parts have 16 | * to be enabled to implement the new property age 17 | */ 18 | @Component(service = PersonRepo.class) 19 | public class PersonRepo { 20 | private static final String QUERY = "select id, name from person"; 21 | //private static final String QUERY = "select id, name, age from person"; 22 | 23 | @Reference 24 | DataSource ds; 25 | 26 | public List list() { 27 | try (Connection con = ds.getConnection()) { 28 | ArrayList persons = new ArrayList(); 29 | ResultSet rs = con.createStatement().executeQuery(QUERY); 30 | while (rs.next()) { 31 | persons.add(read(rs)); 32 | } 33 | return persons; 34 | } catch (SQLException e) { 35 | throw new RuntimeException(e.getMessage(), e); 36 | } 37 | } 38 | 39 | private Person read(ResultSet rs) throws SQLException { 40 | Person person = new Person(); 41 | person.id = rs.getInt("id"); 42 | person.name = rs.getString("name"); 43 | //person.age = rs.getInt("age"); 44 | return person; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /liquibase/service/src/main/resources/db/changesets.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 1 18 | Chris 19 | 20 | 21 | 22 | 29 | 30 | -------------------------------------------------------------------------------- /liquibase/service/src/test/java/net/lr/tutorial/db/service/PersonRepoTest.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.db.service; 2 | 3 | import java.sql.SQLException; 4 | import java.util.List; 5 | 6 | import org.h2.jdbcx.JdbcDataSource; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | 11 | public class PersonRepoTest { 12 | 13 | @Test 14 | public void testList() throws SQLException { 15 | JdbcDataSource ds = new JdbcDataSource(); 16 | ds.setUrl("jdbc:h2:mem:person;DB_CLOSE_DELAY=-1"); 17 | new Migrator().prepare(ds); 18 | PersonRepo personRepo = new PersonRepo(); 19 | personRepo.ds = ds; 20 | List persons = personRepo.list(); 21 | Person person = persons.iterator().next(); 22 | Assert.assertEquals(1, person.id); 23 | Assert.assertEquals("Chris", person.name); 24 | //Assert.assertEquals(42, person.age); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /osgitemplate/readme.txt: -------------------------------------------------------------------------------- 1 | OSGi Template 2 | ========================================== 3 | 4 | Template for a maven based OSGi project. Simply copy this directory as a starting point for your own bundle 5 | -------------------------------------------------------------------------------- /osgitemplate/src/main/java/net/lr/tut/karaf/command/SimpleServlet.java: -------------------------------------------------------------------------------- 1 | package net.lr.tut.karaf.command; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.ServletException; 6 | import javax.servlet.http.HttpServlet; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.slf4j.Marker; 13 | 14 | public class SimpleServlet extends HttpServlet { 15 | 16 | /** 17 | * 18 | */ 19 | private static final long serialVersionUID = 34992072289535683L; 20 | 21 | @Override 22 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) 23 | throws ServletException, IOException { 24 | resp.getWriter().println("Servlet is here"); 25 | Logger log = LoggerFactory.getLogger(SimpleServlet.class); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /osgitemplate/src/main/resources/OSGI-INF/blueprint/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | javax.servlet.http.HttpServlet 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | net.lr.tutorial.karaf 7 | karaf-tutorial 8 | 1.0.0-SNAPSHOT 9 | pom 10 | 11 | 12 | tasklist 13 | configadmin 14 | cxf 15 | camel 16 | vaadin 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/angular-ui/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /bin/ 3 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/angular-ui/osgi.bnd: -------------------------------------------------------------------------------- 1 | Web-ContextPath: /tasklist 2 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/angular-ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | net.lr.tasklist.blueprint.cdi 7 | 1.0.0-SNAPSHOT 8 | parent 9 | 10 | 11 | angular-ui 12 | bundle 13 | 14 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/angular-ui/src/main/resources/app.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var app = angular.module('myApp', []); 3 | var tasksBase = "/cxf/tasks"; 4 | app.factory("Post", function($resource) { 5 | return $resource(tasksBase); 6 | }); 7 | app.controller('TaskController', function($scope, $http) { 8 | $scope.task = {}; 9 | $scope.reload = function() { 10 | $http.get(tasksBase) 11 | .success(function (response) {$scope.tasks = response.task;}); 12 | }; 13 | 14 | $scope.put = function() { 15 | var toSend = {task: $scope.task}; 16 | $http.put(tasksBase + "/" + $scope.task.id, toSend) 17 | .success(function (response) {$scope.reload();}); 18 | 19 | this.task = {}; 20 | }; 21 | 22 | $scope.delete = function(id) { 23 | $http.delete(tasksBase + "/"+ id) 24 | .success(function (response) {$scope.reload();}); 25 | $scope.task = {}; 26 | } 27 | 28 | $scope.select = function(id) { 29 | $scope.task = $scope.tasks[id]; 30 | } 31 | 32 | $scope.newTask = function(id) { 33 | $scope.task = {}; 34 | } 35 | $scope.reload(); 36 | }); 37 | })(); 38 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/model/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/model/osgi.bnd: -------------------------------------------------------------------------------- 1 | Meta-Persistence: \ 2 | META-INF/persistence.xml 3 | Import-Package: \ 4 | org.hibernate.proxy, \ 5 | javassist.util.proxy, \ 6 | * 7 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | net.lr.tasklist.blueprint.cdi 8 | 1.0.0-SNAPSHOT 9 | .. 10 | parent 11 | 12 | 13 | model 14 | bundle 15 | 16 | 17 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/model/src/main/java/net/lr/tasklist/model/Task.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.model; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | 9 | @Entity 10 | @XmlRootElement 11 | public class Task { 12 | @Id 13 | Integer id; 14 | String title; 15 | String description; 16 | Date dueDate; 17 | boolean finished; 18 | 19 | 20 | public Task() { 21 | } 22 | 23 | 24 | public Task(Integer id, String title, String description) { 25 | super(); 26 | this.id = id; 27 | this.title = title; 28 | this.description = description; 29 | } 30 | 31 | public Integer getId() { 32 | return id; 33 | } 34 | 35 | public void setId(Integer id) { 36 | this.id = new Integer(id); 37 | } 38 | 39 | public String getTitle() { 40 | return title; 41 | } 42 | 43 | public void setTitle(String title) { 44 | this.title = title; 45 | } 46 | 47 | public String getDescription() { 48 | return description; 49 | } 50 | 51 | public void setDescription(String description) { 52 | this.description = description; 53 | } 54 | 55 | public Date getDueDate() { 56 | return dueDate; 57 | } 58 | 59 | public void setDueDate(Date dueDate) { 60 | this.dueDate = dueDate; 61 | } 62 | 63 | public boolean isFinished() { 64 | return finished; 65 | } 66 | 67 | public void setFinished(boolean finished) { 68 | this.finished = finished; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/model/src/main/java/net/lr/tasklist/model/TaskService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.model; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.jws.WebService; 6 | 7 | @WebService 8 | public interface TaskService { 9 | Task getTask(Integer id); 10 | void addTask(Task task); 11 | void updateTask(Task task); 12 | void deleteTask(Integer id); 13 | Collection getTasks(); 14 | } 15 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/model/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | 9 | 10 | osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=tasklist) 11 | 12 | 13 | osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=tasklist) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/org.ops4j.datasource-tasklist.cfg: -------------------------------------------------------------------------------- 1 | osgi.jdbc.driver.name=H2-pool-xa 2 | url=jdbc:h2:mem:test 3 | dataSourceName=tasklist 4 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/persistence/osgi.bnd: -------------------------------------------------------------------------------- 1 | Import-Package: \ 2 | org.hibernate.proxy, \ 3 | javassist.util.proxy, \ 4 | * 5 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/persistence/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 4.0.0 8 | 9 | 10 | net.lr.tasklist.blueprint.cdi 11 | 1.0.0-SNAPSHOT 12 | .. 13 | parent 14 | 15 | 16 | persistence 17 | bundle 18 | 19 | 20 | 21 | net.lr.tasklist.blueprint.cdi 22 | model 23 | ${project.version} 24 | 25 | 26 | 27 | 28 | org.hibernate 29 | hibernate-entitymanager 30 | 4.3.5.Final 31 | test 32 | 33 | 34 | com.h2database 35 | h2 36 | 1.3.174 37 | test 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/persistence/src/main/java/net/lr/tasklist/persistence/impl/InitHelper.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import java.util.concurrent.Executors; 4 | 5 | import javax.annotation.PostConstruct; 6 | import javax.inject.Inject; 7 | import javax.inject.Named; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import net.lr.tasklist.model.Task; 13 | import net.lr.tasklist.model.TaskService; 14 | 15 | @Named 16 | public class InitHelper { 17 | Logger LOG = LoggerFactory.getLogger(InitHelper.class); 18 | @Inject 19 | TaskService taskService; 20 | 21 | @PostConstruct 22 | public void addDemoTasks() { 23 | Executors.newSingleThreadExecutor().execute(new Runnable() { 24 | @Override 25 | public void run() { 26 | try { 27 | if (taskService.getTask(1) == null) { 28 | addSampleTask(); 29 | } 30 | } catch (Exception e) { 31 | LOG.warn(e.getMessage(), e); 32 | } 33 | } 34 | }); 35 | 36 | } 37 | 38 | private void addSampleTask() { 39 | Task task = new Task(1, "Just a sample task", "Some more info"); 40 | taskService.addTask(task); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/persistence/src/main/java/net/lr/tasklist/persistence/impl/TaskServiceImpl.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.inject.Named; 6 | import javax.persistence.EntityManager; 7 | import javax.persistence.PersistenceContext; 8 | import javax.persistence.criteria.CriteriaQuery; 9 | import javax.transaction.Transactional; 10 | 11 | import org.ops4j.pax.cdi.api.OsgiServiceProvider; 12 | import org.ops4j.pax.cdi.api.Properties; 13 | import org.ops4j.pax.cdi.api.Property; 14 | 15 | import net.lr.tasklist.model.Task; 16 | import net.lr.tasklist.model.TaskService; 17 | 18 | @OsgiServiceProvider(classes = {TaskService.class}) 19 | // The properties below allow to transparently export the service as a web service using Distributed OSGi 20 | @Properties({ 21 | @Property(name = "service.exported.interfaces", value = "*") 22 | }) 23 | @Named 24 | @Transactional 25 | public class TaskServiceImpl implements TaskService { 26 | 27 | @PersistenceContext(unitName="tasklist") 28 | EntityManager em; 29 | 30 | @Override 31 | @Transactional(Transactional.TxType.SUPPORTS) 32 | public Task getTask(Integer id) { 33 | return em.find(Task.class, id); 34 | } 35 | 36 | @Override 37 | public void addTask(Task task) { 38 | em.persist(task); 39 | em.flush(); 40 | } 41 | 42 | @Transactional(Transactional.TxType.SUPPORTS) 43 | public Collection getTasks() { 44 | CriteriaQuery query = em.getCriteriaBuilder().createQuery(Task.class); 45 | return em.createQuery(query.select(query.from(Task.class))).getResultList(); 46 | } 47 | 48 | @Override 49 | public void updateTask(Task task) { 50 | em.merge(task); 51 | } 52 | 53 | @Override 54 | public void deleteTask(Integer id) { 55 | em.remove(getTask(id)); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/persistence/src/test/java/net/lr/tasklist/persistence/impl/TaskServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.persistence.EntityManager; 6 | import javax.persistence.EntityManagerFactory; 7 | import javax.persistence.Persistence; 8 | 9 | import net.lr.tasklist.model.Task; 10 | 11 | import org.junit.Assert; 12 | import org.junit.Test; 13 | 14 | public class TaskServiceImplTest { 15 | 16 | @Test 17 | public void testWriteRead() throws Exception { 18 | TaskServiceImpl taskService = new TaskServiceImpl(); 19 | EntityManagerFactory emf = Persistence.createEntityManagerFactory("tasklist", System.getProperties()); 20 | EntityManager em = emf.createEntityManager(); 21 | taskService.em = em; 22 | 23 | em.getTransaction().begin(); 24 | Task task = new Task(); 25 | task.setId(1); 26 | task.setTitle("Test task"); 27 | taskService.addTask(task); 28 | em.getTransaction().commit(); 29 | Collection persons = taskService.getTasks(); 30 | 31 | Assert.assertEquals(1, persons.size()); 32 | Task task1 = persons.iterator().next(); 33 | Assert.assertEquals(new Integer(1), task1.getId()); 34 | Assert.assertEquals("Test task", task1.getTitle()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/persistence/src/test/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | 25 | org.hibernate.jpa.HibernatePersistenceProvider 26 | net.lr.tasklist.model.Task 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/persistence/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/tasklist-service/osgi.bnd: -------------------------------------------------------------------------------- 1 | -dsannotations: * 2 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/tasklist-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 4.0.0 8 | 9 | net.lr.tasklist.blueprint.cdi 10 | 1.0.0-SNAPSHOT 11 | .. 12 | parent 13 | 14 | service 15 | bundle 16 | 17 | 18 | 19 | net.lr.tasklist.blueprint.cdi 20 | model 21 | ${project.version} 22 | 23 | 24 | javax.enterprise 25 | cdi-api 26 | 1.2 27 | true 28 | 29 | 30 | 31 | org.apache.cxf 32 | cxf-rt-frontend-jaxrs 33 | ${cxf.version} 34 | 35 | 36 | org.apache.cxf 37 | cxf-rt-features-logging 38 | ${cxf.version} 39 | 40 | 41 | org.apache.cxf 42 | cxf-rt-management 43 | ${cxf.version} 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/tasklist-service/src/main/resources/OSGI-INF/blueprint/rest.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/ui/osgi.bnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/tasklist-blueprint-cdi/ui/osgi.bnd -------------------------------------------------------------------------------- /tasklist-blueprint-cdi/ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 4.0.0 8 | 9 | 10 | net.lr.tasklist.blueprint.cdi 11 | 1.0.0-SNAPSHOT 12 | .. 13 | parent 14 | 15 | 16 | ui 17 | bundle 18 | 19 | 20 | 21 | net.lr.tasklist.blueprint.cdi 22 | model 23 | 1.0.0-SNAPSHOT 24 | 25 | 26 | javax.servlet 27 | servlet-api 28 | 2.5 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tasklist-ds/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /generated/ 3 | /.gradle/ 4 | /reports/ 5 | -------------------------------------------------------------------------------- /tasklist-ds/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Example for the "Karaf Tutorial 10 - Declarative services and JPA" 4 | 5 | In this tutorial we reimplement the TaskService example using declarative services (DS). 6 | Aries JPA 2 is used to bring jpa support to DS. The eclipsesource jax-rs-connector is used to 7 | export an annotated class as REST service. 8 | 9 | The tutorial skips details about DataSource creation and the model bundle as they are exactly the 10 | same as in the blueprint example. 11 | 12 | # Structure 13 | 14 | * model - Service interface and model classes shared between persistence and ui 15 | * persistence - Full persistence implementation using JPA and hibernate 16 | * ui -Servlet based UI. Uses TaskService and publishes a servlet 17 | 18 | # Build 19 | 20 | Make sure to use JDK 8. 21 | 22 | mvn clean install 23 | 24 | # Installation 25 | 26 | Make sure you use JDK 8. 27 | Download and extract Karaf 4.0.3. 28 | 29 | Start karaf and execute the commands below 30 | 31 | ```Shell 32 | cat https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/master/tasklist-ds/org.ops4j.datasource-tasklist.cfg | tac -f etc/org.ops4j.datasource-tasklist.cfg 33 | feature:repo-add mvn:net.lr.tasklist.ds/tasklist/1.0.0-SNAPSHOT/xml/features 34 | feature:install example-tasklist-ds 35 | ``` 36 | 37 | # Test 38 | 39 | Open the url below in your browser to view all known tasks: 40 | 41 | 42 | View the tasks as a rest resource 43 | 44 | 45 | Create Task2 using the rest service 46 | 47 | curl -i -X POST -H "Content-Type: application/json" -d '{task:{"id":2,"title":"Task2"}}' http://localhost:8181/cxf/tasklistRest 48 | 49 | Retrieve Task2 50 | 51 | curl -i http://localhost:8181/cxf/tasklistRest/2 52 | 53 | # Import the source in eclipse 54 | 55 | Import ... -> Existing maven projects -> Browse to tasklist-ds folder -> Select all projects -> Finish 56 | 57 | Switch Advanced -> Name template to _[groupId].[artifactId]_. This will make sure we can also import other examples. 58 | -------------------------------------------------------------------------------- /tasklist-ds/app/src/main/resources/etc/org.ops4j.datasource-tasklist.cfg: -------------------------------------------------------------------------------- 1 | osgi.jdbc.driver.name=H2-pool-xa 2 | url=jdbc:h2:mem:test 3 | dataSourceName=tasklist 4 | -------------------------------------------------------------------------------- /tasklist-ds/model/bnd.bnd: -------------------------------------------------------------------------------- 1 | Meta-Persistence: \ 2 | META-INF/persistence.xml 3 | Import-Package: \ 4 | org.hibernate.proxy, \ 5 | javassist.util.proxy, \ 6 | * 7 | Provide-Capability: osgi.service; objectClass=org.apache.aries.jpa.template.JpaTemplate 8 | -------------------------------------------------------------------------------- /tasklist-ds/model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | net.lr.tasklist.ds 8 | 1.0.0-SNAPSHOT 9 | .. 10 | parent 11 | 12 | 13 | bundle 14 | net.lr.tasklist.ds.model 15 | 16 | 17 | 18 | org.hibernate.javax.persistence 19 | hibernate-jpa-2.1-api 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tasklist-ds/model/src/main/java/net/lr/tasklist/model/Task.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.model; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | 9 | @Entity 10 | @XmlRootElement 11 | public class Task { 12 | @Id 13 | Integer id; 14 | String title; 15 | String description; 16 | Date dueDate; 17 | boolean finished; 18 | 19 | 20 | public Task() { 21 | } 22 | 23 | 24 | public Task(Integer id, String title, String description) { 25 | super(); 26 | this.id = id; 27 | this.title = title; 28 | this.description = description; 29 | } 30 | 31 | public Integer getId() { 32 | return id; 33 | } 34 | 35 | public void setId(Integer id) { 36 | this.id = new Integer(id); 37 | } 38 | 39 | public String getTitle() { 40 | return title; 41 | } 42 | 43 | public void setTitle(String title) { 44 | this.title = title; 45 | } 46 | 47 | public String getDescription() { 48 | return description; 49 | } 50 | 51 | public void setDescription(String description) { 52 | this.description = description; 53 | } 54 | 55 | public Date getDueDate() { 56 | return dueDate; 57 | } 58 | 59 | public void setDueDate(Date dueDate) { 60 | this.dueDate = dueDate; 61 | } 62 | 63 | public boolean isFinished() { 64 | return finished; 65 | } 66 | 67 | public void setFinished(boolean finished) { 68 | this.finished = finished; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /tasklist-ds/model/src/main/java/net/lr/tasklist/model/TaskService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.model; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.jws.WebService; 6 | 7 | @WebService 8 | public interface TaskService { 9 | Task getTask(Integer id); 10 | 11 | void addTask(Task task); 12 | 13 | void updateTask(Task task); 14 | 15 | void deleteTask(Integer id); 16 | 17 | Collection getTasks(); 18 | } 19 | -------------------------------------------------------------------------------- /tasklist-ds/model/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=tasklist) 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tasklist-ds/org.ops4j.datasource-tasklist.cfg: -------------------------------------------------------------------------------- 1 | osgi.jdbc.driver.name=H2-pool-xa 2 | url=jdbc:h2:mem:test 3 | dataSourceName=tasklist 4 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/bnd.bnd: -------------------------------------------------------------------------------- 1 | -dsannotations: * 2 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 4.0.0 8 | 9 | 10 | net.lr.tasklist.ds 11 | 1.0.0-SNAPSHOT 12 | parent 13 | .. 14 | 15 | 16 | net.lr.tasklist.ds.persistence 17 | bundle 18 | 19 | 20 | 21 | net.lr.tasklist.ds 22 | net.lr.tasklist.ds.model 23 | ${project.version} 24 | 25 | 26 | org.hibernate.javax.persistence 27 | hibernate-jpa-2.1-api 28 | 29 | 30 | org.apache.aries.jpa 31 | org.apache.aries.jpa.api 32 | 33 | 34 | 35 | 36 | org.hibernate 37 | hibernate-entitymanager 38 | 4.3.5.Final 39 | test 40 | 41 | 42 | com.h2database 43 | h2 44 | 1.3.174 45 | test 46 | 47 | 48 | org.apache.aries.jpa 49 | org.apache.aries.jpa.support 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/src/main/java/net/lr/tasklist/persistence/impl/InitHelper.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import net.lr.tasklist.model.Task; 4 | import net.lr.tasklist.model.TaskService; 5 | 6 | import org.osgi.service.component.annotations.Activate; 7 | import org.osgi.service.component.annotations.Component; 8 | import org.osgi.service.component.annotations.Reference; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | @Component 13 | public class InitHelper { 14 | Logger LOG = LoggerFactory.getLogger(InitHelper.class); 15 | 16 | @Reference 17 | TaskService taskService; 18 | 19 | @Activate 20 | public void addDemoTasks() { 21 | try { 22 | Task task = new Task(1, "Just a sample task", "Some more info"); 23 | taskService.addTask(task); 24 | } catch (Exception e) { 25 | LOG.warn(e.getMessage(), e); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/src/main/java/net/lr/tasklist/persistence/impl/TaskServiceImpl.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.persistence.criteria.CriteriaQuery; 6 | 7 | import net.lr.tasklist.model.Task; 8 | import net.lr.tasklist.model.TaskService; 9 | 10 | import org.apache.aries.jpa.template.JpaTemplate; 11 | import org.osgi.service.component.annotations.Component; 12 | import org.osgi.service.component.annotations.Reference; 13 | 14 | @Component 15 | public class TaskServiceImpl implements TaskService { 16 | 17 | @Reference(target = "(osgi.unit.name=tasklist)") 18 | JpaTemplate jpa; 19 | 20 | @Override 21 | public Task getTask(Integer id) { 22 | return jpa.txExpr(em -> em.find(Task.class, id)); 23 | } 24 | 25 | @Override 26 | public void addTask(Task task) { 27 | if (task.getId() == null) { 28 | throw new IllegalArgumentException("Id property must be set"); 29 | } 30 | System.err.println("Adding task " + task.getId()); 31 | jpa.tx(em -> { 32 | em.persist(task); 33 | em.flush(); 34 | }); 35 | } 36 | 37 | @Override 38 | public Collection getTasks() { 39 | return jpa.txExpr(em -> { 40 | CriteriaQuery query = em.getCriteriaBuilder().createQuery(Task.class); 41 | return em.createQuery(query.select(query.from(Task.class))).getResultList(); 42 | }); 43 | } 44 | 45 | @Override 46 | public void updateTask(Task task) { 47 | jpa.tx(em -> em.merge(task)); 48 | } 49 | 50 | @Override 51 | public void deleteTask(Integer id) { 52 | jpa.tx(em -> em.remove(getTask(id))); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/src/test/java/net/lr/tasklist/persistence/impl/SimpleJpaTemplate.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import javax.persistence.EntityManager; 4 | 5 | import org.apache.aries.jpa.support.impl.AbstractJpaTemplate; 6 | import org.apache.aries.jpa.template.EmFunction; 7 | import org.apache.aries.jpa.template.TransactionType; 8 | 9 | /** 10 | * Simple JPA Template without any transaction support 11 | */ 12 | public class SimpleJpaTemplate extends AbstractJpaTemplate { 13 | 14 | private EntityManager em; 15 | 16 | public SimpleJpaTemplate(EntityManager em) { 17 | this.em = em; 18 | } 19 | 20 | @Override 21 | public R txExpr(TransactionType type, EmFunction code) { 22 | return code.apply(em); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/src/test/java/net/lr/tasklist/persistence/impl/TaskServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import java.util.Collection; 4 | 5 | import javax.persistence.EntityManager; 6 | import javax.persistence.EntityManagerFactory; 7 | import javax.persistence.Persistence; 8 | 9 | import org.apache.aries.jpa.template.JpaTemplate; 10 | import org.junit.Assert; 11 | import org.junit.Test; 12 | 13 | import net.lr.tasklist.model.Task; 14 | 15 | public class TaskServiceImplTest { 16 | 17 | @Test 18 | public void testWriteRead() throws Exception { 19 | EntityManagerFactory emf = Persistence.createEntityManagerFactory("tasklist", System.getProperties()); 20 | EntityManager em = emf.createEntityManager(); 21 | JpaTemplate jpaTemplate = new SimpleJpaTemplate(em); 22 | TaskServiceImpl taskService = new TaskServiceImpl(); 23 | taskService.jpa = jpaTemplate; 24 | 25 | Task task = new Task(); 26 | task.setId(1); 27 | task.setTitle("Test task"); 28 | 29 | em.getTransaction().begin(); 30 | taskService.addTask(task); 31 | em.getTransaction().commit(); 32 | Collection persons = taskService.getTasks(); 33 | 34 | Assert.assertEquals(1, persons.size()); 35 | Task task1 = persons.iterator().next(); 36 | Assert.assertEquals(new Integer(1), task1.getId()); 37 | Assert.assertEquals("Test task", task1.getTitle()); 38 | em.close(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/src/test/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | 25 | org.hibernate.jpa.HibernatePersistenceProvider 26 | net.lr.tasklist.model.Task 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tasklist-ds/persistence/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tasklist-ds/service/bnd.bnd: -------------------------------------------------------------------------------- 1 | -dsannotations: * 2 | -------------------------------------------------------------------------------- /tasklist-ds/service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | net.lr.tasklist.ds 8 | parent 9 | 1.0.0-SNAPSHOT 10 | .. 11 | 12 | net.lr.tasklist.ds.service 13 | bundle 14 | 15 | 16 | 17 | net.lr.tasklist.ds 18 | net.lr.tasklist.ds.model 19 | ${project.version} 20 | 21 | 22 | javax.ws.rs 23 | javax.ws.rs-api 24 | 2.0.1 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tasklist-ds/ui/bnd.bnd: -------------------------------------------------------------------------------- 1 | -dsannotations: * 2 | -------------------------------------------------------------------------------- /tasklist-ds/ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 4.0.0 8 | 9 | 10 | net.lr.tasklist.ds 11 | 1.0.0-SNAPSHOT 12 | parent 13 | .. 14 | 15 | 16 | net.lr.tasklist.ds.ui 17 | bundle 18 | 19 | 20 | 21 | net.lr.tasklist.ds 22 | net.lr.tasklist.ds.model 23 | ${project.version} 24 | 25 | 26 | javax.servlet 27 | servlet-api 28 | 2.5 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tasklist-ds/ui/src/main/java/net/lr/tasklist/ui/TaskUIConfig.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.ui; 2 | 3 | import org.osgi.service.metatype.annotations.ObjectClassDefinition; 4 | 5 | @ObjectClassDefinition(name = "Tasklist UI") 6 | @interface TaskUIConfig { 7 | String title() default "Tasklist"; 8 | int numTasks() default 20; 9 | } 10 | -------------------------------------------------------------------------------- /tasklist/README.md: -------------------------------------------------------------------------------- 1 | # Karaf Tutorial part 1 - Tasklist example 2 | 3 | ## Overview 4 | 5 | Example for the Karaf Tutorial part 1 that implements a very small application to manage a list of tasks or todo items. 6 | 7 | It shows how to: 8 | * Create bundles using maven and the maven bundle plugin 9 | * Wire bundles using blueprint and OSGi services 10 | * Define blueprint beans using annotations 11 | * Define Felix gogo shell commands 12 | * Use the whiteboard pattern and the pax-web whiteboard extender to publish Servlets 13 | 14 | ## Structure 15 | 16 | | Module | Description | 17 | | -------------- | ----------------------------------------------------------------------------------- | 18 | | tasklist-model | Service interface and model classes shared between persistence and ui | 19 | | tasklist-persistence | Persistence implementation using an OSGi service and a in memory map | 20 | | tasklist-ui | Servlet based UI that connects to the persistence layer using an OSGi service | 21 | | tasklist-command | Felix gogo command to interact with tasks from the shell | 22 | 23 | ## Build 24 | 25 | mvn clean install 26 | 27 | ## Installation 28 | 29 | Download and start karaf >= 4.1. If you want to use karaf 4.0.x you need to switch the way the http servlet is published. See the comment in TaskListServlet. 30 | 31 | feature:repo-add mvn:net.lr.tasklist/tasklist-features/1.0.0-SNAPSHOT/xml 32 | feature:install example-tasklist 33 | 34 | # Test 35 | 36 | http:list 37 | 38 | This should show the servlet we expose. 39 | 40 | task:list 41 | 42 | Will list the tasks currently managed by the service 43 | 44 | Open the URL below in your browser [http://localhost:8181/tasklist](http://localhost:8181/tasklist). It should show the pre defined tasks. 45 | 46 | 47 | -------------------------------------------------------------------------------- /tasklist/tasklist-command/bnd.bnd: -------------------------------------------------------------------------------- 1 | Private-Package: \ 2 | net.lr.tasklist.command,\ 3 | org.apache.karaf.shell.table -------------------------------------------------------------------------------- /tasklist/tasklist-command/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | net.lr.tasklist 8 | tasklist 9 | 1.0.0-SNAPSHOT 10 | .. 11 | 12 | 13 | tasklist-command 14 | bundle 15 | 16 | 17 | 18 | net.lr.tasklist 19 | tasklist-model 20 | 1.0.0-SNAPSHOT 21 | 22 | 23 | org.apache.karaf.shell 24 | org.apache.karaf.shell.table 25 | 4.0.7 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tasklist/tasklist-command/src/main/java/net/lr/tasklist/command/TaskCommands.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.command; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Singleton; 5 | 6 | import org.apache.aries.blueprint.annotation.service.Reference; 7 | import org.apache.aries.blueprint.annotation.service.Service; 8 | import org.apache.aries.blueprint.annotation.service.ServiceProperty; 9 | import org.apache.karaf.shell.table.ShellTable; 10 | 11 | import net.lr.tasklist.model.Task; 12 | import net.lr.tasklist.model.TaskService; 13 | 14 | @Singleton 15 | @Service(classes=TaskCommands.class, 16 | properties= { 17 | @ServiceProperty(name = "osgi.command.scope", values = "task"), 18 | @ServiceProperty(name = "osgi.command.function", values = {"add", "list", "get"}) 19 | }) 20 | public class TaskCommands { 21 | 22 | @Inject @Reference 23 | TaskService taskService; 24 | 25 | public void add(String id, String title, String description) throws Exception { 26 | Task task = new Task(); 27 | task.setId(id); 28 | task.setTitle(title); 29 | task.setDescription(description); 30 | taskService.addTask(task); 31 | } 32 | 33 | public Task get(String id) throws Exception { 34 | return taskService.getTask(id); 35 | } 36 | 37 | public void list() throws Exception { 38 | ShellTable table = new ShellTable(); 39 | table.column("id"); 40 | table.column("title"); 41 | for (Task task : taskService.getTasks()) { 42 | table.addRow().addContent(task.getId(), task.getTitle()); 43 | } 44 | table.print(System.out); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tasklist/tasklist-features/src/main/resources/features.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | example-tasklist-persistence 11 | example-tasklist-ui 12 | 13 | 14 | 15 | aries-blueprint 16 | mvn:net.lr.tasklist/tasklist-model/${pom.version} 17 | mvn:net.lr.tasklist/tasklist-persistence/${pom.version} 18 | mvn:net.lr.tasklist/tasklist-command/${pom.version} 19 | 20 | 21 | 22 | aries-blueprint 23 | http 24 | http-whiteboard 25 | mvn:net.lr.tasklist/tasklist-model/${pom.version} 26 | mvn:net.lr.tasklist/tasklist-ui/${pom.version} 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tasklist/tasklist-model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | 8 | net.lr.tasklist 9 | tasklist 10 | 1.0.0-SNAPSHOT 11 | .. 12 | 13 | 14 | tasklist-model 15 | bundle 16 | 17 | 18 | -------------------------------------------------------------------------------- /tasklist/tasklist-model/src/main/java/net/lr/tasklist/model/Task.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | public class Task implements Serializable { 7 | /** 8 | * Only needed for ECF generic transport 9 | */ 10 | private static final long serialVersionUID = 5117254163782139591L; 11 | 12 | String id; 13 | String title; 14 | String description; 15 | Date dueDate; 16 | boolean finished; 17 | 18 | public String getId() { 19 | return id; 20 | } 21 | public void setId(String id) { 22 | this.id = id; 23 | } 24 | 25 | public String getTitle() { 26 | return title; 27 | } 28 | public void setTitle(String title) { 29 | this.title = title; 30 | } 31 | public String getDescription() { 32 | return description; 33 | } 34 | public void setDescription(String description) { 35 | this.description = description; 36 | } 37 | public Date getDueDate() { 38 | return dueDate; 39 | } 40 | public void setDueDate(Date dueDate) { 41 | this.dueDate = dueDate; 42 | } 43 | public boolean isFinished() { 44 | return finished; 45 | } 46 | public void setFinished(boolean finished) { 47 | this.finished = finished; 48 | } 49 | 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /tasklist/tasklist-model/src/main/java/net/lr/tasklist/model/TaskService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.model; 2 | 3 | import java.util.Collection; 4 | 5 | public interface TaskService { 6 | Task getTask(String id); 7 | void addTask(Task task); 8 | void updateTask(Task task); 9 | void deleteTask(String id); 10 | Collection getTasks(); 11 | } 12 | -------------------------------------------------------------------------------- /tasklist/tasklist-persistence/bnd.bnd: -------------------------------------------------------------------------------- 1 | #Provide-Capability: osgi.service;objectClass=net.lr.tasklist.model.TaskService 2 | -------------------------------------------------------------------------------- /tasklist/tasklist-persistence/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | net.lr.tasklist 8 | tasklist 9 | 1.0.0-SNAPSHOT 10 | .. 11 | 12 | 13 | tasklist-persistence 14 | bundle 15 | 16 | 17 | 18 | net.lr.tasklist 19 | tasklist-model 20 | 1.0.0-SNAPSHOT 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tasklist/tasklist-persistence/src/main/java/net/lr/tasklist/persistence/impl/TaskServiceImpl.java: -------------------------------------------------------------------------------- 1 | package net.lr.tasklist.persistence.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import javax.inject.Singleton; 9 | 10 | import org.apache.aries.blueprint.annotation.service.Service; 11 | import org.apache.aries.blueprint.annotation.service.ServiceProperty; 12 | 13 | import net.lr.tasklist.model.Task; 14 | import net.lr.tasklist.model.TaskService; 15 | 16 | @Service(classes=TaskService.class, 17 | properties= { 18 | // Only necessary for Remote Services 19 | @ServiceProperty(name = "service.exported.interfaces", values = "*") 20 | }) 21 | @Singleton 22 | public class TaskServiceImpl implements TaskService { 23 | Map taskMap; 24 | 25 | public TaskServiceImpl() { 26 | taskMap = new HashMap(); 27 | Task task = new Task(); 28 | task.setId("1"); 29 | task.setTitle("Buy some coffee"); 30 | task.setDescription("Take the extra strong"); 31 | addTask(task); 32 | task = new Task(); 33 | task.setId("2"); 34 | task.setTitle("Finish karaf tutorial"); 35 | task.setDescription("Last check and wiki upload"); 36 | addTask(task); 37 | } 38 | 39 | @Override 40 | public Task getTask(String id) { 41 | return taskMap.get(id); 42 | } 43 | 44 | @Override 45 | public void addTask(Task task) { 46 | taskMap.put(task.getId(), task); 47 | } 48 | 49 | @Override 50 | public Collection getTasks() { 51 | // taskMap.values is not serializable 52 | return new ArrayList(taskMap.values()); 53 | } 54 | 55 | @Override 56 | public void updateTask(Task task) { 57 | taskMap.put(task.getId(), task); 58 | } 59 | 60 | @Override 61 | public void deleteTask(String id) { 62 | taskMap.remove(id); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /tasklist/tasklist-ui/bnd.bnd: -------------------------------------------------------------------------------- 1 | Require-Capability:\ 2 | osgi.service;filter:="(objectClass=org.osgi.service.http.HttpService)";effective:=active 3 | # From karaf 4.1.0 we can switch to requiring the OSGi http impl 4 | # osgi.implementation;osgi.implementation="osgi.http" -------------------------------------------------------------------------------- /tasklist/tasklist-ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | net.lr.tasklist 8 | tasklist 9 | 1.0.0-SNAPSHOT 10 | .. 11 | 12 | 13 | tasklist-ui 14 | bundle 15 | 16 | 17 | 18 | net.lr.tasklist 19 | tasklist-model 20 | 1.0.0-SNAPSHOT 21 | 22 | 23 | javax.servlet 24 | servlet-api 25 | 2.5 26 | provided 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /vaadin/README.txt: -------------------------------------------------------------------------------- 1 | h1. Overview 2 | 3 | Example for the Karaf Tutorial Vaadin that implements Vaadin based UI on top of the tasklist example from the first tutorial. 4 | The Vaadin UI reuses the original Tasklist model and persistence service. Below we deploy it alongside the original Servlet UI. 5 | As both use the same persistence service the UIs keep in sync. 6 | 7 | h1. Build 8 | 9 | On top level of Karaf-Tutorial do: 10 | mvn clean install 11 | 12 | h1. Installation 13 | 14 | features:addurl mvn:net.lr.tutorial.karaf.vaadin/tasklist-vaadin-features/1.0.0-SNAPSHOT/xml 15 | features:install example-tasklist-vaadin 16 | 17 | h1. Test 18 | 19 | Old Servlet UI: 20 | http://localhost:8181/tasklist 21 | 22 | Vaadin UI: 23 | http://localhost:8181/tasklist-vaadin 24 | -------------------------------------------------------------------------------- /vaadin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | net.lr.tutorial.karaf.vaadin 7 | vaadin 8 | 1.0.0-SNAPSHOT 9 | pom 10 | 11 | 12 | vaadinbridge 13 | tasklist-ui-vaadin 14 | tasklist-vaadin-features 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /vaadin/tasklist-ui-vaadin/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | bin_test 3 | generated 4 | runtimefw 5 | -------------------------------------------------------------------------------- /vaadin/tasklist-ui-vaadin/src/main/java/net/lr/tutorial/karaf/vaadin/ExampleAppFactory.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vaadin; 2 | 3 | import net.lr.tasklist.model.TaskService; 4 | 5 | import org.example.utils.vaadinbridge.ApplicationFactory; 6 | 7 | import com.vaadin.Application; 8 | import com.vaadin.Application.SystemMessages; 9 | 10 | public class ExampleAppFactory implements ApplicationFactory { 11 | 12 | private final TaskService taskService; 13 | private final String title; 14 | 15 | public ExampleAppFactory(TaskService taskService, String title) { 16 | this.taskService = taskService; 17 | this.title = title; 18 | } 19 | 20 | public String getApplicationCSSClassName() { 21 | return "ExampleApplication"; 22 | } 23 | 24 | public SystemMessages getSystemMessages() { 25 | return null; 26 | } 27 | 28 | public Application newInstance() { 29 | return new ExampleApplication(taskService, title); 30 | } 31 | } -------------------------------------------------------------------------------- /vaadin/tasklist-ui-vaadin/src/main/resources/OSGI-INF/blueprint/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /vaadin/tasklist-vaadin-features/src/main/resources/features.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | mvn:net.lr.tasklist/tasklist-features/1.0.0-SNAPSHOT/xml 4 | 5 | example-tasklist 6 | mvn:com.vaadin/vaadin/6.7.1 7 | mvn:net.lr/vaadinbridge/${pom.version} 8 | mvn:net.lr.tutorial.karaf.vaadin/tasklist-ui-vaadin/${pom.version} 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /vaadin/vaadinbridge/README.txt: -------------------------------------------------------------------------------- 1 | Based on the vaadinbridge by Neil Bartlet. 2 | 3 | See https://github.com/njbartlett/VaadinOSGi 4 | 5 | -------------------------------------------------------------------------------- /vaadin/vaadinbridge/src/main/java/org/example/utils/vaadinbridge/ApplicationFactory.java: -------------------------------------------------------------------------------- 1 | package org.example.utils.vaadinbridge; 2 | 3 | import com.vaadin.Application; 4 | import com.vaadin.Application.SystemMessages; 5 | 6 | public interface ApplicationFactory { 7 | 8 | static final String ALIAS_NAME = "alias"; 9 | 10 | Application newInstance(); 11 | 12 | String getApplicationCSSClassName(); 13 | 14 | /** 15 | * Return system messages for the Application type, or {@code null} if there 16 | * are no Application-specific system messages. 17 | */ 18 | SystemMessages getSystemMessages(); 19 | 20 | } -------------------------------------------------------------------------------- /vaadin/vaadinbridge/src/main/java/org/example/utils/vaadinbridge/internal/ApplicationFactoryServlet.java: -------------------------------------------------------------------------------- 1 | package org.example.utils.vaadinbridge.internal; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.http.HttpServletRequest; 5 | 6 | import org.example.utils.vaadinbridge.ApplicationFactory; 7 | 8 | import com.vaadin.Application; 9 | import com.vaadin.Application.SystemMessages; 10 | import com.vaadin.terminal.gwt.server.AbstractApplicationServlet; 11 | 12 | class ApplicationFactoryServlet extends AbstractApplicationServlet { 13 | 14 | private static final long serialVersionUID = 1L; 15 | private final ApplicationFactory factory; 16 | 17 | ApplicationFactoryServlet(ApplicationFactory factory) { 18 | this.factory = factory; 19 | } 20 | 21 | @Override 22 | protected Application getNewApplication(HttpServletRequest request) throws ServletException { 23 | return factory.newInstance(); 24 | } 25 | 26 | @Override 27 | protected Class getApplicationClass() { 28 | return null; 29 | } 30 | 31 | @Override 32 | protected String getApplicationCSSClassName() { 33 | return factory.getApplicationCSSClassName(); 34 | } 35 | 36 | @Override 37 | protected SystemMessages getSystemMessages() { 38 | SystemMessages messages = factory.getSystemMessages(); 39 | 40 | return messages != null ? messages : Application.getSystemMessages(); 41 | } 42 | } -------------------------------------------------------------------------------- /vaadin/vaadinbridge/src/main/java/org/example/utils/vaadinbridge/internal/ApplicationFactoryTracker.java: -------------------------------------------------------------------------------- 1 | package org.example.utils.vaadinbridge.internal; 2 | 3 | import javax.servlet.ServletException; 4 | 5 | import org.example.utils.vaadinbridge.ApplicationFactory; 6 | import org.osgi.framework.BundleContext; 7 | import org.osgi.framework.ServiceReference; 8 | import org.osgi.service.http.HttpService; 9 | import org.osgi.service.http.NamespaceException; 10 | import org.osgi.util.tracker.ServiceTracker; 11 | 12 | class ApplicationFactoryTracker extends ServiceTracker { 13 | 14 | private final HttpService httpService; 15 | 16 | ApplicationFactoryTracker(HttpService httpService, BundleContext context) { 17 | super(context, ApplicationFactory.class.getName(), null); 18 | this.httpService = httpService; 19 | } 20 | 21 | @Override 22 | public Object addingService(ServiceReference ref) { 23 | 24 | Object aliasObj = ref.getProperty(ApplicationFactory.ALIAS_NAME); 25 | if(aliasObj instanceof String) { 26 | String alias = (String) aliasObj; 27 | BundleContentHttpContext httpContext = new BundleContentHttpContext(ref.getBundle()); 28 | 29 | ApplicationFactory factory = (ApplicationFactory) context.getService(ref); 30 | ApplicationFactoryServlet servlet = new ApplicationFactoryServlet(factory); 31 | 32 | try { 33 | httpService.registerServlet(alias, servlet, null, httpContext); 34 | return alias; 35 | } catch (ServletException e) { 36 | // TODO Auto-generated catch block 37 | e.printStackTrace(); 38 | } catch (NamespaceException e) { 39 | // TODO Auto-generated catch block 40 | e.printStackTrace(); 41 | } 42 | } 43 | return null; 44 | } 45 | @Override 46 | public void removedService(ServiceReference ref, Object service) { 47 | String alias = (String) service; 48 | httpService.unregister(alias); 49 | 50 | context.ungetService(ref); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /vaadin/vaadinbridge/src/main/java/org/example/utils/vaadinbridge/internal/BundleContentHttpContext.java: -------------------------------------------------------------------------------- 1 | package org.example.utils.vaadinbridge.internal; 2 | 3 | import java.io.IOException; 4 | import java.net.URL; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | import org.osgi.framework.Bundle; 10 | import org.osgi.service.http.HttpContext; 11 | 12 | class BundleContentHttpContext implements HttpContext { 13 | 14 | private Bundle bundle; 15 | 16 | BundleContentHttpContext(Bundle bundle) { 17 | this.bundle = bundle; 18 | } 19 | 20 | public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException { 21 | // default behaviour assumes the container has already performed authentication 22 | return true; 23 | } 24 | 25 | public URL getResource(String name) { 26 | return bundle.getResource(name); 27 | } 28 | 29 | public String getMimeType(String name) { 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /vaadin/vaadinbridge/src/main/java/org/example/utils/vaadinbridge/internal/HttpServiceTracker.java: -------------------------------------------------------------------------------- 1 | package org.example.utils.vaadinbridge.internal; 2 | 3 | import org.osgi.framework.BundleContext; 4 | import org.osgi.framework.ServiceReference; 5 | import org.osgi.service.http.HttpService; 6 | import org.osgi.service.http.NamespaceException; 7 | import org.osgi.util.tracker.ServiceTracker; 8 | 9 | 10 | class HttpServiceTracker extends ServiceTracker { 11 | 12 | HttpServiceTracker(BundleContext context) { 13 | super(context, HttpService.class.getName(), null); 14 | } 15 | 16 | @Override 17 | public Object addingService(ServiceReference reference) { 18 | HttpService httpService = (HttpService) context.getService(reference); 19 | try { 20 | httpService.registerResources("/VAADIN", "/VAADIN", new TargetBundleHttpContext(context, "com.vaadin")); 21 | } catch (NamespaceException e) { 22 | e.printStackTrace(); 23 | } 24 | ApplicationFactoryTracker bridge = new ApplicationFactoryTracker(httpService, context); 25 | bridge.open(); 26 | return bridge; 27 | } 28 | @Override 29 | public void removedService(ServiceReference reference, Object service) { 30 | ApplicationFactoryTracker bridge = (ApplicationFactoryTracker) service; 31 | bridge.close(); 32 | context.ungetService(reference); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vaadin/vaadinbridge/src/main/java/org/example/utils/vaadinbridge/internal/LogTracker.java: -------------------------------------------------------------------------------- 1 | package org.example.utils.vaadinbridge.internal; 2 | 3 | import org.osgi.framework.BundleContext; 4 | import org.osgi.framework.ServiceReference; 5 | import org.osgi.service.log.LogService; 6 | import org.osgi.util.tracker.ServiceTracker; 7 | 8 | 9 | public class LogTracker extends ServiceTracker implements LogService { 10 | 11 | public LogTracker(BundleContext context) { 12 | super(context, LogService.class.getName(), null); 13 | } 14 | 15 | public void log(int level, String message) { 16 | log(null, level, message, null); 17 | } 18 | 19 | public void log(int level, String message, Throwable exception) { 20 | log(null, level, message, exception); 21 | } 22 | 23 | public void log(ServiceReference sr, int level, String message) { 24 | log(sr, level, message, null); 25 | } 26 | 27 | public void log(ServiceReference sr, int level, String message, Throwable exception) { 28 | LogService log = (LogService) getService(); 29 | if(log != null) 30 | log.log(sr, level, message, exception); 31 | } 32 | } -------------------------------------------------------------------------------- /vaadin/vaadinbridge/src/main/java/org/example/utils/vaadinbridge/internal/VaadinBridgeActivator.java: -------------------------------------------------------------------------------- 1 | package org.example.utils.vaadinbridge.internal; 2 | 3 | import org.osgi.framework.BundleActivator; 4 | import org.osgi.framework.BundleContext; 5 | 6 | 7 | public class VaadinBridgeActivator implements BundleActivator { 8 | public void start(BundleContext context) throws Exception { 9 | new HttpServiceTracker(context).open(); 10 | } 11 | public void stop(BundleContext context) throws Exception { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /voting/command/src/main/java/net/lr/tutorial/karaf/vote/command/impl/VoteAdd.java: -------------------------------------------------------------------------------- 1 | 2 | package net.lr.tutorial.karaf.vote.command.impl; 3 | 4 | import net.lr.tutorial.karaf.vote.model.VoteService; 5 | 6 | import org.apache.felix.gogo.commands.Argument; 7 | import org.apache.felix.gogo.commands.Command; 8 | import org.apache.karaf.shell.console.OsgiCommandSupport; 9 | 10 | 11 | /** 12 | * Displays the last log entries 13 | */ 14 | @Command(scope = "vote", name = "add", description = "add a vote") 15 | public class VoteAdd extends OsgiCommandSupport { 16 | protected VoteService voteService; 17 | 18 | @Argument(index = 0, name="topic", description = "Voting topic to show", required = true, multiValued = false) 19 | private String topic; 20 | 21 | @Argument(index = 1, name="vote", description = "Vote to add (1..6)", required = true, multiValued = false) 22 | private Integer vote; 23 | 24 | public void setVoteService(VoteService voteService) { 25 | this.voteService = voteService; 26 | } 27 | 28 | protected Object doExecute() throws Exception { 29 | System.out.println(String.format("Vote %d added for topic %s", vote, topic)); 30 | voteService.addVote(topic, vote); 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /voting/command/src/main/java/net/lr/tutorial/karaf/vote/command/impl/VoteStats.java: -------------------------------------------------------------------------------- 1 | 2 | package net.lr.tutorial.karaf.vote.command.impl; 3 | 4 | import net.lr.tutorial.karaf.vote.model.VoteService; 5 | import net.lr.tutorial.karaf.vote.model.Voting; 6 | 7 | import org.apache.felix.gogo.commands.Argument; 8 | import org.apache.felix.gogo.commands.Command; 9 | import org.apache.karaf.shell.console.OsgiCommandSupport; 10 | 11 | 12 | /** 13 | * Displays the last log entries 14 | */ 15 | @Command(scope = "vote", name = "stats", description = "list existing votes") 16 | public class VoteStats extends OsgiCommandSupport { 17 | protected VoteService voteService; 18 | 19 | @Argument(index = 0, name="topic", description = "Voting topic to show", required = true, multiValued = false) 20 | private String topic; 21 | 22 | public void setVoteService(VoteService voteService) { 23 | this.voteService = voteService; 24 | } 25 | 26 | protected Object doExecute() throws Exception { 27 | System.out.println("Executing command list"); 28 | Voting voting = voteService.getVoting(topic); 29 | System.out.println(voting.getStats()); 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /voting/command/src/main/resources/OSGI-INF/blueprint/command.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /voting/features/src/main/resources/features.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | mvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features 4 | mvn:org.apache.camel.karaf/apache-camel/${camel.version}/xml/features 5 | 6 | 7 | cxf-jaxrs 8 | camel-twitter 9 | camel-blueprint 10 | mvn:net.lr.karaf.tutorial.voting/voting-model/${pom.version} 11 | mvn:net.lr.karaf.tutorial.voting/voting-service/${pom.version} 12 | mvn:net.lr.karaf.tutorial.voting/voting-twitter-adapter/${pom.version} 13 | mvn:net.lr.karaf.tutorial.voting/voting-ui/${pom.version} 14 | mvn:net.lr.karaf.tutorial.voting/voting-command/${pom.version} 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /voting/model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | voting-model 8 | bundle 9 | 10 | 11 | net.lr.karaf.tutorial.voting 12 | voting-parent 13 | 1.0.0-SNAPSHOT 14 | 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | javax.ws.rs 23 | javax.ws.rs-api 24 | 2.0-m15 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /voting/model/src/main/java/net/lr/tutorial/karaf/vote/model/Vote.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.model; 2 | 3 | import java.util.Date; 4 | 5 | import javax.xml.bind.annotation.XmlType; 6 | 7 | @XmlType 8 | public class Vote { 9 | String topic; 10 | int vote; 11 | String fromUser; 12 | Date voteDateTime; 13 | 14 | public Vote() { 15 | } 16 | 17 | public Vote(String topic, int vote) { 18 | this(topic, vote, "Anonymous", new Date()); 19 | } 20 | 21 | public Vote(String topic, int vote, String fromUser, Date voteDateTime) { 22 | super(); 23 | this.topic = topic; 24 | setVote(vote); 25 | this.fromUser = fromUser; 26 | this.voteDateTime = voteDateTime; 27 | } 28 | 29 | public int getVote() { 30 | return vote; 31 | } 32 | 33 | public String getFromUser() { 34 | return fromUser; 35 | } 36 | 37 | public Date getVoteDateTime() { 38 | return voteDateTime; 39 | } 40 | 41 | public String getTopic() { 42 | return topic; 43 | } 44 | 45 | public void setTopic(String topic) { 46 | this.topic = topic; 47 | } 48 | 49 | public void setVote(int vote) { 50 | if (!isValid(vote)) { 51 | throw new IllegalArgumentException("Vote must be a number between 1 and 6"); 52 | } 53 | this.vote = vote; 54 | } 55 | 56 | public void setFromUser(String fromUser) { 57 | this.fromUser = fromUser; 58 | } 59 | 60 | public void setVoteDateTime(Date voteDateTime) { 61 | this.voteDateTime = voteDateTime; 62 | } 63 | 64 | public static boolean isValid(int vote) { 65 | return vote >= 1 && vote <= 6; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /voting/model/src/main/java/net/lr/tutorial/karaf/vote/model/VoteService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.model; 2 | 3 | import javax.ws.rs.DELETE; 4 | import javax.ws.rs.GET; 5 | import javax.ws.rs.PUT; 6 | import javax.ws.rs.Path; 7 | import javax.ws.rs.PathParam; 8 | import javax.ws.rs.Produces; 9 | import javax.ws.rs.core.MediaType; 10 | import javax.ws.rs.core.Response; 11 | 12 | @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) 13 | @Path("") 14 | public interface VoteService { 15 | @Path("") 16 | @GET 17 | Response getVotings(); 18 | 19 | @Path("{topic}") 20 | @GET 21 | Voting getVoting(@PathParam("topic") String topic); 22 | 23 | @Path("{topic}/stats") 24 | @GET 25 | @Produces(MediaType.APPLICATION_JSON) 26 | String getStats(@PathParam("topic") String topic); 27 | 28 | @Path("{topic}") 29 | @DELETE 30 | Voting removeVoting(@PathParam("topic") String topic); 31 | 32 | @Path("") 33 | @PUT 34 | void addVote(Vote vote); 35 | 36 | @Path("{topic}/vote/{vote}") 37 | @GET 38 | void addVote(@PathParam("topic") String topic, @PathParam("vote") int vote); 39 | } 40 | -------------------------------------------------------------------------------- /voting/model/src/main/java/net/lr/tutorial/karaf/vote/model/VoteStats.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.model; 2 | 3 | import javax.xml.bind.annotation.XmlElement; 4 | import javax.xml.bind.annotation.XmlRootElement; 5 | import javax.xml.bind.annotation.XmlType; 6 | 7 | @XmlType 8 | @XmlRootElement 9 | public class VoteStats { 10 | Integer[] stats; 11 | String[][] table; 12 | 13 | public VoteStats() { 14 | stats = new Integer[]{0,0,0,0,0,0}; 15 | table = new String[7][2]; 16 | } 17 | 18 | /** 19 | * @param vote 20 | */ 21 | public void countVote(Vote vote) { 22 | stats[vote.getVote()-1]++; 23 | } 24 | 25 | /** 26 | * 27 | * @return json table with two columns vote and count. In the lines each vote of 1 to 6 is represented 28 | */ 29 | @XmlElement 30 | public String getStats() { 31 | StringBuilder sb = new StringBuilder(); 32 | sb.append("[[" + encode("Vote") + "," + encode("Count") + "],"); 33 | for (int c=1; c<=6; c++) { 34 | sb.append("[" + encode("" + c) + "," + stats[c-1] + "]" ); 35 | sb.append((c==6)?"]":","); 36 | } 37 | return sb.toString(); 38 | } 39 | 40 | private String encode(String st) { 41 | return "\""+ st + "\""; 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /voting/model/src/main/java/net/lr/tutorial/karaf/vote/model/Voting.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.xml.bind.annotation.XmlElement; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | import javax.xml.bind.annotation.XmlType; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | @XmlRootElement 14 | @XmlType 15 | public class Voting { 16 | private static final Logger LOG = LoggerFactory.getLogger(Voting.class); 17 | private String topic; 18 | private List votes; 19 | 20 | public Voting() { 21 | this.votes = new ArrayList(); 22 | } 23 | 24 | public Voting(String topic) { 25 | this(); 26 | this.topic = topic; 27 | } 28 | 29 | @XmlElement 30 | public double getAverage() { 31 | int sum = 0; 32 | for (Vote vote : votes) { 33 | sum += vote.getVote(); 34 | } 35 | return new Double(sum) / votes.size(); 36 | } 37 | 38 | public String getTopic() { 39 | return topic; 40 | } 41 | 42 | public void setTopic(String topic) { 43 | this.topic = topic; 44 | } 45 | 46 | @XmlElement(name="vote") 47 | public List getVotes() { 48 | return votes; 49 | } 50 | 51 | public void addVote(Vote vote) { 52 | this.votes.add(vote); 53 | LOG.info("Adding vote {} on topic {}", vote.getVote(), vote.getTopic()); 54 | } 55 | 56 | public String getStats() { 57 | VoteStats stats = new VoteStats(); 58 | for (Vote vote : votes) { 59 | stats.countVote(vote); 60 | } 61 | return stats.getStats(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /voting/model/src/main/java/net/lr/tutorial/karaf/vote/model/VotingLink.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.model; 2 | 3 | import javax.xml.bind.annotation.XmlType; 4 | 5 | @XmlType 6 | public class VotingLink { 7 | String topic; 8 | String link; 9 | 10 | public VotingLink() { 11 | } 12 | 13 | public VotingLink(String topic, String link) { 14 | this.topic = topic; 15 | this.link = link; 16 | } 17 | 18 | public String getTopic() { 19 | return topic; 20 | } 21 | 22 | public String getLink() { 23 | return link; 24 | } 25 | 26 | public void setTopic(String topic) { 27 | this.topic = topic; 28 | } 29 | 30 | public void setLink(String link) { 31 | this.link = link; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /voting/model/src/main/java/net/lr/tutorial/karaf/vote/model/VotingLinks.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.xml.bind.annotation.XmlElement; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | import javax.xml.bind.annotation.XmlType; 9 | 10 | @XmlType 11 | @XmlRootElement 12 | public class VotingLinks { 13 | private List votings; 14 | 15 | public VotingLinks() { 16 | this.votings = new ArrayList(); 17 | } 18 | 19 | @XmlElement(name="votingLink") 20 | public List getVotingLinks() { 21 | return votings; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /voting/model/src/test/java/net/lr/tutorial/karaf/vote/model/VotingTest.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.model; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class VotingTest { 7 | private static final String TOPIC = "How do you like Camel ?"; 8 | 9 | @Test 10 | public void testAverage() { 11 | Voting voting = createVoting(); 12 | Assert.assertEquals(1.5, voting.getAverage(), 0.001); 13 | } 14 | 15 | private Voting createVoting() { 16 | Voting voting = new Voting(TOPIC); 17 | voting.addVote(new Vote(TOPIC, 1)); 18 | voting.addVote(new Vote(TOPIC, 2)); 19 | voting.addVote(new Vote(TOPIC, 1)); 20 | voting.addVote(new Vote(TOPIC, 2)); 21 | return voting; 22 | } 23 | 24 | @Test 25 | public void testStats() { 26 | Voting voting = createVoting(); 27 | voting.addVote(new Vote(TOPIC, 2)); 28 | String table = voting.getStats(); 29 | Assert.assertEquals("[[\"Vote\",\"Count\"],[\"1\",2],[\"2\",3],[\"3\",0],[\"4\",0],[\"5\",0],[\"6\",0]]", table); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /voting/service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | voting-service 7 | bundle 8 | 9 | 10 | net.lr.karaf.tutorial.voting 11 | voting-parent 12 | 1.0.0-SNAPSHOT 13 | 14 | 15 | 16 | 17 | net.lr.karaf.tutorial.voting 18 | voting-model 19 | ${project.version} 20 | 21 | 22 | org.apache.cxf 23 | cxf-rt-frontend-jaxrs 24 | ${cxf.version} 25 | 26 | 27 | org.apache.cxf 28 | cxf-rt-frontend-jaxws 29 | ${cxf.version} 30 | 31 | 32 | org.apache.cxf 33 | cxf-rt-transports-http 34 | ${cxf.version} 35 | 36 | 37 | org.apache.cxf 38 | cxf-rt-transports-http-jetty 39 | ${cxf.version} 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /voting/service/src/main/java/net/lr/tutorial/karaf/vote/service/MemoryVoteService.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.service; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.ws.rs.core.Link; 7 | import javax.ws.rs.core.Response; 8 | 9 | import net.lr.tutorial.karaf.vote.model.Vote; 10 | import net.lr.tutorial.karaf.vote.model.VoteService; 11 | import net.lr.tutorial.karaf.vote.model.Voting; 12 | 13 | public class MemoryVoteService implements VoteService { 14 | Map votingMap; 15 | 16 | public MemoryVoteService() { 17 | this.votingMap = new HashMap(); 18 | addVote("test1", 1); 19 | } 20 | 21 | @Override 22 | public Voting getVoting(String topic) { 23 | if (this.votingMap.containsKey(topic)) { 24 | return votingMap.get(topic); 25 | } else { 26 | Voting voting = new Voting(topic); 27 | this.votingMap.put(topic, voting); 28 | return voting; 29 | } 30 | } 31 | 32 | @Override 33 | public Voting removeVoting(String topic) { 34 | return this.votingMap.remove(topic); 35 | } 36 | 37 | @Override 38 | public void addVote(String topic, int voteNum) { 39 | getVoting(topic).addVote(new Vote(topic, voteNum)); 40 | } 41 | 42 | @Override 43 | public Response getVotings() { 44 | Link[] links = new Link[votingMap.size()]; 45 | int c = 0; 46 | for (Voting voting : votingMap.values()) { 47 | links[c++] = Link.fromResourceMethod(VoteService.class, "getVoting", voting.getTopic()).build(); 48 | } 49 | return Response.ok().links(links).build(); 50 | } 51 | 52 | @Override 53 | public void addVote(Vote vote) { 54 | if (vote != null) { 55 | getVoting(vote.getTopic()).addVote(vote); 56 | } 57 | } 58 | 59 | @Override 60 | public String getStats(String topic) { 61 | return getVoting(topic).getStats(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /voting/twitter-adapter/src/main/java/net/lr/tutorial/karaf/vote/adapter/IrcConverter.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.adapter; 2 | 3 | import java.util.Date; 4 | 5 | import org.apache.camel.Header; 6 | 7 | import net.lr.tutorial.karaf.vote.model.Vote; 8 | 9 | public class IrcConverter { 10 | public Vote textToVote(String chatLine, @Header("irc.user.nick") String userNick) { 11 | String[] parts = chatLine.split(" "); 12 | String topic = parts[0]; 13 | int voteNum = Integer.parseInt(parts[1]); 14 | return new Vote(topic, voteNum, userNick, new Date()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /voting/twitter-adapter/src/main/java/net/lr/tutorial/karaf/vote/adapter/TwitterConverter.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.adapter; 2 | 3 | import net.lr.tutorial.karaf.vote.model.Vote; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import twitter4j.DirectMessage; 9 | import twitter4j.Status; 10 | 11 | public class TwitterConverter { 12 | Logger LOG = LoggerFactory.getLogger(TwitterConverter.class); 13 | 14 | public Vote convert(DirectMessage message) { 15 | try { 16 | String text = message.getText(); 17 | String[] parts = text.split(" "); 18 | String topic = parts[0]; 19 | int voteNum = Integer.parseInt(parts[1]); 20 | String fromUser = message.getSender().getName(); 21 | return new Vote(topic, voteNum, fromUser, message.getCreatedAt()); 22 | } catch (Throwable e) { 23 | LOG.info("Invalid tweet " + message.getText() + ": " + e.getMessage()); 24 | return null; 25 | } 26 | } 27 | 28 | public Vote convert(Status tweet) { 29 | try { 30 | String text = tweet.getText(); 31 | String[] parts = text.split(" "); 32 | String topic = parts[1]; 33 | int voteNum = Integer.parseInt(parts[2]); 34 | String fromUser = tweet.getSource(); 35 | return new Vote(topic, voteNum, fromUser, tweet.getCreatedAt()); 36 | } catch (Throwable e) { 37 | LOG.info("Invalid tweet " + tweet.getText() + ": " + e.getMessage()); 38 | return null; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /voting/twitter-adapter/src/main/java/net/lr/tutorial/karaf/vote/adapter/VotingRoutes.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.lr.tutorial.karaf.vote.adapter; 18 | 19 | import org.apache.camel.builder.RouteBuilder; 20 | 21 | /** 22 | * Receives votes based on twitter searches and direct messages 23 | */ 24 | public class VotingRoutes extends RouteBuilder { 25 | 26 | @Override 27 | public void configure() throws Exception { 28 | from("twitter://search?type=polling&delay=10&keywords=#esbvote") 29 | .bean(new TwitterConverter()) 30 | .to("direct:vote"); 31 | 32 | from("twitter://directmessage?type=polling&delay=60") 33 | .bean(new TwitterConverter()) 34 | .to("direct:vote"); 35 | 36 | from("irc:karafvoting@cameron.freenode.net:6667/karafvoting") 37 | .bean(new IrcConverter()) 38 | .to("direct:vote"); 39 | 40 | from("direct:vote") 41 | .choice().when(body().isNotNull()).to("bean:voteService").end() 42 | .to("log:INFO"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /voting/twitter-adapter/src/test/java/net/lr/tutorial/karaf/vote/adapter/TwitterConverterTest.java: -------------------------------------------------------------------------------- 1 | package net.lr.tutorial.karaf.vote.adapter; 2 | 3 | import java.util.Date; 4 | 5 | import net.lr.tutorial.karaf.vote.model.Vote; 6 | 7 | import org.easymock.EasyMock; 8 | import org.junit.Assert; 9 | import org.junit.Test; 10 | 11 | import twitter4j.Status; 12 | 13 | public class TwitterConverterTest { 14 | 15 | @Test 16 | public void testConvertStatus() { 17 | TwitterConverter converter = new TwitterConverter(); 18 | 19 | Status tweet = EasyMock.createMock(Status.class); 20 | EasyMock.expect(tweet.getSource()).andReturn("schneider_chris").anyTimes(); 21 | Date now = new Date(); 22 | EasyMock.expect(tweet.getCreatedAt()).andReturn(now).anyTimes(); 23 | EasyMock.expect(tweet.getText()).andReturn("#camel mytopic 2").anyTimes(); 24 | EasyMock.replay(tweet); 25 | Vote vote = converter.convert(tweet); 26 | Assert.assertEquals(tweet.getSource(), vote.getFromUser()); 27 | Assert.assertEquals(now, vote.getVoteDateTime()); 28 | Assert.assertEquals(2, vote.getVote()); 29 | Assert.assertEquals("mytopic", vote.getTopic()); 30 | EasyMock.verify(tweet); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /voting/twitter-adapter/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, out 2 | 3 | log4j.logger.org.apache.camel.impl.converter=WARN 4 | log4j.logger.org.apache.camel.management=WARN 5 | log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN 6 | log4j.logger.org.springframework=ERROR 7 | 8 | # CONSOLE appender not used by default 9 | log4j.appender.out=org.apache.log4j.ConsoleAppender 10 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n 12 | 13 | -------------------------------------------------------------------------------- /voting/ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | voting-ui 8 | bundle 9 | 10 | 11 | net.lr.karaf.tutorial.voting 12 | voting-parent 13 | 1.0.0-SNAPSHOT 14 | 15 | 16 | 17 | 18 | javax.servlet 19 | servlet-api 20 | 2.5 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /voting/ui/src/main/java/net/lr/karaf/tutorial/vote/ui/VoteChartServlet.java: -------------------------------------------------------------------------------- 1 | package net.lr.karaf.tutorial.vote.ui; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.PrintWriter; 6 | 7 | import javax.servlet.ServletException; 8 | import javax.servlet.http.HttpServlet; 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | public class VoteChartServlet extends HttpServlet { 13 | 14 | /** 15 | * 16 | */ 17 | private static final long serialVersionUID = 34992072289535683L; 18 | 19 | @Override 20 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) 21 | throws ServletException, IOException { 22 | PrintWriter writer = resp.getWriter(); 23 | InputStream is = VoteChartServlet.class.getClassLoader().getResourceAsStream("/index.html"); 24 | while (is.available() > 0) { 25 | writer.write(is.read()); 26 | } 27 | is.close(); 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /voting/ui/src/main/resources/OSGI-INF/blueprint/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /voting/voting-ui2/bin/src/main/java/my/MyServlet.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cschneider/Karaf-Tutorial/d979026c465e364c4ad688ff8bc7d1a090524377/voting/voting-ui2/bin/src/main/java/my/MyServlet.class -------------------------------------------------------------------------------- /voting/voting-ui2/src/main/java/my/MyServlet.java: -------------------------------------------------------------------------------- 1 | package my; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.ServletException; 6 | import javax.servlet.http.HttpServlet; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | public class MyServlet extends HttpServlet { 11 | 12 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 13 | // your logic here 14 | } 15 | 16 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 | // your logic here 18 | } 19 | 20 | } --------------------------------------------------------------------------------