This is an automated email from the ASF dual-hosted git repository.
meonkeys pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 1a2ab056e9 FINERACT-2383: Modernize and correct README page (#5076)
1a2ab056e9 is described below
commit 1a2ab056e993a606c7263bafbe0a1a5e94470efe
Author: Felix van Hove <[email protected]>
AuthorDate: Tue Oct 14 18:23:04 2025 +0200
FINERACT-2383: Modernize and correct README page (#5076)
see
https://github.com/apache/fineract/pull/5076
https://issues.apache.org/jira/browse/FINERACT-2383
https://lists.apache.org/thread/6nctwb6g6krxxtcxr3q1blx2xb9w8h1s
---
CONTRIBUTING.md | 242 +++++++++++++++++++++-
README.md | 608 ++++++++++++++++----------------------------------------
2 files changed, 407 insertions(+), 443 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 57724d1f3f..e948c167f3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,16 +1,240 @@
+# Contributing
+
Hello there!
-First of all, **Thank You** for contributing to Apache Fineract, we're
grateful for your interest in our project.
+First of all, **Thank You** for contributing to Apache Fineract! We are
grateful for your interest in this project.
+
+Please join the [developer mailing
list](https://fineract.apache.org/#contribute), if you have not already done
so, as this is where discussions about this project take place - say _Hi_
there! Please also have a quick look at the [Code of
Conduct](CODE_OF_CONDUCT.md).
+
+The [JIRA
Dashboard](https://issues.apache.org/jira/secure/Dashboard.jspa?selectPageId=12335824)
shows what's going on. Create a login - it can take a day or two. If you face
difficulties, ask on the mailing list.
+
+You don't need to be a committer to provide pull requests, but [Becoming a
Committer](https://cwiki.apache.org/confluence/display/FINERACT/Becoming+a+Committer)
explains the process of becoming one - just in case...
+
+
+## Developer How To's
+
+### How to run tests
+
+#### Unit tests
+
+Here's how to run the set of relatively fast and independent Fineract tests:
+
+```bash
+./gradlew test -x :twofactor-tests:test -x :oauth2-tests:test -x
:integration-tests:test
+```
+
+This runs nearly 1,000 tests and completes in a few minutes on decent hardware.
+They shouldn't need any special servers/services running.
+
+#### Integration tests
+
+Running tests with external dependencies is a multi-step process with many
moving parts.
+Sometimes there are arbitrary failures and the prerequisite setup can be
daunting.
+A full local integration test run (on a developer workstation) covering every
possible test using every external service and every supported relational
database engine could take an entire day - and that's assuming everything is
properly configured and runs as expected.
+
+Right now we depend on GitHub to know if "the build" is passing (it's actually
multiple builds).
+The authoritative source of truth for what commands/services/tests to run,
how, and when are the files in `.github/workflows/`.
+Output from runs based on those configuration files appears at
<https://github.com/apache/fineract/actions>.
+
+Incorrect default Java-related executables may cause test failures.
+To fix this on Debian and Ubuntu systems, run the following:
+
+```bash
+export JAVA_HOME=/usr/lib/jvm/zulu21
+sudo update-alternatives --set java $JAVA_HOME/bin/java
+sudo update-alternatives --set javac $JAVA_HOME/bin/javac
+sudo update-alternatives --set javadoc $JAVA_HOME/bin/javadoc
+```
+
+This would correct, for example, a [class file version
error](https://en.wikipedia.org/wiki/Java_class_file#General_layout).
+You might see something like this if a Java 11 executable (class file format
version 56) was the system default, but the integration tests were using Java
21 (class file format version 65):
+
+> UnsupportedClassVersionError: com.example.package/ClassName has been
compiled by a more recent version of the Java Runtime (class file version
65.0), this version of the Java Runtime only recognizes class file versions up
to 55.0
+
+The GitHub builds are run in [short-lived virtual
machines](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners),
so locally reproducing the same may require additional effort, such as these
extra clean-up procedures:
+
+```bash
+# Might fix `error: cannot find symbol` or other intermittent failures.
+# `doc` here is a placeholder for any task(s) you are trying to run.
+# π This is generally very safe to run between builds.
+./gradlew --refresh-dependencies doc
+
+# Destroy anything untracked by git.
+# β οΈ This may delete something important, e.g. a finely-tuned IDE
configuration.
+git clean --force -dx
+
+# Destroy various caches and configs.
+# β οΈ This may delete gibibytes of cached data, making the next build very slow.
+rm -rf ~/.gradle ~/.m2 /tmp/cargo*
+
+# Destroy any Java containers left running.
+# π This is generally very safe to run between builds.
+ps auxwww | grep [c]argo | awk '{ print $2 }' | xargs -r kill
+```
+
+Integration test runs such as
+```bash
+./gradlew --no-daemon --console=plain test -x :twofactor-tests:test \
+ -x :oauth2-tests:test :fineract-e2e-tests-runner:test -PdbType=postgresql
+```
+in `.github/workflows/build-postgresql.yml` often take an hour or longer to
complete.
+If you notice the `:integration-tests:test` task taking significantly less
time, say, one minute, gradle may be skipping it.
+Look for something like this in the test output:
+
+> Task :integration-tests:test UP-TO-DATE π
+Custom actions are attached to task ':integration-tests:test'.
+Build cache key for task ':integration-tests:test' is
6aeeec3f58bf9703d4c100fbaa657f5c
+Skipping task ':integration-tests:test' as it is up-to-date.
+Resolve mutations for :integration-tests:cargoStopLocal (Thread[Execution
worker Thread 11,5,main]) started.
+:integration-tests:cargoStopLocal (Thread[Execution worker Thread 11,5,main])
started.
+
+
+(This is with the `--info` gradle argument with eyeballs added for emphasis.)
+The `--rerun-tasks` gradle argument may help, or you can try destroying
`~/.gradle` and other clean-up procedures as indicated above, then re-running
tests.
+This is useful for repeated test runs (say, for timing) when gradle would
otherwise assume a task is "up-to-date" and not re-run it.
+
+See the next section for testing in Eclipse and
[here](https://fineract-academy.com) for testing in IntelliJ.
+
+### How to run and debug in Eclipse IDE
+
+It is possible to run Fineract in Eclipse IDE and also to debug Fineract using
Eclipse's debugging facilities.
+To do this, you need to create the Eclipse project files and import the
project into an Eclipse workspace:
+
+1. Create Eclipse project files into the Fineract project by running
`./gradlew cleanEclipse eclipse`
+2. Import the fineract-provider project into your Eclipse workspace
(File->Import->General->Existing Projects into Workspace, choose root directory
fineract/fineract-provider)
+3. Do a clean build of the project in Eclipse (Project->Clean...)
+3. Run / debug Fineract by right clicking on
org.apache.fineract.ServerApplication class and choosing Run As / Debug As ->
Java Application. All normal Eclipse debugging features (breakpoints,
watchpoints etc) should work as expected.
+
+If you change the project settings (dependencies etc) in Gradle, you should
redo step 1 and refresh the project in Eclipse.
+
+You can also use Eclipse JUnit support to run tests in Eclipse (Run As->JUnit
Test)
+
+Finally, modifying source code in Eclipse automatically triggers hot code
replace to a running instance, allowing you to immediately test your changes
+
+How to download Gradle wrapper
+---
+The file gradle/wrapper/gradle-wrapper.jar binary is checked into this
projects Git source repository,
+but won't exist in your copy of the Fineract codebase if you downloaded a
released source archive from apache.org.
+In that case, you need to download it using the commands below:
+```bash
+wget -P gradle/wrapper
https://github.com/apache/fineract/raw/develop/gradle/wrapper/gradle-wrapper.jar
+```
+or
+```bash
+curl -L
https://github.com/apache/fineract/raw/develop/gradle/wrapper/gradle-wrapper.jar
> \
+ gradle/wrapper/gradle-wrapper.jar
+```
+
+### How to run Apache RAT (Release Audit Tool)
+
+1. Extract the archive file to your local directory.
+2. Run `./gradlew rat`. A report will be generated under
build/reports/rat/rat-report.txt
+
+
+### How to build documentation
+
+Run the following command:
+
+```bash
+./gradlew doc
+```
+
+Some dependencies are required (e.g. Ghostscript, Graphviz), see
[.github/workflows/build-documentation.yml](https://github.com/apache/fineract/tree/develop/.github/workflows/build-documentation.yml)
for hints.
+
+IDEs such as IntelliJ are useful for editing the AsciiDoc source files while
providing a live rendered preview.
+
+HTML rendered from the AsciiDoc source files is also available online at
[https://fineract.apache.org/docs/current/](https://fineract.apache.org/docs/current/).
+
+
+## How We Code
+
+### Checkstyle and Spotless
+
+This project enforces its code conventions using
[checkstyle.xml](config/checkstyle/checkstyle.xml) through Checkstyle and
[fineractdev-formatter.xml](config/fineractdev-formatter.xml) through Spotless.
They are configured to run automatically during the normal Gradle build, and
fail if there are any violations detected. You can run the following command to
automatically fix spotless violations:
+```bash
+./gradlew spotlessApply
+```
+Since some checks are present in both Checkstyle and Spotless, the same
command can help you fix some of the Checkstyle violations too.
+
+You can also check solely for Spotless violations, but normally don't have to,
because regular builds already include this:
+```bash
+./gradlew spotlessCheck
+```
+
+We recommend that you configure your favourite Java IDE to match those
conventions. For Eclipse, you can go to
+Window > Java > Code Style and import the aforementioned
[config/fineractdev-formatter.xml](config/fineractdev-formatter.xml) under
formatter section and
[config/fineractdev-cleanup.xml](config/fineractdev-cleanup.xml) under cleanup
section.
+
+You could also use Checkstyle directly in your IDE, but you don't have to: it
may just be more convenient for you. For Eclipse, use
https://checkstyle.org/eclipse-cs/ and load our checkstyle.xml into it. For
IntelliJ you can use
[CheckStyle-IDEA](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea).
+
+
+### Code Coverage
+
+Changed or added code should ideally have test coverage.
+
+The project uses Jacoco to measure unit tests code coverage. To generate a
report run the following command:
+```bash
+./gradlew clean build jacocoTestReport
+```
+Generated reports can be found in the build/code-coverage directory.
+
+
+### Error Handling
+
+* When catching exceptions, either rethrow them, or log them. Either way,
include the root cause by using `catch (SomeException e)` and then either
`throw AnotherException("..details..", e)` or `LOG.error("...context...", e)`.
+* Completely empty catch blocks are VERY suspicious. Are you sure that you
want to just "swallow" an exception? Really, 100% totally absolutely sure??
;-) Such "normal exceptions which just happen sometimes but are actually not
really errors" are almost always a bad idea, can be a performance issue, and
typically are an indication of another problem - e.g. the use of a wrong API
which throws an Exception for an expected condition, when really you would want
to use another API that inst [...]
+* In tests, you'll typically never catch exceptions, but just propagate them,
with `@Test void testXYZ() throws SomeException, AnotherException`..., so that
the test fails if the exception happens. Unless you actually really want to
test for the occurrence of a problem - in that case, use [JUnit's
Assert.assertThrows()](https://github.com/junit-team/junit4/wiki/Exception-testing)
(but not `@Test(expected = SomeException.class)`).
+* Never catch `NullPointerException` & Co.
+
+### Logging
+
+* We use [SLF4J](http://www.slf4j.org) as our logging API.
+* Never, ever, use `System.out` and `System.err` or `printStackTrace()`
anywhere, but always `LOG.info()` or `LOG.error()` instead.
+* Use placeholder (`LOG.error("Could not... details: {}", something,
exception)`) and never String concatenation (`LOG.error("Could not... details:
" + something, exception)`)
+* Which Log Level is appropriate?
+ * `LOG.error()` should be used to inform an "operator" running Fineract
who supervises error logs of an unexpected condition. This includes technical
problems with an external "environment" (e.g. can't reach a database), and
situations which are likely bugs which need to be fixed in the code. They do
NOT include e.g. validation errors for incoming API requests - that is signaled
through the API response - and does (should) not be logged as an error. (Note
that there is no _FATAL_ [...]
+ * `LOG.warn()` should be using sparingly. Make up your mind if it's an
error (above) - or not!
+ * `LOG.info()` can be used notably for one-time actions taken during
start-up. It should typically NOT be used to print out "regular" application
usage information. The default logging configuration always outputs the
application INFO logs, and in production under load, there's really no point to
constantly spew out lots of information from frequently traversed paths in the
code about what's going on. (Metrics are a better way.) `LOG.info()` *can* be
used freely in tests though.
+ * `LOG.debug()` can be used anywhere in the code to log things that may be
useful during investigations of specific problems. They are not shown in the
default logging configuration, but can be enabled for troubleshooting.
Developers should typically "turn down" most `LOG.info()` which they used while
writing a new feature to "follow along what happens during local testing" to
`LOG.debug()` for production before we merge their PRs.
+ * `LOG.trace()` is not used in Fineract.
+
+## Change Process
+
+### Dependency Upgrades
+
+This project uses a number of 3rd-party libraries. We have set up [Renovate's
bot](https://github.com/renovatebot/github-action) to automatically raise Pull
Requests for our review when new dependencies are available.
+
+Our `ClasspathHellDuplicatesCheckRuleTest` detects classes that appear in more
than 1 JAR. If a version bump in
[build.gradle](https://github.com/apache/fineract/blob/develop/build.gradle)
causes changes in transitives dependencies, then you may have to add related
`exclude` to our
[dependencies.gradle](https://github.com/apache/fineract/search?q=dependencies.gradle).
Running `./gradlew dependencies` helps to understand what is required.
+
+### Pull Requests
+
+We request that your commit message includes a FINERACT JIRA issue and a
one-liner that describes the changes.
+Start with an upper case imperative verb (not past form), and a short but
concise clear description. (E.g. "FINERACT-821: Add enforced
HideUtilityClassConstructor checkstyle").
+
+If your PR is failing to pass our CI build due to a test failure, then:
+
+1. Understand if the failure is due to your PR or an unrelated unstable test.
+1. If you suspect it is because of a "flaky" test, and not due to a change in
your PR, then please do not simply wait for an active maintainer to come and
help you, but instead be a proactive contributor to the project - see next
steps. Do understand that we may not review PRs that are not green - it is the
contributor's (that's you!) responsibility to get a proposed PR to pass the
build, not primarily the maintainers.
+1. Search for the name of the failed test on https://issues.apache.org/jira/,
e.g. for `AccountingScenarioIntegrationTest` you would find
[FINERACT-899](https://issues.apache.org/jira/browse/FINERACT-899).
+1. If you happen to read in such bug reports that tests were just recently
fixed, or ignored, then rebase your PR to pick up that change.
+1. If you find previous comments "proving" that the same test has arbitrarily
failed in at least 3 past PRs, then please do yourself raise a small separate
new PR proposing to add an `@Disabled // TODO FINERACT-123` to the respective
unstable test (e.g. [#774](https://github.com/apache/fineract/pull/774)) with
the commit message mentioning said JIRA, as always. (Please do NOT just
`@Disabled` any existing tests mixed in as part of your larger PR.)
+1. If there is no existing JIRA for the test, then first please evaluate
whether the failure couldn't be a (perhaps strange) impact of the change you
are proposing after all. If it's not, then please raise a new JIRA to document
the suspected Flaky Test, and link it to
[FINERACT-850](https://issues.apache.org/jira/browse/FINERACT-850). This will
allow the next person coming along hitting the same test failure to easily find
it, and eventually propose to ignore the unstable test.
+1. Then (only) Close and Reopen your PR, which will cause a new build, to see
if it passes.
+1. Of course, we very much appreciate you then jumping onto any such bugs and
helping us figure out how to fix all ignored tests!
+
+[Pull Request Size
Limit](https://cwiki.apache.org/confluence/display/FINERACT/Pull+Request+Size+Limit)
+documents that we cannot accept huge "code dump" Pull Requests, with some
related suggestions.
+
+Guideline for new Feature commits involving Refactoring: If you are submitting
a PR for a new feature,
+and it involves refactoring, try to differentiate "new feature code" from
"refactored" by placing
+them in different commits. This helps to review your code faster.
+
+We have an automated bot which marks pull requests as "stale" after a while,
and ultimately automatically closes them.
-Please do [join our developer mailing
list](https://fineract.apache.org/#contribute), as it's where discussions about
this project take place - say _Hi_ there!
-Our [JIRA
Dashboard](https://issues.apache.org/jira/secure/Dashboard.jspa?selectPageId=12335824)
is another good way to see what's going on (do create a Login).
+### Merge Strategy
-Here are a few additional useful pointers:
+This project's committers typically prefer to bring your pull requests in
through _Rebase and Merge_ instead of _Create a Merge Commit_. (If you are
unfamiliar with GitHub's UI regarding this, note the somewhat hidden little
triangle drop-down at the bottom of the PR, visible only to committers, not
contributors.) This avoids the "merge commits" which we consider to be
somewhat "polluting" the project's commit log history view. We understand this
doesn't give an easy automatic referenc [...]
-* https://github.com/apache/fineract/#pull-requests
-* https://github.com/apache/fineract/#checkstyle-and-spotless
-* https://github.com/apache/fineract/#logging-guidelines
-* https://github.com/apache/fineract/#error-handling-guidelines
+We expect most proposed PRs to typically consist of a single commit.
Committers may use _Squash and merge_ to combine your commits at merge time,
and if they do so, will rewrite your commit message as they see fit.
-Note also [our Code of Conduct](CODE_OF_CONDUCT.md).
+Neither of these two are hard absolute rules, but mere conventions. Multiple
commits in single PRs make sense in certain cases (e.g. branch backports).
diff --git a/README.md b/README.md
index 720dcb1ac6..d09075818c 100644
--- a/README.md
+++ b/README.md
@@ -1,80 +1,67 @@
-Apache Fineract: A Platform for Microfinance
-============
+# Apache Fineract
<!-- TODO Reactivate when there is a working CI-CD instance: [](https://validator.swagger.io/validator/debug?url=https://sandbox.mifos.community/fineract-provider/swagger-ui/fineract.yaml)
-->
[](https://github.com/apache/fineract/actions/workflows/build-mariadb.yml)
[](https://hub.docker.com/r/apache/fineract)
[](https://github.com/apache/fineract/actions/workflows/publish-dockerhub.yml)
[](https://sonarcloud.io/summary/new_code?id=apache_fineract)
-</b>
+Apache Fineract is an open-source core banking platform providing a
+flexible, extensible foundation for a wide range of financial services. By
+making robust banking technology openly available, it lowers barriers for
+institutions and innovators to reach underserved and unbanked populations.
-Fineract is a mature platform with open APIs that provides a reliable, robust,
and affordable core banking solution for financial institutions offering
services to the worldβs 3 billion underbanked and unbanked.
+Have a look at the [documentation](https://fineract.apache.org/docs/current),
the [wiki](https://cwiki.apache.org/confluence/display/FINERACT) or at the
[FAQ](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=91554327),
if this README does not answer what you are looking for.
-[Have a look at the FAQ on our Wiki at
apache.org](https://cwiki.apache.org/confluence/display/FINERACT/FAQ) if this
README does not answer what you are looking for. [Visit our JIRA
Dashboard](https://issues.apache.org/jira/secure/Dashboard.jspa?selectPageId=12335824)
to find issues to work on, see what others are working on, or open new issues.
COMMUNITY
=========
-If you are interested in contributing to this project, but perhaps don't quite
know how and where to get started, please [join our developer mailing
list](http://fineract.apache.org/#contribute), listen into our conversations,
chime into threads, and just send us a "Hello!" introduction email; we're a
friendly bunch, and look forward to hearing from you.
-
-
-REQUIREMENTS
-============
-* `Java >= 21` (Azul Zulu JVM is tested by our CI on GitHub Actions)
-* MariaDB `11.5.2`
-
-You can run the required version of the database server in a container,
instead of having to install it, like this:
-
- docker run --name mariadb-11.5 -p 3306:3306 -e MARIADB_ROOT_PASSWORD=mysql
-d mariadb:11.5.2
+If you are interested in contributing to this project, but perhaps don't quite
know how and where to get started, please [join our developer mailing
list](http://fineract.apache.org/#contribute), listen into our conversations,
chime into threads, or just send us a "Hello!" introduction email; we're a
friendly bunch, and look forward to hearing from you. A more informal
alternative is the [Fineract Slack
channel](https://app.slack.com/client/T0F5GHE8Y/C028634A61L) (thank you, Mifos,
for s [...]
-and stop and destroy it like this:
+For the developer wiki, see [Contributor's
Zone](https://cwiki.apache.org/confluence/display/FINERACT/Contributor%27s+Zone).
Maybe [these how-to
articles](https://cwiki.apache.org/confluence/display/FINERACT/How-to+articles)
help you to get started.
- docker rm -f mariadb-11.5
+In any case visit [our JIRA
Dashboard](https://issues.apache.org/jira/secure/Dashboard.jspa?selectPageId=12335824)
to find issues to work on, see what others are doing, or open new issues.
-<br>Beware that this database container database keeps its state inside the
container and not on the host filesystem. It is lost when you destroy (rm)
this container. This is typically fine for development. See [Caveats: Where
to Store Data on the database container
documentation](https://hub.docker.com/_/mariadb) re. how to make it persistent
instead of ephemeral.<br>
+In the moment you get started writing code, please consult our
[CONTRIBUTING](CONTRIBUTING.md) guidelines, where you will find more
information on subjects like coding style, testing and pull requests.
-Tomcat v10 is only required if you wish to deploy the Fineract WAR to a
separate external servlet container. Note that you do not require to install
Tomcat to develop Fineract, or to run it in production if you use the
self-contained JAR, which transparently embeds a servlet container using Spring
Boot. (Until FINERACT-730, Tomcat 7/8 were also supported, but now Tomcat 10
is required.)
-<br>IMPORTANT: If you use MySQL or MariaDB
+REQUIREMENTS
============
+* min. 16GB RAM and 8 core CPU
+* `MariaDB >= 11.5.2` or `PostgreSQL >= 17.0`
+* `Java >= 21` (Azul Zulu JVM is tested by our CI on GitHub Actions)
-Recently (after release `1.7.0`), we introduced improved date time handling in
Fineract. Date time is from now on stored in UTC and we are enforcing UTC
timezone even on the JDBC driver, e. g. for MySQL:
-
-```
-serverTimezone=UTC&useLegacyDatetimeCode=false&sessionVariables=time_zone=β-00:00β
-```
+Tomcat (min. v10) is only required, if you wish to deploy the Fineract WAR to
a separate external servlet container. You do not need to install Tomcat to
run Fineract. We recommend the use of the self-contained JAR, which
transparently embeds a servlet container using Spring Boot.
-__DO__: If you do use MySQL as your Fineract database then the following
configuration is highly recommended:
-* Run the application in UTC (the default command line in our Docker image has
the necessary parameters already set)
-* Run the MySQL database server in UTC (if you use managed services like AWS
RDS then this should be the default anyway, but it would be good to
double-check)
+SECURITY
+============
+If you believe you have found a security vulnerability, [let us know
privately](https://fineract.apache.org/#contribute).
-__DON'T__: In case the Fineract instance and the MySQL server are __not__
running in UTC then the following could happen:
+For details about security during development and deployment, see the
documentation [here](https://fineract.apache.org/docs/current/#_security).
-* MySQL is saving date time values differently from PostgreSQL
-* Example scenario: if the Fineract instance runs in timezone: GMT+2, and the
local date time is 2022-08-11 17:15 ...
-* ... then __PostgreSQL saves__ the LocalDateTime as is: __2022-08-11 17:15__
-* ... and __MySQL saves__ the LocalDateTime in UTC: __2022-08-11 15:15__
-* ... but when we __read__ the date time from PostgreSQL __or__ from MySQL,
then both systems give us the same values: __2022-08-11 17:15 GMT+2__
-If a previously used Fineract instance didn't run in UTC (backward
compatibility), then all prior dates will be read wrongly by MySQL/MariaDB.
This can cause issues when you run the database migration scripts.
+INSTRUCTIONS
+============
-__RECOMMENDATION__: you need to shift all dates in your database by the
timezone offset that your Fineract instance used.
+The following how-to's assume you have Java installed, you cloned the
repository (or downloaded and extracted a [specific
version](https://github.com/apache/fineract/releases)) and you have a [database
server](#database-and-tables) (MariaDB or PostgreSQL) running.
-<br>INSTRUCTIONS: How to run for local development
-============
+How to run for local development
+---
-Run the following commands:
-1. `./gradlew createDB -PdbName=fineract_tenants`
-1. `./gradlew createDB -PdbName=fineract_default`
-1. `./gradlew devRun`
+Run the following commands in this order:
+```bash
+./gradlew createDB -PdbName=fineract_tenants
+./gradlew createDB -PdbName=fineract_default
+./gradlew devRun
+```
-Fineract is now running, and will be listening for API requests on port 8443
by default.
+This creates two databases and builds and runs Fineract, which will be
listening for API requests on port 8443 (by default) now.
Confirm Fineract is ready with, for example:
```bash
-curl --insecure https://localhost:8443/fineract-provider/actuator/health`
+curl --insecure https://localhost:8443/fineract-provider/actuator/health
```
To test authenticated endpoints, include credentials in your request:
@@ -87,233 +74,102 @@ curl --location \
--header 'Authorization: Basic bWlmb3M6cGFzc3dvcmQ='
```
-<br>INSTRUCTIONS: How to build the JAR file
-============
-1. Clone the repository or download and extract the archive file to your local
directory.
-2. Run `./gradlew clean bootJar` to build a modern cloud native fully self
contained JAR file which will be created at `fineract-provider/build/libs`
directory.
-3. As we are not allowed to include a JDBC driver in the built JAR, download a
JDBC driver of your choice. For example: `wget
https://dlm.mariadb.com/4174416/Connectors/java/connector-java-3.5.2/mariadb-java-client-3.5.2.jar`
-4. Start the jar and pass the directory where you have downloaded the JDBC
driver as loader.path, for example: `java -Dloader.path=. -jar
fineract-provider/build/libs/fineract-provider.jar` (does not require external
Tomcat)
-
-The tenants database connection details are configured [via environment
variables (as with Docker
container)](#instructions-to-run-using-docker-and-docker-compose), e.g. like
this:
-
- export FINERACT_HIKARI_PASSWORD=verysecret
- ...
- java -jar fineract-provider.jar
-
-
-<br>SECURITY
-============
-If you believe you have found a security vulnerability, [let us know
privately](https://fineract.apache.org/#contribute).
-
-For details about security during development and deployment, see
<https://fineract.apache.org/docs/current/#_security>.
+How to run for production
+---
+Running Fineract to try it out is relatively easy. If you intend to use it in
a production environment, be aware that a proper deployment can be complex,
costly, and time-consuming. Considerations include: Security, privacy,
compliance, performance, service availability, backups, and more. The Fineract
project does not provide a comprehensive guide for deploying Fineract in
production. You might need skills in enterprise Java applications and more.
Alternatively, you could pay a vendor f [...]
-<br>INSTRUCTIONS: How to build a WAR file
-============
-1. Clone the repository or download and extract the archive file to your local
directory.
-2. Run `./gradlew :fineract-war:clean :fineract-war:war` to build a
traditional WAR file which will be created at `fineract-war/build/libs`
directory.
-3. Deploy this WAR to your Tomcat v10 Servlet Container.
-
-We recommend using the JAR instead of the WAR file deployment, because it's
much easier.
-
-Note that with the 1.4 release the tenants database pool configuration changed
from Tomcat DBCP in XML to an embedded Hikari, configured by environment
variables, see above.
-
-
-INSTRUCTIONS: How to run tests
-============
-
-Unit tests
-----------
-
-Here's how to run the set of relatviely fast and indepedent Fineract tests:
-
+How to build the JAR file
+---
+Build a modern, cloud native, fully self contained JAR file:
```bash
-./gradlew test -x :twofactor-tests:test -x :oauth2-tests:test -x
:integration-tests:test
+./gradlew clean bootJar
```
-
-This runs nearly 1,000 tests and completes in a few minutes on decent hardware.
-They shouldn't need any special servers/services running.
-
-Integration tests
------------------
-
-Running tests with external dependencies yourself is a multi-step process with
many moving parts.
-Sometimes there are arbitrary failures and the prerequisite setup can be
daunting.
-A full local integration test run (on a developer workstation) covering every
possible test using every external service and every supported relational
database engine could take an entire day, and that's assuming everything is
properly configured and runs as expected.
-
-Right now we depend on GitHub to know if "the build" is passing (it's actually
multiple builds).
-The authoritative source of truth for what commands/services/tests to run,
how, and when are the files in `.github/workflows/`.
-Output from runs based on those configuration files appears at
<https://github.com/apache/fineract/actions>.
-
-Incorrect default Java-related executables may cause test failures.
-To fix this on Debian and Ubuntu systems, run the following:
-
+The JAR will be created in the `fineract-provider/build/libs` directory.
+As we are not allowed to include a JDBC driver in the built JAR, download a
JDBC driver of your choice. For example:
```bash
-export JAVA_HOME=/usr/lib/jvm/zulu21
-sudo update-alternatives --set java $JAVA_HOME/bin/java
-sudo update-alternatives --set javac $JAVA_HOME/bin/javac
-sudo update-alternatives --set javadoc $JAVA_HOME/bin/javadoc
-```
-
-This would correct, for example, a [class file verson
error](https://en.wikipedia.org/wiki/Java_class_file#General_layout).
-You might see something like this if a Java 11 executable (class file format
version 56) was the system default, but the integration tests were using Java
21 (class file format version 65):
-
+wget
https://dlm.mariadb.com/4174416/Connectors/java/connector-java-3.5.2/mariadb-java-client-3.5.2.jar
```
-UnsupportedClassVersionError: com.example.package/ClassName has been compiled
by a more recent version of the Java Runtime (class file version 65.0), this
version of the Java Runtime only recognizes class file versions up to 55.0
+Start the JAR and specify the directory containing the JDBC driver using the
loader.path option, for example:
+```bash
+java -Dloader.path=. -jar fineract-provider/build/libs/fineract-provider.jar
```
+This does not require an external Tomcat.
-The GitHub builds are run in [short-lived virtual
machines](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners),
so locally reproducing the same may require additional effort, such as these
extra clean-up procedures:
-
+The tenants database connection details are configured [via environment
variables (as with Docker
container)](#instructions-to-run-using-docker-or-podman), e.g. like this:
```bash
-# Might fix `error: cannot find symbol` or other intermittent failures.
-# `doc` here is a placeholder for any task(s) you are trying to run.
-# π This is generally very safe to run between builds.
-./gradlew --refresh-dependencies doc
-
-# Destroy anything untracked by git.
-# β οΈ This may delete something important, e.g. a finely-tuned IDE
configuration.
-git clean --force -dx
-
-# Destroy various caches and configs.
-# β οΈ This may delete gibibytes of cached data, making the next build very slow.
-rm -rf ~/.gradle ~/.m2 /tmp/cargo*
-
-# Destroy any Java containers left running.
-# π This is generally very safe to run between builds.
-ps auxwww | grep [c]argo | awk '{ print $2 }' | xargs -r kill
+export FINERACT_HIKARI_PASSWORD=verysecret
+...
+java -jar fineract-provider.jar
```
-Integration test runs such as `./gradlew --no-daemon --console=plain test -x
:twofactor-tests:test -x :oauth2-test:test :fineract-e2e-tests-runner:test
-PdbType=postgresql` in `.github/workflows/build-postgresql.yml` often take an
hour or longer to complete.
-If you notice the `:integration-tests:test` task taking significantly less
time, say, one minute, gradle may be skipping it.
-Look for something like this in the test output:
-
-```
-> Task :integration-tests:test UP-TO-DATE π
-Custom actions are attached to task ':integration-tests:test'.
-Build cache key for task ':integration-tests:test' is
6aeeec3f58bf9703d4c100fbaa657f5c
-Skipping task ':integration-tests:test' as it is up-to-date.
-Resolve mutations for :integration-tests:cargoStopLocal (Thread[Execution
worker Thread 11,5,main]) started.
-:integration-tests:cargoStopLocal (Thread[Execution worker Thread 11,5,main])
started.
+How to build the WAR file
+---
+Build a traditional WAR file:
+```bash
+./gradlew :fineract-war:clean :fineract-war:war
```
+The WAR will be created in the `fineract-war/build/libs` directory. Afterwards
deploy the WAR to your Tomcat Servlet Container.
-(This is with the `--info` gradle argument with eyeballs added for emphasis)
-The `--rerun-tasks` gradle argument may help, or you can try destroying
`~/.gradle` and other clean-up procedures as indicated above then re-running
tests.
-This is useful for repeated test runs (say, for timing) when gradle would
otherwise assume a task is "up-to-date" and not re-run it.
-
-Testing within IDEs
------------------
-
-See the next section for testing in Eclipse.
-
-See <https://fineract-academy.com> for testing in IntelliJ.
-
-INSTRUCTIONS: How to run and debug in Eclipse IDE
-============
-
-It is possible to run Fineract in Eclipse IDE and also to debug Fineract using
Eclipse's debugging facilities.
-To do this, you need to create the Eclipse project files and import the
project into an Eclipse workspace:
-
-1. Create Eclipse project files into the Fineract project by running
`./gradlew cleanEclipse eclipse`
-2. Import the fineract-provider project into your Eclipse workspace
(File->Import->General->Existing Projects into Workspace, choose root directory
fineract/fineract-provider)
-3. Do a clean build of the project in Eclipse (Project->Clean...)
-3. Run / debug Fineract by right clicking on
org.apache.fineract.ServerApplication class and choosing Run As / Debug As ->
Java Application. All normal Eclipse debugging features (breakpoints,
watchpoints etc) should work as expected.
-
-If you change the project settings (dependencies etc) in Gradle, you should
redo step 1 and refresh the project in Eclipse.
-
-You can also use Eclipse Junit support to run tests in Eclipse (Run As->Junit
Test)
-
-Finally, modifying source code in Eclipse automatically triggers hot code
replace to a running instance, allowing you to immediately test your changes
+We recommend using the JAR instead of the WAR file deployment, because it's
much easier.
-INSTRUCTIONS: How to run using Docker and docker-compose
-===================================================
+How to run using Docker or Podman
+---
It is possible to do a 'one-touch' installation of Fineract using containers
(AKA "Docker").
-Fineract now packs the mifos community-app web UI in it's docker deploy.
-You can now run and test fineract with a GUI directly from the combined docker
builds.
-This includes the database running in a container.
+This includes the database running in the container.
-As Prerequisites, you must have `docker` and `docker-compose` installed on
your machine; see
-[Docker Install](https://docs.docker.com/install/) and
-[Docker Compose Install](https://docs.docker.com/compose/install/).
+As prerequisites, you must have `docker` and `docker-compose` installed on
your machine; see
+[Docker Install](https://docs.docker.com/install/) and [Docker Compose
Install](https://docs.docker.com/compose/install/).
Alternatively, you can also use [Podman](https://github.com/containers/libpod)
(e.g. via `dnf install podman-docker`), and [Podman
Compose](https://github.com/containers/podman-compose/)
(e.g. via `pip3 install podman-compose`) instead of Docker.
-Now to run a new Fineract instance you can simply:
-
-1. `git clone https://github.com/apache/fineract.git ; cd fineract`
-1. for windows, use `git clone https://github.com/apache/fineract.git --config
core.autocrlf=input ; cd fineract`
-1. `./gradlew :fineract-provider:jibDockerBuild -x test`
-1. install the Loki log driver with `docker plugin install
grafana/loki-docker-driver:latest --alias loki --grant-all-permissions`
-1. `docker compose -f docker-compose-development.yml up -d`
-1. fineract (back-end) is running at https://localhost:8443/fineract-provider/
-1. wait for https://localhost:8443/fineract-provider/actuator/health to return
`{"status":"UP"}`
-1. you must go to https://localhost:8443 and remember to accept the
self-signed SSL certificate of the API once in your browser, otherwise you get
a message that is rather misleading from the UI.
-1. community-app (UI) is running at
http://localhost:9090/?baseApiUrl=https://localhost:8443/fineract-provider&tenantIdentifier=default
-1. login using default _username_ `mifos` and _password_ `password`
+To run a new Fineract instance on Linux you can simply:
+```bash
+git clone https://github.com/apache/fineract.git
+cd fineract
+./gradlew :fineract-provider:jibDockerBuild -x test
+```
+On Windows, do this instead:
+```cmd
+git clone https://github.com/apache/fineract.git --config core.autocrlf=input
+cd fineract
+gradlew :fineract-provider:jibDockerBuild -x test
+```
+Install the Loki log driver and start:
+```bash
+docker plugin install grafana/loki-docker-driver:latest \
+ --alias loki --grant-all-permissions
+docker compose -f docker-compose-development.yml up -d
+```
+The Fineract (back-end) should be running at
https://localhost:8443/fineract-provider/ now.
+Wait for https://localhost:8443/fineract-provider/actuator/health to return
`{"status":"UP"}`.
+You must go to https://localhost:8443 and remember to accept the self-signed
SSL certificate of the API once in your browser.
-https://hub.docker.com/r/apache/fineract has a pre-built container image of
this project, built continuously.
+[Docker Hub](https://hub.docker.com/r/apache/fineract) has a pre-built
container image of this project, built continuously.
You must specify the MySQL tenants database JDBC URL by passing it to the
`fineract` container via environment
variables; please consult the [`docker-compose.yml`](docker-compose.yml) for
exact details how to specify those.
-_(Note that in previous versions, the `mysqlserver` environment variable used
at `docker build` time instead of at
-`docker run` time did something similar; this has changed in
[FINERACT-773](https://issues.apache.org/jira/browse/FINERACT-773)),
-and the `mysqlserver` environment variable is now no longer supported.)_
-The logfiles and the Java Flight Recorder output are available in
`PROJECT_ROOT/build/fineract/logs`. If you use IntelliJ then you can
double-click on the `.jfr` file and open it with the IDE. You can also download
Azul Mission Control from here
https://www.azul.com/products/components/azul-mission-control/ to analyze the
Java Flight Recorder file.
+The logfiles and the Java Flight Recorder output are available in
`PROJECT_ROOT/build/fineract/logs`. If you use IntelliJ then you can
double-click on the `.jfr` file and open it with the IDE. You can also download
[Azul Mission
Control](https://www.azul.com/products/components/azul-mission-control/) to
analyze the Java Flight Recorder file.
NOTE: If you have issues with the file permissions and Docker Compose then you
might need to change the variable values for `FINERACT_USER` and
`FINERACT_GROUP` in `PROJECT_ROOT/config/docker/env/fineract-common.env`. You
can find out what values you need to put there with the following commands:
-```
-id -u ${USER}
-id -u ${GROUP}
-```
-
-Please make sure that you are not checking in your changed values. The
defaults should normally work for most people.
-
-INSTRUCTIONS: How to build documentation
-===================================================
-
-Run the following command:
-
```bash
-./gradlew doc
+id -u ${USER}
+id -g ${GROUP}
```
-Some dependencies are required (e.g. Ghostscript, Graphviz), see
`.github/workflows/build-documentation.yml` for hints.
-
-Additionally, IDEs such as IntelliJ are useful for editing the AsciiDoc source
files while providing a live rendered preview.
-
-HTML rendered from the AsciiDoc source files is also available online at
<https://fineract.apache.org/docs/current/>.
-
-A release version is derived from source control. The version will include
`-SNAPSHOT` unless the current branch looks like a release or release
maintenance branch. See `gitVersioning` settings in `build.gradle` for details.
-
-Connection pool configuration
-=============================
-
-Please check `application.properties` to see which connection pool settings
can be tweaked. The associated environment variables are prefixed with
`FINERACT_HIKARI_*`. You can find more information about specific connection
pool settings (Hikari) at
https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby
-
-NOTE: we'll keep backwards compatibility until one of the next releases to
ensure that things are working as expected. Environment variables prefixed
`fineract_tenants_*` can still be used to configure the database connection,
but we strongly encourage using `FINERACT_HIKARI_*` with more options.
-
-<br>SSL CONFIGURATION
-=================
-
-See [the HTTPS related doc](https://fineract.apache.org/docs/current/#_https).
-
-
-<br>TOMCAT CONFIGURATION
-====================
+Please make sure that you are not checking in your changed values. The
defaults should work for most people.
-Please refer to the `application.properties` and the official Spring Boot
documentation
(https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html)
on how to do performance tuning for Tomcat. Note: you can set now the
acceptable form POST size (default is 2MB) via environment variable
`FINERACT_SERVER_TOMCAT_MAX_HTTP_FORM_POST_SIZE`.
+How to run on Kubernetes
+---
-<br>INSTRUCTIONS: How to run on Kubernetes
-=================================
-
-<br>General Clusters
-----------------
+### General Clusters
You can also run Fineract using containers on a Kubernetes cluster.
Make sure you set up and connect to your Kubernetes cluster.
@@ -321,72 +177,53 @@ You can follow
[this](https://cwiki.apache.org/confluence/display/FINERACT/Insta
Now e.g. from your Google Cloud shell, run the following commands:
-1. `git clone https://github.com/apache/fineract.git ; cd fineract/kubernetes`
-1. `./kubectl-startup.sh`
+```bash
+git clone https://github.com/apache/fineract.git
+cd fineract/kubernetes
+./kubectl-startup.sh
+```
To shutdown and reset your Cluster, run:
+```bash
+./kubectl-shutdown.sh
+```
- ./kubectl-shutdown.sh
-
-Using Minikube
---------------
+### Using Minikube
Alternatively, you can run fineract on a local kubernetes cluster using
[minikube](https://minikube.sigs.k8s.io/docs/).
-As Prerequisites, you must have `minikube` and `kubectl` installed on your
machine; see
+As prerequisite you must have `minikube` and `kubectl` installed on your
machine; see
[Minikube & Kubectl
install](https://kubernetes.io/docs/tasks/tools/install-minikube/).
-Now to run a new Fineract instance on Minikube you can simply:
+To run a new Fineract instance on Minikube you can simply:
-1. `git clone https://github.com/apache/fineract.git ; cd fineract/kubernetes`
-1. `minikube start`
-1. `./kubectl-startup.sh`
-1. `minikube service fineract-server --url --https`
-1. Fineract is now running at the printed URL (note HTTP), which you can check
e.g. using:
-
- http --verify=no --timeout 240 --check-status get $(minikube service
fineract-server --url --https)/fineract-provider/actuator/health
+```bash
+git clone https://github.com/apache/fineract.git
+cd fineract/kubernetes
+minikube start
+./kubectl-startup.sh
+minikube service fineract-server --url --https
+```
+Fineract is now running at the printed URL, which you can check e.g. using:
+```bash
+http --verify=no --timeout 240 --check-status get $(minikube service
fineract-server --url --https)/fineract-provider/actuator/health
+```
To check the status of your containers on your local minikube Kubernetes
cluster, run:
-
- minikube dashboard
-
+```bash
+minikube dashboard
+```
You can check Fineract logs using:
-
- kubectl logs deployment/fineract-server
-
-To shutdown and reset your cluster, run:
-
- ./kubectl-shutdown.sh
-
+```bash
+kubectl logs deployment/fineract-server
+```
To shutdown and reset your cluster, run:
-
- minikube ssh
-
- sudo rm -rf /mnt/data/
-
-We have [some open issues in JIRA with Kubernetes related enhancement
ideas](https://jira.apache.org/jira/browse/FINERACT-783?jql=labels%20%3D%20kubernetes%20AND%20project%20%3D%20%22Apache%20Fineract%22%20)
which you are welcome to contribute to.
-
-
-INSTRUCTIONS: How to download Gradle wrapper
-============
-The file gradle/wrapper/gradle-wrapper.jar binary is checked into this
projects Git source repository,
-but won't exist in your copy of the Fineract codebase if you downloaded a
released source archive from apache.org.
-In that case, you need to download it using the commands below:
-
- wget --no-check-certificate -P gradle/wrapper
https://github.com/apache/fineract/raw/develop/gradle/wrapper/gradle-wrapper.jar
-
-(or)
-
- curl --insecure -L
https://github.com/apache/fineract/raw/develop/gradle/wrapper/gradle-wrapper.jar
> gradle/wrapper/gradle-wrapper.jar
-
-
-INSTRUCTIONS: How to run Apache RAT (Release Audit Tool)
-============
-1. Extract the archive file to your local directory.
-2. Run `./gradlew rat`. A report will be generated under
build/reports/rat/rat-report.txt
+```bash
+./kubectl-shutdown.sh
+```
-INSTRUCTIONS: How to enable External Message Broker (ActiveMQ or Apache Kafka)
-============
+How to enable External Message Broker (ActiveMQ or Apache Kafka)
+---
There are two use-cases where external message broker is needed:
- External Business Events / Reliable Event Framework
@@ -394,10 +231,11 @@ There are two use-cases where external message broker is
needed:
External Events are business events, e.g.: `ClientCreated`, which might be
important for third party systems. Apache Fineract supports ActiveMQ (or other
JMS compliant brokers) and Apache Kafka endpoints for sending out Business
Events. By default, they are not emitted.
-In case of a large deployment with millions of accounts, the Close of Business
Day Spring Batch job may run several hours. In order to speed up this task,
remote partitioning of the job is supported. The Manager node partitions
(breaks up) the COB job into smaller pieces (sub tasks) which then can be
executed on multiple Worker nodes in parallel. The worker nodes are notified
either by ActiveMQ or Kafka regarding their new sub tasks.
-### Active MQ
+In case of a large deployment with millions of accounts, the Close of Business
Day Spring Batch job may run several hours. In order to speed up this task,
remote partitioning of the job is supported. The Manager node partitions breaks
up the COB job into smaller pieces (sub tasks), which then can be executed on
multiple Worker nodes in parallel. The worker nodes are notified either by
ActiveMQ or Kafka regarding their new sub tasks.
+
+### ActiveMQ
-JMS based messaging is disabled by default. In
`docker-compose-postgresql-activemq.yml` an example is shown where ActiveMQ is
enabled. In that configuration one Spring Batch Manager instance and two Spring
Batch Worker instances are created.
+JMS based messaging is disabled by default. In
`docker-compose-postgresql-activemq.yml` an example is shown, where ActiveMQ is
enabled. In that configuration one Spring Batch Manager instance and two Spring
Batch Worker instances are created.
Spring based events should be disabled and jms based event handling should be
enabled. Furthermore, proper broker JMS URL should be configured.
```
@@ -410,186 +248,88 @@ For additional ActiveMQ related configuration please
take a look to the `applica
### Kafka
-Kafka support also disabled by default. In
`docker-compose-postgresql-kafka.yml` an example is shown where self-hosted
Kafka is enabled for both External Events and Spring Batch Remote Job execution.
+Kafka support is also disabled by default. In
`docker-compose-postgresql-kafka.yml` an example is shown, where self-hosted
Kafka is enabled for both External Events and Spring Batch Remote Job execution.
-During the development Fineract was tested with PLAINTEXT Kafka brokers
without authentication and with AWS MSK using IAM authentication. The extra
[jar file](https://github.com/aws/aws-msk-iam-auth/releases) required for IAM
authentication is already added to the classpath.
+During the development Fineract was tested with PLAINTEXT Kafka brokers
without authentication and with AWS MSK using IAM authentication. The extra
[JAR file](https://github.com/aws/aws-msk-iam-auth/releases) required for IAM
authentication is already added to the classpath.
An example MSK setup can be found in `docker-compose-postgresql-kafka-msk.yml`.
-The full list of supported Kafka related properties are documented here:
https://fineract.apache.org/docs/current/
-
-Checkstyle and Spotless
-============
-
-This project enforces its code conventions using
[checkstyle.xml](config/checkstyle/checkstyle.xml) through Checkstyle and
[fineract-formatting-preferences.xml](config/fineract-formatting-preferences.xml)
through Spotless. They are configured to run automatically during the normal
Gradle build, and fail if there are any violations detected. You can run the
following command to automatically fix spotless violations:
+The full list of supported Kafka related properties is documented in the
[Fineract Platform documentation](https://fineract.apache.org/docs/current/).
- `./gradlew spotlessApply`
-Since some checks are present in both Checkstyle and Spotless, the same
command can help you fix some of the Checkstyle violations (but not all, other
Checkstyle violations need to fixed manually).
-
-You can also check for Spotless violations (only; but normally don't have to,
because the regular build full already includes this anyway):
-
- `./gradlew spotlessCheck`
-
-We recommend that you configure your favourite Java IDE to match those
conventions. For Eclipse, you can go to
-Window > Java > Code Style and import our
[config/fineractdev-formatter.xml](config/fineractdev-formatter.xml) under
formatter section and
[config/fineractdev-cleanup.xml](config/fineractdev-cleanup.xml) under Clean up
section. The same fineractdev-formatter.xml configuration file (that can be
used in Eclipse IDE) is also used by Spotless to both check for violations and
autoformat code on the CLI.
-You could also use Checkstyle directly in your IDE (but you don't neccesarily
have to, it may just be more convenient for you). For Eclipse, use
https://checkstyle.org/eclipse-cs/ and load our checkstyle.xml into it, for
IntelliJ you can use
[CheckStyle-IDEA](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea).
+DATABASE AND TABLES
+===================
+You can run the required version of the database server in a container,
instead of having to install it, like this:
-Code Coverage Reports
-============
+ docker run --name mariadb-11.5 -p 3306:3306 -e MARIADB_ROOT_PASSWORD=mysql
-d mariadb:11.5.2
-The project uses Jacoco to measure unit tests code coverage, to generate a
report run the following command:
+and stop and destroy it like this:
- `./gradlew clean build jacocoTestReport`
+ docker rm -f mariadb-11.5
-Generated reports can be found in build/code-coverage directory.
+Beware that this container database keeps its state inside the container and
not on the host filesystem. It is lost when you destroy (rm) this container.
This is typically fine for development. See [Caveats: Where to Store Data on
the database container documentation](https://hub.docker.com/_/mariadb)
regarding how to make it persistent instead of ephemeral.
-Versions
-============
+MySQL/MariaDB and UTC timezone
+---
+With release `1.8.0` we introduced improved date time handling in Fineract.
Date time is stored in UTC, and UTC timezone enforced even on the JDBC driver,
e. g. for MySQL:
-The latest stable release can be viewed on the develop branch: [Latest Release
on Develop](https://github.com/apache/fineract/tree/develop "Latest Release").
+```
+serverTimezone=UTC&useLegacyDatetimeCode=false&sessionVariables=time_zone='-00:00'
+```
-The progress of this project can be viewed here: [View change
log](https://github.com/apache/fineract/blob/develop/CHANGELOG.md "Latest
release change log")
+If you use MySQL as Fineract database, the following configuration is highly
recommended:
+* Run the application in UTC (the default command line in our Docker image has
the necessary parameters already set)
+* Run the MySQL database server in UTC (if you use managed services like AWS
RDS, then this should be the default anyway, but it would be good to
double-check)
-License
-============
+In case Fineract and MySQL do not run in UTC, MySQL might save date time
values differently from PostgreSQL
-This project is licensed under Apache License Version 2.0. See
<https://github.com/apache/fineract/blob/develop/APACHE_LICENSETEXT.md> for
reference.
+Example scenario: If the Fineract instance runs in timezone: GMT+2, and the
local date time is 2022-08-11 17:15 ...
+* ... then PostgreSQL saves the LocalDateTime as is: 2022-08-11 17:15
+* ... and MySQL saves the LocalDateTime in UTC: 2022-08-11 15:15
+* ... but when we read the date time from PostgreSQL or from MySQL, both
systems give us the same value: 2022-08-11 17:15 GMT+2
-The Connector/J JDBC Driver client library from MariaDB.org, which is licensed
under the LGPL,
-is used in development when running integration tests that use the Liquibase
library. That JDBC
-driver is however not included in and distributed with the Fineract product
and is not
-required to use the product.
-If you are developer and object to using the LGPL licensed Connector/J JDBC
driver,
-simply do not run the integration tests that use the Liquibase library and/or
use another JDBC driver.
-As discussed in [LEGAL-462](https://issues.apache.org/jira/browse/LEGAL-462),
this project therefore
-complies with the [Apache Software Foundation third-party license
policy](https://www.apache.org/legal/resolved.html).
+If a previously used Fineract instance didn't run in UTC (backward
compatibility), all prior dates will be read wrongly by MySQL. This can cause
issues, when you run the database migration scripts.
+Recommendation: Shift all dates in your database by the timezone offset that
your Fineract instance used.
-<br><br>APACHE FINERACT PLATFORM API
-============
-The API for Fineract is documented in
[apiLive.htm](fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm),
and the [apiLive.htm can be viewed on
fineract.apache.org](https://fineract.apache.org/docs/legacy/ "API
Documentation"). If you have your own Fineract instance running, you can find
this documentation under
[/fineract-provider/legacy-docs/apiLive.htm](https://localhost:8443/fineract-provider/legacy-docs/apiLive.htm).
+CONNECTION POOL CONFIGURATION
+=======
-The Swagger documentation (work in progress; see
[FINERACT-733](https://issues.apache.org/jira/browse/FINERACT-733)) can be
accessed under
[/fineract-provider/swagger-ui/index.html](https://localhost:8443/fineract-provider/swagger-ui/index.html)
and [live Swagger UI here on
Fineract.dev](https://sandbox.mifos.community/fineract-provider/swagger-ui/index.html).
+Please check `application.properties` to see which connection pool settings
can be tweaked. The associated environment variables are prefixed with
`FINERACT_HIKARI_*`. You can find more information about specific connection
pool settings at the [HikariCP Github
repository](https://github.com/brettwooldridge/HikariCP?tab=readme-ov-file#gear-configuration-knobs-baby).
-Apache Fineract supports client code generation using [Swagger
Codegen](https://github.com/swagger-api/swagger-codegen) based on the [OpenAPI
Specification](https://swagger.io/specification/). For more instructions on
how to generate the client code, check
[fineract-doc/src/docs/en/chapters/sdk/client.adoc](fineract-doc/src/docs/en/chapters/sdk/client.adoc).
+NOTE: We keep backwards compatibility until one of the next releases to ensure
that things are working as expected. Environment variables prefixed
`fineract_tenants_*` can still be used to configure the database connection,
but we strongly encourage using `FINERACT_HIKARI_*` with more options.
-<br>API CLIENTS (Web UIs, Mobile, etc.)
+VERSIONS
============
-* https://github.com/openMF/community-app/ is the "traditional" Reference
Client App Web UI for the API offered by this project
-* https://github.com/openMF/web-app is the next generation UI rewrite also
using this project's API
-* https://github.com/openMF/android-client is an Android Mobile App client for
this project's API
-* https://github.com/openMF has more related proejcts
-
+A release version is derived from source control. The version will include
`-SNAPSHOT` unless the current branch looks like a release or release
maintenance branch. See `gitVersioning` settings in `build.gradle` for details.
-<br>ONLINE DEMOS
-============
+The latest stable release can be viewed on the develop branch: [Latest Release
on Develop](https://github.com/apache/fineract/tree/develop "Latest Release").
-* [sandbox.mifos.community](https://sandbox.mifos.community) always runs the
latest version of this code
-* [demo.mifos.io](https://demo.mifos.io) A demo account is provided for users
to experience the functionality of the Community App. Users can use "mifos"
for USERNAME and "password" for PASSWORD (without quotation marks).
-* [Swagger-UI Demo video](https://www.youtube.com/watch?v=FlVd-0YAo6c) This is
a demo video for Swagger-UI documentation, more information
[here](https://github.com/apache/fineract#swagger-ui-documentation).
+The progress of this project can be viewed in the left hand navigation under
[this page of the
wiki](https://cwiki.apache.org/confluence/display/FINERACT/Fineract+Releases)
-<br>DEVELOPERS
+LICENSE
============
-Please see
<https://cwiki.apache.org/confluence/display/FINERACT/Contributor%27s+Zone> for
the developers wiki page.
-
-Please refer to
<https://cwiki.apache.org/confluence/display/FINERACT/Fineract+101> for the
first-time contribution to this project.
-
-Please see
<https://cwiki.apache.org/confluence/display/FINERACT/How-to+articles> for
technical details to get started.
-Please visit [our JIRA
Dashboard](https://issues.apache.org/jira/secure/Dashboard.jspa?selectPageId=12335824)
to find issues to work on, see what others are working on, or open new issues.
+This project is licensed under [Apache License Version
2.0](https://github.com/apache/fineract/blob/develop/APACHE_LICENSETEXT.md).
+The Connector/J JDBC Driver client library from
[MariaDB](https://www.mariadb.org) is licensed under the LGPL.
+The library is often used in development when running integration tests that
use the Liquibase library. That JDBC
+driver is however not distributed with the Fineract product and is not
required to use the product.
+If you are a developer and object to using the LGPL licensed Connector/J JDBC
driver,
+simply do not run the integration tests that use the Liquibase library and use
another JDBC driver.
+As discussed in [LEGAL-462](https://issues.apache.org/jira/browse/LEGAL-462),
this project therefore
+complies with the [Apache Software Foundation third-party license
policy](https://www.apache.org/legal/resolved.html).
-<br>VIDEO DEMONSTRATION
-============
-
-Apache Fineract / Mifos X Demo (November 2016) -
<https://www.youtube.com/watch?v=h61g9TptMBo>
-<br>SWAGGER UI DEMONSTRATION
+PLATFORM API
============
-We use Swagger-UI to generate and maintain our API documentation, you can see
the demo video [here](https://www.youtube.com/watch?v=FlVd-0YAo6c) or a live
version
-[here](https://sandbox.mifos.community/fineract-provider/swagger-ui/index.html).
If you interested to know more about Swagger-UI you can check their
[website](https://swagger.io/).
-
-<br>GOVERNANCE AND POLICIES
-=======================
+Fineract does not provide a UI, but provides an API. Running Fineract locally,
the Swagger documentation can be accessed under
`https://localhost:8443/fineract-provider/swagger-ui/index.html`. A live
version can be accessed via [this
Sandbox](https://sandbox.mifos.community/fineract-provider/swagger-ui/index.html)
(not hosted by us).
-[Becoming a
Committer](https://cwiki.apache.org/confluence/display/FINERACT/Becoming+a+Committer)
-documents the process through which you can become a committer in this project.
-
-
-<br>ERROR HANDLING GUIDELINES
-------------------
-* When catching exceptions, either rethrow them, or log them. Either way,
include the root cause by using `catch (SomeException e)` and then either
`throw AnotherException("..details..", e)` or `LOG.error("...context...", e)`.
-* Completely empty catch blocks are VERY suspicous! Are you sure that you
want to just "swallow" an exception? Really, 100% totally absolutely sure??
;-) Such "normal exceptions which just happen sometimes but are actually not
really errors" are almost always a bad idea, can be a performance issue, and
typically are an indication of another problem - e.g. the use of a wrong API
which throws an Exception for an expected condition, when really you would want
to use another API that inste [...]
-* In tests, you'll typically never catch exceptions, but just propagate them,
with `@Test void testXYZ() throws SomeException, AnotherException`..., so that
the test fails if the exception happens. Unless you actually really want to
test for the occurence of a problem - in that case, use [JUnit's
Assert.assertThrows()](https://github.com/junit-team/junit4/wiki/Exception-testing)
(but not `@Test(expected = SomeException.class)`).
-* Never catch `NullPointerException` & Co.
-
-<br>LOGGING GUIDELINES
-------------------
-* We use [SLF4J](http://www.slf4j.org) as our logging API.
-* Never, ever, use `System.out` and `System.err` or `printStackTrace()`
anywhere, but always `LOG.info()` or `LOG.error()` instead.
-* Use placeholder (`LOG.error("Could not... details: {}", something,
exception)`) and never String concatenation (`LOG.error("Could not... details:
" + something, exception)`)
-* Which Log Level is appropriate?
- * `LOG.error()` should be used to inform an "operator" running Fineract
who supervises error logs of an unexpected condition. This includes technical
problems with an external "environment" (e.g. can't reach a database), and
situations which are likely bugs which need to be fixed in the code. They do
NOT include e.g. validation errors for incoming API requests - that is signaled
through the API response - and does (should) not be logged as an error. (Note
that there is no _FATAL_ [...]
- * `LOG.warn()` should be using sparingly. Make up your mind if it's an
error (above) - or not!
- * `LOG.info()` can be used notably for one-time actions taken during
start-up. It should typically NOT be used to print out "regular" application
usage information. The default logging configuration always outputs the
application INFO logs, and in production under load, there's really no point to
constantly spew out lots of information from frequently traversed paths in the
code about what's going on. (Metrics are a better way.) `LOG.info()` *can* be
used freely in tests though.
- * `LOG.debug()` can be used anywhere in the code to log things that may be
useful during investigations of specific problems. They are not shown in the
default logging configuration, but can be enabled for troubleshooting.
Developers should typically "turn down" most `LOG.info()` which they used while
writing a new feature to "follow along what happens during local testing" to
`LOG.debug()` for production before we merge their PRs.
- * `LOG.trace()` is not used in Fineract.
-
-Pull Requests
--------------
-
-We request that your commit message include a FINERACT JIRA issue, and a
one-liner that describe the changes.
-Start with an upper case imperative verb (not past form), and a short but
concise clear description. (E.g. "FINERACT-821: Add enforced
HideUtilityClassConstructor checkstyle").
-
-If your PR is failing to pass our CI build due to a test failure, then:
-
-1. Understand if the failure is due to your PR or an unrelated unstable test.
-1. If you suspect it is because of a "flaky" test, and not due to a change in
your PR, then please do not simply wait for an active maintainer to come and
help you, but instead be a proactive contributor to the project - see next
steps. Do understand that we may not review PRs that are not green - it is the
contributor's (that's you!) responsability to get a proposed PR to pass the
build, not primarily the maintainers.
-1. Search for the name of the failed test on https://issues.apache.org/jira/,
e.g. for `AccountingScenarioIntegrationTest` you would find
[FINERACT-899](https://issues.apache.org/jira/browse/FINERACT-899).
-1. If you happen to read in such bugs that tests were just recently fixed, or
ignored, then rebase your PR to pick up that change.
-1. If you find previous comments "proving" that the same test has arbitrarily
failed in at least 3 past PRs, then please do yourself raise a small separate
new PR proposing to add an `@Disabled // TODO FINERACT-123` to the respective
unstable test (e.g. [#774](https://github.com/apache/fineract/pull/774)) with
the commit message mentioning said JIRA, as always. (Please do NOT just
`@Disabled` any existing tests mixed in as part of your larger PR.)
-1. If there is no existing JIRA for the test, then first please evaluate
whether the failure couldn't be a (perhaps strange) impact of the change you
are proposing after all. If it's not, then please raise a new JIRA to document
the suspected Flaky Test, and link it to
[FINERACT-850](https://issues.apache.org/jira/browse/FINERACT-850). This will
allow the next person coming along hitting the same test failure to easily find
it, and eventually propose to ignore the unstable test.
-1. Then (only) Close and Reopen your PR, which will cause a new build, to see
if it passes.
-1. Of course, we very much appreciate you then jumping onto any such bugs and
helping us figure out how to fix all ignored tests!
-
-[Pull Request Size
Limit](https://cwiki.apache.org/confluence/display/FINERACT/Pull+Request+Size+Limit)
-documents that we cannot accept huge "code dump" Pull Requests, with some
related suggestions.
-
-Guideline for new Feature commits involving Refactoring: If you are submitting
PR for a new Feature,
-and it involves refactoring, try to differentiate "new Feature code" with
"Refactored" by placing
-them in different commits. This helps review to review your code faster.
-
-We have an automated Bot which marks pull requests as "stale" after a while,
and ultimately automatically closes them.
-
-
-Merge Strategy
---------------
-
-This project's committers typically prefer to bring your Pull Requests in
through _Rebase and Merge_ instead of _Create a Merge Commit_. (If you are
unfamiliar with GitHub's UI re. this, note the somewhat hidden little triangle
drop-down at the bottom of PR, visible only to committers, not contributors.)
This avoids the "merge commits" which we consider to be somewhat "polluting"
the projects commits log history view. We understand this doesn't give an easy
automatic reference to the o [...]
-
-We expect most proposed PRs to typically consist of a single commit.
Committers may use _Squash and merge_ to combine your commits at merge time,
and if they do so will rewrite your commit message as they see fit.
-
-Neither of these two are hard absolute rules, but mere conventions. Multiple
commits in single PR make sense in certain cases (e.g. branch backports).
-
-
-Dependency Upgrades
--------------------
-
-This project uses a number of 3rd-party libraries, and this section provides
some guidance for their updates. We have set-up [Renovate's
bot](https://renovate.whitesourcesoftware.com) to automatically raise Pull
Requests for our review when new dependencies are available
[FINERACT-962](https://issues.apache.org/jira/browse/FINERACT-962).
-
-Upgrades sometimes require package name changes. Changed code should ideally
have test coverage.
-
-Our `ClasspathHellDuplicatesCheckRuleTest` detects classes that appear in more
than 1 JAR. If a version bump in
[`build.gradle`](https://github.com/search?q=repo%3Aapache%2Ffineract+filename%3Abuild.gradle&type=Code&ref=advsearch&l=&l=)
causes changes in transitives dependencies, then you may have to add related
`exclude` to our
[`dependencies.gradle`](https://github.com/apache/fineract/search?q=dependencies.gradle).
Running `./gradlew dependencies` helps to understand what is required.
-
-
-More Information
-============
-More details of the project can be found at
<https://cwiki.apache.org/confluence/display/FINERACT>.
+Apache Fineract supports client code generation using [Swagger
Codegen](https://github.com/swagger-api/swagger-codegen) based on the [OpenAPI
Specification](https://swagger.io/specification/). For more instructions on how
to generate client code, check [this
section](https://fineract.apache.org/docs/current/#_generate_api_client) of the
Fineract documentation. [This
video](https://www.youtube.com/watch?v=FlVd-0YAo6c) documents the use of the
Swagger-UI.