Added RPM build
This commit is contained in:
parent
200b27e03c
commit
3cfbf9cf6e
|
@ -117,3 +117,11 @@ Followup: Excess payloads were being added to the welcome page
|
|||
that caused HTTP "400" errors fetching resources. A fix has
|
||||
been made, although the ultimate solution will probably be more
|
||||
JSF-friendly.
|
||||
|
||||
## Minor release 2.0.1
|
||||
|
||||
This release can build an installable RPM for Red Hat-compatible
|
||||
systems, including CentOS and its relatives and Fedora.
|
||||
|
||||
Just run ``mvn install`` and the RPM will be produced under the
|
||||
``/target/rpm`` directory.
|
96
architecture.md
Normal file
96
architecture.md
Normal file
|
@ -0,0 +1,96 @@
|
|||
# GourmetJ application Architecture.
|
||||
|
||||
This is a Spring Boot self-hosted website built on standard JEE
|
||||
components like JavaServer Faces (JSF) and the Java Persistence
|
||||
Architecture (JPA). It is built and can be tested using Maven.
|
||||
|
||||
The Maven pom.xml file determines the build and what dependencies
|
||||
it has. The core dependencies and their versions are determined
|
||||
in the `dependencyManagement` section of the POM. Actual inclusion
|
||||
of dependencies is done in the `dependencies` section.
|
||||
|
||||
Of the 3 dependencyManagement dependencies, the JoinFaces BOM is
|
||||
the most important. It ensures that the proper version of Spring
|
||||
Boot and its dependencies is brought into the `dependencies` as
|
||||
well as allowing the option to select which JSF extension libraries
|
||||
are to be used. For this project, PrimeFaces is the primary JSF
|
||||
framework.
|
||||
|
||||
## Source Code components
|
||||
|
||||
Source code files come in 4 major types:
|
||||
|
||||
1. Spring/Spring Boot support
|
||||
1. JSF Backing Beans
|
||||
1. Data Persistence
|
||||
1. General Utilities (for example data format converters and parsers)
|
||||
|
||||
### Spring and Spring Boot Support
|
||||
|
||||
The application code root package is `com.mousetech.gourmetj`. The
|
||||
Spring configuration classes are located in this package. There
|
||||
are two of them: `SpringPrimeFacesApplication'java`, which is the
|
||||
main class for the app, and `SpringSecurityConfig.java`, which
|
||||
defines security. Security credentials (userid/password) are taken
|
||||
from an external password file whose location is defined by the
|
||||
`application.yml` properties file. There are no security roles, and
|
||||
all site pages are accessible without logging in except for the
|
||||
ones that can modify the database (create/edit recipe).
|
||||
|
||||
Secondary Spring characteristics come from the `WelcomePageRedirect.java`
|
||||
file which defines the site's welcome page (index.html).
|
||||
|
||||
A small bit of Spring Web in the `springweb.PicureController` class.
|
||||
This Controller resolves the image URLs for recipe images and
|
||||
thumbnails.
|
||||
|
||||
### JSF BackingBeans
|
||||
|
||||
The heart of the webapp is in JavaServer Faces Backing Beans which
|
||||
provide the Models for their corresponding View Template (.xhtml)
|
||||
files. The most important beans are the adminMain bean, which
|
||||
generates the recipe list page and the recipeDetail bean, which
|
||||
back the display and editing of a recipe. The CookieBean is
|
||||
a utility class that allows keeping search information in user-side
|
||||
cookies between user sessions and JSFUtils allows access to
|
||||
HTTP/Servlet soecific resources in a way that isolates them from
|
||||
the general application code. That allows platform independence
|
||||
and easier unit testing.
|
||||
|
||||
### Persistence
|
||||
|
||||
Persistence is done via JPA and has 3 layers:
|
||||
|
||||
1. Service layer. This layer fetches and updates "working sets" of
|
||||
related database entity objects. All service methods are
|
||||
Transactions. Working sets passed in or out of the service layer
|
||||
to the higher (business) layer of the app are detached objects,
|
||||
so the Service layer also ensures detaching and re-attaching
|
||||
(merging) as needed for the lower layer functions.
|
||||
|
||||
1. DAO layer. This layer does find/CRUD functions for a single
|
||||
Entity type or sometimes a parent/child Entity set. I've coded this
|
||||
using explicit logic in times past, but in this app, I've leveraged
|
||||
Spring's Repository feature to let it write the grunt code.
|
||||
|
||||
1. Model layer. This layer contains the actual Entity classes,
|
||||
which are all POJOs and have no executable logic except get/set.
|
||||
|
||||
### Utilities
|
||||
|
||||
Most utility services are in the ``utils`` package, except for
|
||||
JSFUtils, which serves as a liason between JSF server-independent
|
||||
code and server platform-specific services.
|
||||
|
||||
## Future considerations
|
||||
|
||||
There's probably still some lint in the POM and perhaps some dead
|
||||
code from deadend solutions that weren't viable. That's how apps
|
||||
are in the Real World.
|
||||
|
||||
Adding an I18N Bundle would probably be nice.
|
||||
|
||||
A Schema file was recently added to the project and it needs to
|
||||
be checked for functionality. A similar `data.sql` is probably
|
||||
needed to be able to fully set up a database from scratch. My
|
||||
current copy was simply cloned from an existing database.
|
74
pom.xml
74
pom.xml
|
@ -7,7 +7,7 @@
|
|||
|
||||
<groupId>com.mousetech.gourmet</groupId>
|
||||
<artifactId>gourmetj</artifactId>
|
||||
<version>0.3.1</version>
|
||||
<version>2.0.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>GourmetJ</name>
|
||||
|
@ -177,6 +177,78 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>rpm-maven-plugin</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-rpm</id>
|
||||
<goals>
|
||||
<goal>rpm</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<license>GPL (c) 2024, mousetech.com</license>
|
||||
<distribution>Gourmetj</distribution>
|
||||
<group>Application/Collectors</group>
|
||||
<packager>Tom Holloway</packager>
|
||||
<prefix>/usr/local</prefix>
|
||||
<changelogFile>src/changelog</changelogFile>
|
||||
<defineStatements>
|
||||
<defineStatement>_unpackaged_files_terminate_build 0</defineStatement>
|
||||
</defineStatements>
|
||||
<mappings>
|
||||
<mapping>
|
||||
<directory>/opt/mousetech/gourmetj</directory>
|
||||
<filemode>750</filemode>
|
||||
<username>gourmetj</username>
|
||||
<groupname>gourmetj</groupname>
|
||||
<sources>
|
||||
<source>
|
||||
<location>
|
||||
target/${project.build.finalName}.jar</location>
|
||||
</source>
|
||||
<softlinkSource>
|
||||
<destination>gourmetj.jar</destination>
|
||||
<location>
|
||||
${project.build.finalName}.jar</location>
|
||||
</softlinkSource>
|
||||
</sources>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/mousetech/gourmetj</directory>
|
||||
<configuration>true</configuration>
|
||||
<filemode>440</filemode>
|
||||
<username>gourmetj</username>
|
||||
<groupname>gourmetj</groupname>
|
||||
<sources>
|
||||
<source>
|
||||
<location>src/main/conf</location>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/etc/systemd/system/</directory>
|
||||
<directoryIncluded>false</directoryIncluded>
|
||||
<configuration>true</configuration>
|
||||
<filemode>440</filemode>
|
||||
<sources>
|
||||
<source>
|
||||
<location>src/main/systemd/gourmetj.service</location>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
</mappings>
|
||||
<preinstallScriptlet>
|
||||
<script>echo "installing ${project.name} now"
|
||||
/usr/bin/getent passwd gourmetj || /usr/sbin/useradd -r -d /opt/mousetech/gourmetj -s /sbin/nologin gourmetj
|
||||
</script>
|
||||
</preinstallScriptlet>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
1
src/main/conf/.gourmetpw
Normal file
1
src/main/conf/.gourmetpw
Normal file
|
@ -0,0 +1 @@
|
|||
# Application user password file
|
29
src/main/conf/application.properties
Normal file
29
src/main/conf/application.properties
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
# THIS is the application properties used when testing in the IDE
|
||||
# or running stand-alone from the command line.
|
||||
# It augments/overrides application.yml in the JAR
|
||||
joinfaces.jsf.webapp-resources-directory=/resources
|
||||
server.servlet.session.timeout=30m
|
||||
|
||||
spring.thymeleaf.enabled=false
|
||||
server.error.whitelabel.enabled=false
|
||||
|
||||
spring.datasource.url=jdbc:mysql://dbase/recipes
|
||||
#jdbc:sqlite:${home}/recipes.db
|
||||
spring.datasource.username=recipes
|
||||
pring.datasource.password=yumyumyum
|
||||
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
|
||||
|
||||
#Runtime lies and says no longer required, but it defaults to MySQL5.5.0!:
|
||||
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
|
||||
#org.sqlite.hibernate.dialect.SQLiteDialect
|
||||
#spring.jpa.show-sql: true
|
||||
|
||||
# My special properties
|
||||
gourmet.password.file=.gourmetpw
|
||||
|
||||
# This will override aplication.yml
|
||||
#server.servlet.context-parameters.primefaces.THEME=le-frog
|
||||
|
||||
### HttpSession timeout (note effects on detailEdit idleMonitors)
|
||||
server.servlet.session.timeout=35m
|
16
src/main/systemd/gourmetj.service
Normal file
16
src/main/systemd/gourmetj.service
Normal file
|
@ -0,0 +1,16 @@
|
|||
[Unit]
|
||||
Description=Gourmet Recipe Manager
|
||||
Documentation=https://gogs.mousetech.com/gourmetj
|
||||
Requires=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=gourmetj
|
||||
WorkingDirectory=/opt/mousetech/gourmetj
|
||||
ExecStart=/usr/bin/java -jar gourmetj.jar
|
||||
#Restart=yes
|
||||
|
||||
[Install]
|
||||
Alias=gourmetj.service
|
||||
|
Loading…
Reference in New Issue
Block a user