We've been talking about our new NixMash Blog application where we have both public and private content. Here's the GitHub Repository with the public release. Prior to this post we covered how to manage two versions of an application in Git (here and here.) Today we'll look at how we're separating private and public resources and templates with Spring.
The design goal for our Blog Application is NO overlap between private and public content. We have the following separate elements in our application:
- Thymeleaf Templates
- Static Resources like CSS files and images
- Freemarker Templates
- Separate Messages.properties files in multiple modules
- Separate external properties files by mode for development and testing
Before looking at how we're using Spring to prevent any overlap of those resources and templates let's look at some screenshots.
Here is the layout of the MVC Module master branch where both private and public content lives. Admin and common at (1) are shared between the two versions, nixmash and private are the private templates and static resource locations (2), static and templates are public (3). Mvc.properties is shared, while messages.properties is public and nixmash.properties private (4).
Now let's look at the public MVC Module contents in the public branch. Nice and clean.
What We Want to Avoid
This is what we want to avoid, storing configuration settings for two separate application versions in a single String .properties file. We don't want to have to resolve anything in core configuration files when merging and updating the public repository.
A Single Public-Private Master Switch
All modules in the NixMash Blog application flow through JPA, so that's where we're going to put a “master switch.” It will be in the form of an application.properties setting that we can override with Spring command line arguments. (See this NixMash Post for more on using Spring Command Line arguments.)
Our Master Switch is nixmash.mode.enabled, defaulting to false unless overridden on the command line or in a Gradle bootRun task. We also have a property for the external properties file base name we can override.
Here's an example of using the Master Switch in our MAIL Module where we set the Freemarker TemplateLoaderPath based on the current execution mode. Notice we're doing an @Import of the JPA ApplicationConfig.class to put its application.properties file in context for accessing the nixmash.mode.enabled setting.
Static Resource Separation
Back to our MVC Module where we're keeping our Static Resources separate. We use a similar “Master Switch” approach here as well.
Setting the Execution Mode at Runtime
The idea for executing the application is for Open Source users to simply run the app, which will default to using all public resources and template locations. As caretaker of both releases it is up to the private, master branch developer to switch between private and public modes when required. Here is an example of doing that in an IntelliJ Run Configuration.
Source Code Notes for this Post
Source code discussed in this post can be found in my NixMash Blog project located on GitHub.