diff --git a/README.md b/README.md index 6bc75f5..3a1a633 100644 --- a/README.md +++ b/README.md @@ -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. \ No newline at end of file diff --git a/architecture.md b/architecture.md new file mode 100644 index 0000000..c78274f --- /dev/null +++ b/architecture.md @@ -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. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 845e081..56a9313 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.mousetech.gourmet gourmetj - 0.3.1 + 2.0.1 jar GourmetJ @@ -177,6 +177,78 @@ org.springframework.boot spring-boot-maven-plugin + + org.codehaus.mojo + rpm-maven-plugin + 2.3.0 + + + generate-rpm + + rpm + + + + + GPL (c) 2024, mousetech.com + Gourmetj + Application/Collectors + Tom Holloway + /usr/local + src/changelog + + _unpackaged_files_terminate_build 0 + + + + /opt/mousetech/gourmetj + 750 + gourmetj + gourmetj + + + + target/${project.build.finalName}.jar + + + gourmetj.jar + + ${project.build.finalName}.jar + + + + + /opt/mousetech/gourmetj + true + 440 + gourmetj + gourmetj + + + src/main/conf + + + + + /etc/systemd/system/ + false + true + 440 + + + src/main/systemd/gourmetj.service + + + + + + + + + + diff --git a/src/main/conf/.gourmetpw b/src/main/conf/.gourmetpw new file mode 100644 index 0000000..9eb830a --- /dev/null +++ b/src/main/conf/.gourmetpw @@ -0,0 +1 @@ +# Application user password file diff --git a/src/main/conf/application.properties b/src/main/conf/application.properties new file mode 100644 index 0000000..78b3cae --- /dev/null +++ b/src/main/conf/application.properties @@ -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 diff --git a/src/main/systemd/gourmetj.service b/src/main/systemd/gourmetj.service new file mode 100644 index 0000000..b0efc43 --- /dev/null +++ b/src/main/systemd/gourmetj.service @@ -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 +