This is a barebones sample application for a multi-module, multi-bundle apache karaf web application.
Intended to make it simple to start a new webapp.
The application database has a table “accounts” listing the users that are allowed to log into the database. It also has some tables supporting a simple counter application (the increment step size for the counter for each logged in user, and the current count for each user).
Highlights of the app:
- Uses the OSGi HTTP whiteboard to register servlets as services and give them a web context and paths
- react.js frontend, using redux for state management (set up using redux-toolkit)
- bootstrap v5 styling of the frontend
- i18n/l11n support (using redux on the frontend and Java resource bundles on the backend) with English and Norwegian as the languages
- JAX-RS REST Service support provided by eclipse jersey
- authentication and authorization provided by apache shiro (implemented in authservice, but in theory anything that provides a shiro Realm as an OSGi service and provides a shiro role named sampleappuser can give access to the application)
- JDBC configuration and setup using PAX JDBC config (provides a Datasource OSGi service using configuration only and no code needed)
- Database migration support provided by liquibase with sample database setups for apache derby and PostgreSQL
All user information, outside of the username, i.e. full name, email, comes from an injected OSGi service of type UserManagementService provided by the authservice.
The username/password combinations of users in the test db version of authservice, are:
username | password | authorized for sampleapp |
---|---|---|
jad | 1ad | yes |
jod | johnnyBoi | no |
First clone and build the sample application:
mkdir -p ~/git/ cd ~/git/ git clone https://github.com/steinarb/sampleapp.git cd ~/git/sampleapp/ mvn install
Then give the following commands to the karaf console:
feature:repo-add mvn:no.priv.bang.sampleapp/karaf/LATEST/xml/features feature:install sampleapp-with-derby
Then:
- open http://localhost:8181/sampleapp in a web browser
- log in as user “jad” with password “1ad”
- click on counter and use “-” and “+” to change the value
- try editing the step size, wait a few seconds and then observe that “+” and “-” change the value with the step size
- Navigate to the top page and log out
- Log in as user “jod” with password “johnnyBoi” and observe that you end in a “not authorized page” (the user exists but do not have the role of the app)
- Log out and log back in as user “jad”, navigate to the “counter” page, and observe that the count is like you left it (the count is persisted in the database)
Using the maven archetype plugin to adapt the sample project to a new project is simpler than hand editing the sample project and moving all packages and module names, but it doesn’t take you all the way (it doesn’t rename Java classes and doesn’t fix up the shiro.ini files).
To create a new project called “mynewapp”:
- First clone the sample project and create an archetype from it (it’s best to create an archetype from a fresh clone, because then the archetype won’t contain unnecessary files like IDE config files and binary files from the build)
cd /tmp git clone https://github.com/steinarb/sampleapp.git cd sampleapp mvn archetype:create-from-project -Darchetype.filteredExtensions=java cd target/generated-sources/archetype/ mvn install
- Create the new project from the archetype (the -DgroupId, -DartifactId, and -Dversion arguments are the GAV values of the new project)
mkdir -p ~/git/ cd ~/git/ mvn archetype:generate -DarchetypeCatalog=local -DarchetypeGroupId=no.priv.bang.sampleapp -DarchetypeArtifactId=sampleapp-archetype -DgroupId=com.mycompany.mynewapp -DartifactId=mynewapp -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false
- Fix the groupId for a karaf feature file dependency in the integration test maven module, because this dependency isn’t handled by the archetype project generator:
cd ~/git/mynewapp/ sed -i 's/no\.priv\.bang\.sampleapp/com.mycompany.mynewapp/gI' */pom.xml
- Fix up some files that aren’t handled by the archetype filtering (don’t know why everything in the pom files aren’t filtered)
sed -i 's/sampleapp/mynewapp/g' */src/main/resources/shiro.ini sed -i 's/sampleapp/mynewapp/g' */src/test/resources/test.shiro.ini sed -i 's/sampleapp/mynewapp/gI' */pom.xml find . -name \*.js | xargs sed -i 's/sampleapp/mynewapp/g'
- Add a .gitignore file (there is a bug in maven-resources-plugin that excludes this file from archetypes):
*.iml *.log .classpath .idea/ .project .settings/ /.metadata/ /TAGS node_modules/ target/
- Test build the project with “mvn install” (it should build without any errors)
cd ~/git/mynewapp/ mvn install
- Open the java maven modules of the mynewapp project, in a Java IDE (eclipse or IntelliJ), and use the refactoring of the IDE to rename classes with names starting with “Sampleapp” into classes starting with “Mynewapp” (this is the step that the archetype can’t handle, but at least the classes are already in packages they are supposed to be in for the new application), classnames to change:
SampleappServiceProvider SampleappServiceProviderTest SampleappService SampleappServiceTest SampleappException SampleappExceptionTest SampleappConstants SampleappLiquibase SampleappLiquibaseTest SampleappTestDbLiquibaseRunner SampleappTestDbLiquibaseRunnerTest SampleappProductionDbLiquibaseRunner SampleappProductionDbLiquibaseRunnerTest SampleappWebApi SampleappWebApiTest SampleappServlet SampleappServletTest SampleappServletContextHelper SampleappShiroFilter SampleappShiroFilterTest SampleappIntegrationTest SampleappTestdata SampleappTestdataTest
- Build mynewapp from the top with “mvn clean install” (“clean” is to get rid of .class files with the old names)
cd ~/git/mynewapp/ mvn clean install
- Fix some Java class member names that hasn’t been touched by the renaming (OSGi service injection setter and constants):
find . -name \*.java | xargs sed -i 's/Sampleapp/Mynewapp/g' find . -name \*.java | xargs sed -i 's/SAMPLEAPP/MYNEWAPP/g'
- Fix some leftover Sampleapp texts
find . -name pom.xml | xargs sed -i 's/Sampleapp/Mynewapp/g' find . -name feature.xml | xargs sed -i 's/Sampleapp/Mynewapp/g' find . -name \*.html | xargs sed -i 's/Sampleapp/Mynewapp/g' find . -name package.json | xargs sed -i 's/Sampleapp/Mynewapp/g' find . -name package-lock.json | xargs sed -i 's/Sampleapp/Mynewapp/g' find ./mynewapp.web.frontend/src/main/frontend/src -name \*.js | xargs sed -i 's/Sampleapp/Mynewapp/g'
- Fix copyright dates
find . -name *.xml | xargs sed -i 's/2021-2022/2024/g' find . -name *.java | xargs sed -i 's/2021-2022/2024/g' find . -name *.xml | xargs sed -i 's/2021-2023/2024/g' find . -name *.java | xargs sed -i 's/2021-2023/2024/g' find . -name *.java | xargs sed -i 's/2021-2024/2024/g' find . -name *.xml | xargs sed -i 's/2021/2024/g' find . -name *.java | xargs sed -i 's/2021/2024/g'
- Install mynewapp in a karaf instance
feature:repo-add mvn:com.mycompany.mynewapp/karaf/LATEST/xml/features feature:install mynewapp-with-derby
- Verify that the application is running on http://localhost:8181/mynewapp
Out of the box, the sample application supports two locales: nb_NO (Norwegian bokmål) and en_GB (UK English).
The locale texts are provided by a Java resource bundle, and new languages can be added by adding them to the bundle and to the available locales returned by the SampleappService.
The default locale is nb_NO.
It is possible to persistently configuring the default locale to en_GB with the following commands in the karaf console command line:
config:edit no.priv.bang.sampleapp.backend.SampleappServiceProvider config:property-set defaultlocale en_GB config:update
Note! The name of the config file will change when the package name and classname of the class changes in a new application based on this one, so adjust the command example accordingly.
This software is licensed with the Apache License v2. See the file LICENSE for details.