├── .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 |
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 extends Application> 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 | }
--------------------------------------------------------------------------------