Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Steve Conrad
2019-10-02 14:56:16 -04:00
28 changed files with 680 additions and 250 deletions
+29
View File
@@ -0,0 +1,29 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
build/*
.gradle/*
# Incremental "docker build" is faster if we can modify the Dockerfile
# without "COPY ." re-transferring everything into the builder container.
Dockerfile
# https://github.com/containers/buildah/issues/1582
.git/*
.git/*/*
.git/*/*/*
.git/*/*/*/*
+42
View File
@@ -0,0 +1,42 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# https://www.gitpod.io
# https://www.gitpod.io/docs/41_Config_Gitpod_File/
# https://github.com/gitpod-io/workspace-images/tree/master/mysql
image: gitpod/workspace-mysql
ports:
- port: 3306
onOpen: ignore
- port: 8005
onOpen: ignore
- port: 8009
onOpen: ignore
- port: 8080
- port: 8081
onOpen: ignore
- port: 8443
tasks:
- command: |
# NB MySQL on GitPod.io is currently quite slow.
# similar to .travis.yml, but using authentication_string= instead of password= due to mysql major version difference
mysql -e "USE mysql;\nUPDATE user SET authentication_string=PASSWORD('mysql') WHERE user='root';\nFLUSH PRIVILEGES;\n"
./gradlew createDB -PdbName=mifosplatform-tenants
./gradlew createDB -PdbName=mifostenant-default
./gradlew build -x test
+4 -5
View File
@@ -27,14 +27,12 @@ jdk:
services: services:
- mysql - mysql
# Hardcoding system time as a temporary fix for running buggy test cases
before_install: before_install:
- echo "USE mysql;\nUPDATE user SET password=PASSWORD('mysql') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root - echo "USE mysql;\nUPDATE user SET password=PASSWORD('mysql') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root
- mysql -u root -pmysql -e 'CREATE DATABASE IF NOT EXISTS `mifosplatform-tenants`;' - mysql -u root -pmysql -e 'CREATE DATABASE IF NOT EXISTS `mifosplatform-tenants`;'
- mysql -u root -pmysql -e 'CREATE DATABASE IF NOT EXISTS `mifostenant-default`;' - mysql -u root -pmysql -e 'CREATE DATABASE IF NOT EXISTS `mifostenant-default`;'
# Hardcoding the time zone is a temporary fix for https://issues.apache.org/jira/browse/FINERACT-723
- export TZ=Asia/Kolkata - export TZ=Asia/Kolkata
- sudo service ntp stop
- sudo date --set="23 February 2019 01:02:03"
# https://docs.travis-ci.com/user/languages/java/#caching # https://docs.travis-ci.com/user/languages/java/#caching
before_cache: before_cache:
@@ -53,5 +51,6 @@ cache:
# https://jira.apache.org/jira/browse/FINERACT-732 removed that again, because it made Travis CI fail. # https://jira.apache.org/jira/browse/FINERACT-732 removed that again, because it made Travis CI fail.
script: script:
- date - date
- ./gradlew --console=plain licenseMain licenseTest licenseIntegrationTest test - ./gradlew --console=plain licenseMain licenseTest licenseIntegrationTest test && ./gradlew --console=plain integrationTest
- ./gradlew --console=plain clean integrationTest # using "&&" instead of x2 "-" means that integrationTest does not run if test fails, which makes sense.
# @see https://docs.travis-ci.com/user/job-lifecycle/#customizing-the-build-phase
+15 -11
View File
@@ -15,25 +15,29 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
FROM openjdk:8 AS builder
FROM bitnami/tomcat:7.0.94 as fineract
USER root
RUN apt-get update -qq && apt-get install -y git openjdk-8-jdk wget
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
RUN mkdir fineract RUN mkdir fineract
COPY . fineract COPY . fineract
WORKDIR fineract WORKDIR fineract
RUN sed -i 's/localhost/fineractmysql/' ./fineract-provider/build.gradle ARG mysqlserver=fineractmysql
RUN sed -i 's/localhost/fineractmysql/' ./fineract-provider/src/main/resources/sql/migrations/list_db/V1__mifos-platform-shared-tenants.sql RUN sed -i "s/localhost/${mysqlserver}/" ./fineract-provider/src/main/resources/sql/migrations/list_db/V1__mifos-platform-shared-tenants.sql
RUN ./gradlew clean war RUN ./gradlew clean war
RUN mv build/libs/fineract-provider.war /opt/bitnami/tomcat/webapps
FROM bitnami/tomcat:7.0.94 as fineract
USER root
ARG mysqlserver=fineractmysql
RUN apt-get update -qq && apt-get install -y wget
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
COPY --from=builder /fineract/build/libs/fineract-provider.war /opt/bitnami/tomcat/webapps
RUN keytool -genkey -keyalg RSA -alias tomcat -keystore /opt/bitnami/tomcat/tomcat.keystore -keypass xyz123 -storepass xyz123 -noprompt -dname "CN=Fineract, OU=Fineract, O=Fineract, L=Unknown, ST=Unknown, C=Unknown" RUN keytool -genkey -keyalg RSA -alias tomcat -keystore /opt/bitnami/tomcat/tomcat.keystore -keypass xyz123 -storepass xyz123 -noprompt -dname "CN=Fineract, OU=Fineract, O=Fineract, L=Unknown, ST=Unknown, C=Unknown"
COPY ./docker/server.xml /opt/bitnami/tomcat/conf COPY ./docker/server.xml /opt/bitnami/tomcat/conf
RUN sed -i "s/fineractmysql/${mysqlserver}/" /opt/bitnami/tomcat/conf/server.xml
RUN chmod 664 /opt/bitnami/tomcat/conf/server.xml RUN chmod 664 /opt/bitnami/tomcat/conf/server.xml
WORKDIR /opt/bitnami/tomcat/lib WORKDIR /opt/bitnami/tomcat/lib
RUN wget http://central.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/1.3/drizzle-jdbc-1.3.jar RUN wget http://central.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/1.4/drizzle-jdbc-1.4.jar
+51 -13
View File
@@ -1,7 +1,16 @@
Apache Fineract: A Platform for Microfinance [![Build Status](https://travis-ci.org/apache/fineract.svg?branch=develop)](https://travis-ci.org/apache/fineract) Apache Fineract: A Platform for Microfinance [![Build Status](https://travis-ci.org/apache/fineract.svg?branch=develop)](https://travis-ci.org/apache/fineract) [![Docker Hub](https://img.shields.io/docker/pulls/apache/fineract.svg)](https://hub.docker.com/r/apache/fineract) [![Docker Build](https://img.shields.io/docker/cloud/build/apache/fineract.svg)](https://hub.docker.com/r/apache/fineract/builds)
============ ============
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 2 billion underbanked and unbanked. 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 2 billion underbanked and unbanked.
[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.
[![Code Now! (Gitpod)](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/apache/fineract)
to start contributing to this project in the online web-based IDE GitPod.io right away!
(You may initially have to press F1 to Find Command and run "Java: Start Language Server".)
It's of course also possible to contribute with a "traditional" loca ldevelopment environment (see below).
Requirements Requirements
============ ============
* Java >= 1.8 (Oracle JVMs have been tested) * Java >= 1.8 (Oracle JVMs have been tested)
@@ -17,24 +26,36 @@ and stop and destroy it like this:
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/_/mysql) re. how to make it persistant instead of ephemeral. 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/_/mysql) re. how to make it persistant instead of ephemeral.
Instructions how to run for local development
============
Run the following commands:
1. `./gradlew createDB -PdbName=mifosplatform-tenants`
1. `./gradlew createDB -PdbName=mifostenant-default`
1. `./gradlew tomcatRunWAR`
Instructions to download gradle wrapper Instructions to download gradle wrapper
============ ============
The file fineract-provider/gradle/wrapper/gradle-wrapper.jar binary is checked into this projects's Git source repository, The file fineract-provider/gradle/wrapper/gradle-wrapper.jar binary is checked into this projects's Git source repository,
but won't exist in your copy of the Fineract codebase if you downloaded a released source archive from apache.org. 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 downloaded it using the commands below: In that case, you need to downloaded it using the commands below:
wget --no-check-certificate -P fineract-provider/gradle/wrapper https://github.com/apache/fineract/raw/develop/fineract-provider/gradle/wrapper/gradle-wrapper.jar wget --no-check-certificate -P fineract-provider/gradle/wrapper https://github.com/apache/fineract/raw/develop/fineract-provider/gradle/wrapper/gradle-wrapper.jar
(or) (or)
curl --insecure -L https://github.com/apache/fineract/raw/develop/fineract-provider/gradle/wrapper/gradle-wrapper.jar > fineract-provider/gradle/wrapper/gradle-wrapper.jar curl --insecure -L https://github.com/apache/fineract/raw/develop/fineract-provider/gradle/wrapper/gradle-wrapper.jar > fineract-provider/gradle/wrapper/gradle-wrapper.jar
Instructions to run Apache RAT (Release Audit Tool) Instructions to run Apache RAT (Release Audit Tool)
============ ============
1. Extract the archive file to your local directory. 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 2. Run `./gradlew rat`. A report will be generated under build/reports/rat/rat-report.txt
Instructions to build a war file
Instructions to build a WAR file
============ ============
1. Extract the archive file to your local directory. 1. Extract the archive file to your local directory.
2. Run `./gradlew clean war` or `./gradlew build` to build deployable war file which will be created at build/libs directory. 2. Run `./gradlew clean war` or `./gradlew build` to build deployable war file which will be created at build/libs directory.
@@ -53,19 +74,30 @@ Run the following commands, very similarly to how [.travis.yml](.travis.yml) doe
Instructions to run using Docker and docker-compose Instructions to run using Docker and docker-compose
=================================================== ===================================================
It is possible to do a 'one-touch' installation of Fineract using docker-compose It is possible to do a 'one-touch' installation of Fineract using docker-compose:
Prerequisites: Prerequisites:
* docker and docker-compose installed on your machine * docker and docker-compose installed on your machine
Installing a new Fineract instance:
Installing a new Fineract instance: * Clone the Fineract Github repository
* Run the following commands:
* docker-compose build
* docker-compose up -d
* Fineract will run at https://localhost:8443/fineract-provider
* Clone the Fineract Github repository The [`docker-compose.yml`](docker-compose.yml) will build the `fineract` container from source.
* Run the following commands:
* docker-compose build https://hub.docker.com/r/apache/fineract has a pre-built container of this project, built continously.
* docker-compose up -d
* Fineract will run at https://localhost:8443/fineract-provider You can use a MySQL database from a different or remote server by passing the server's IP address to the docker finerect buid process like this:
docker build --build-arg mysqlserver=<MySQL server IP> -t fineract:latest .
The run it:
docker run -d fineract:latest
Version Version
@@ -75,6 +107,7 @@ The latest stable release can be viewed on the develop branch: [Latest Release o
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") 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")
License License
============ ============
@@ -95,12 +128,14 @@ Apache Fineract Platform API
The API for the Fineract-platform (project named 'Apache Fineract') is documented in the API-docs under <b><i>Full API Matrix</i></b> and can be viewed [here](https://demo.openmf.org/api-docs/apiLive.htm "API Documentation"). The API for the Fineract-platform (project named 'Apache Fineract') is documented in the API-docs under <b><i>Full API Matrix</i></b> and can be viewed [here](https://demo.openmf.org/api-docs/apiLive.htm "API Documentation").
Online Demos Online Demos
============ ============
* [Community App](https://demo.openmf.org "Reference Client App") * [Community App](https://demo.openmf.org "Reference Client App")
> For this demo, a demo account is also provided for users to experience the functionality of this Community App. Users can use "mifos" for USERNAME and "password" for PASSWORD(without quotation marks). > For this demo, a demo account is also provided for users to experience the functionality of this Community App. Users can use "mifos" for USERNAME and "password" for PASSWORD(without quotation marks).
Developers Developers
============ ============
Please see <https://cwiki.apache.org/confluence/display/FINERACT/Contributor%27s+Zone> for the developers wiki page. Please see <https://cwiki.apache.org/confluence/display/FINERACT/Contributor%27s+Zone> for the developers wiki page.
@@ -115,11 +150,13 @@ Roadmap
[Project Release Roadmap on JIRA (Detailed View)](https://issues.apache.org/jira/browse/FINERACT-268?jql=project%20%3D%20FINERACT "Project Release Roadmap on JIRA (Detailed View)") [Project Release Roadmap on JIRA (Detailed View)](https://issues.apache.org/jira/browse/FINERACT-268?jql=project%20%3D%20FINERACT "Project Release Roadmap on JIRA (Detailed View)")
Video Demonstration Video Demonstration
============ ============
Apache Fineract / Mifos X Demo (November 2016) - <https://www.youtube.com/watch?v=h61g9TptMBo> Apache Fineract / Mifos X Demo (November 2016) - <https://www.youtube.com/watch?v=h61g9TptMBo>
Governance and Policies Governance and Policies
======================= =======================
@@ -129,6 +166,7 @@ documents the process through which you can become a committer in this project.
[Pull Request Size Limit](https://cwiki.apache.org/confluence/display/FINERACT/Pull+Request+Size+Limit) [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. documents that we cannot accept huge "code dump" Pull Requests, with some related suggestions.
More Information More Information
============ ============
More details of the project can be found at <https://cwiki.apache.org/confluence/display/FINERACT>. More details of the project can be found at <https://cwiki.apache.org/confluence/display/FINERACT>.
@@ -1,3 +0,0 @@
Manifest-Version: 1.0
Class-Path:
+72 -168
View File
@@ -20,7 +20,17 @@ description = '''\
Run as: Run as:
gradle clean tomcatrunwar gradle clean tomcatrunwar
''' '''
project.ext.springBootVersion = '1.2.8.RELEASE'
project.ext.springVersion = '4.1.9.RELEASE'
project.ext.springOauthVersion = '2.0.4.RELEASE'
project.ext.jerseyVersion = '1.17'
project.ext.springDataJpaVersion = '1.7.0.RELEASE' // also change spring-boot-gradle-plugin version below
buildscript { buildscript {
ext {
openJPAVersion = '2.4.3'
}
repositories { repositories {
jcenter() jcenter()
mavenCentral() mavenCentral()
@@ -28,12 +38,12 @@ buildscript {
} }
dependencies { dependencies {
classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:1.0', classpath 'com.bmuschko:gradle-tomcat-plugin:2.5',
'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0', 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0',
'org.zeroturnaround:gradle-jrebel-plugin:1.1.2', 'org.zeroturnaround:gradle-jrebel-plugin:1.1.2',
'org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE' // also change springDataJpaVersion below 'org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE' // also change springDataJpaVersion below
classpath 'org.apache.openjpa:openjpa-all:2.4.1' classpath "org.apache.openjpa:openjpa:$openJPAVersion"
classpath 'at.schmutterer.oss.gradle:gradle-openjpa:0.2.0' classpath 'com.radcortez.gradle:openjpa-gradle-plugin:3.0.0'
classpath 'gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.2.2' classpath 'gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.2.2'
} }
} }
@@ -42,44 +52,36 @@ apply plugin: "org.nosphere.apache.rat"
apply plugin: 'rebel' apply plugin: 'rebel'
apply plugin: 'license' apply plugin: 'license'
apply plugin: 'war' apply plugin: 'war'
apply plugin: 'spring-boot' apply plugin: 'org.springframework.boot'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'tomcat' apply plugin: 'com.bmuschko.tomcat'
apply plugin: 'project-report' apply plugin: 'project-report'
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'openjpa' apply plugin: 'openjpa'
apply plugin: 'pmd' // apply plugin: 'pmd'
apply plugin: 'findbugs' // apply plugin: 'findbugs'
/* define the valid syntax level for source files */ /* define the valid syntax level for source files */
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
/* define binary compatibility version */ /* define binary compatibility version */
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
project.ext.springBootVersion = '1.2.8.RELEASE'
project.ext.springVersion = '4.1.9.RELEASE'
project.ext.springOauthVersion = '2.0.4.RELEASE'
project.ext.jerseyVersion = '1.17'
project.ext.springDataJpaVersion = '1.7.0.RELEASE' // also change spring-boot-gradle-plugin version above
project.ext.mysqlUser='root' project.ext.mysqlUser='root'
project.ext.mysqlPassword='mysql' project.ext.mysqlPassword='mysql'
group = 'org.apache.fineract' group = 'org.apache.fineract'
buildDir = new File(rootProject.projectDir, "../build") buildDir = new File(rootProject.projectDir, "../build")
repositories { repositories {
jcenter() jcenter()
// mavenLocal() // useful for local dev using MariaDB4j SNAPSHOTs (not needed for real-world non-SNAPHOT builds) // mavenLocal() // useful for local dev using MariaDB4j SNAPSHOTs (not needed for real-world non-SNAPHOT builds)
} }
openjpa {
files = fileTree(sourceSets.main.output.classesDir).matching {
include '**/AbstractPersistableCustom.class'
include '**/domain/*.class'
openjpa {
includes = ['**/AbstractPersistableCustom.class', '**/domain/*.class']
enhance {
enforcePropertyRestrictions true
} }
enforcePropertyRestrictions = true
} }
rat { rat {
@@ -175,9 +177,6 @@ configurations {
exclude module: 'bcmail-jdk14' exclude module: 'bcmail-jdk14'
exclude module: 'bcprov-jdk14' exclude module: 'bcprov-jdk14'
exclude module: 'bctsp-jdk14' exclude module: 'bctsp-jdk14'
exclude module: 'bval-core'
exclude module: 'org.apache.bval.bundle'
exclude module: 'bval-jsr303'
exclude module: 'c3p0' exclude module: 'c3p0'
exclude module: 'stax-api' exclude module: 'stax-api'
exclude module: 'jaxb-api' exclude module: 'jaxb-api'
@@ -185,12 +184,10 @@ configurations {
exclude module: 'jboss-logging' exclude module: 'jboss-logging'
exclude module: 'itext-rtf' exclude module: 'itext-rtf'
exclude module: 'classworlds' exclude module: 'classworlds'
exclude module: 'jcl-over-slf4j'
exclude module: 'jul-to-slf4j'
exclude module: 'serp'
} }
runtime runtime
all*.exclude group: 'commons-logging' all*.exclude group: 'commons-logging'
all*.exclude module: 'jul-to-slf4j' // see FINERACT-700 re. ClassCircularityError: java/util/logging/LogRecord
} }
/* Pick up dependencies based on the environemnt, defaults to production */ /* Pick up dependencies based on the environemnt, defaults to production */
if (project.hasProperty('env') && project.getProperty('env') == 'dev') { if (project.hasProperty('env') && project.getProperty('env') == 'dev') {
@@ -270,6 +267,7 @@ task dist(type:Zip){
compileJava{ compileJava{
dependsOn rat dependsOn rat
} }
/*
pmd { pmd {
sourceSets = [sourceSets.main] sourceSets = [sourceSets.main]
ignoreFailures = true ignoreFailures = true
@@ -278,6 +276,7 @@ findbugs {
ignoreFailures = true ignoreFailures = true
sourceSets = [sourceSets.main] sourceSets = [sourceSets.main]
} }
*/
war { war {
from('../licenses/binary/') { // notice the parens from('../licenses/binary/') { // notice the parens
@@ -295,7 +294,7 @@ war {
from('../DISCLAIMER') { // notice the parens from('../DISCLAIMER') { // notice the parens
into "WEB-INF/" // no leading slash into "WEB-INF/" // no leading slash
} }
war.finalizedBy(bootRepackage) war.finalizedBy(bootWar)
} }
license { license {
@@ -329,9 +328,26 @@ tomcatRunWar {
configFile = file('src/test/resources/META-INF/context.xml') configFile = file('src/test/resources/META-INF/context.xml')
} }
task tomcatRunWarAsDaemonForIntegrationTest(type: com.bmuschko.gradle.tomcat.tasks.TomcatRunWar) {
httpPort = 8080
httpsPort = 8443
stopPort = 8081
stopKey= 'stopKey'
enableSSL = true
keystoreFile = file('src/main/resources/keystore.jks')
keystorePass = 'openmf'
configFile = file('src/test/resources/META-INF/context.xml')
daemon = true
}
task tomcatStopAfterIntegrationTest(type: com.bmuschko.gradle.tomcat.tasks.TomcatStop) {
stopPort = 8081
stopKey = 'stopKey'
}
/* http://stackoverflow.com/questions/19653311/jpa-repository-works-in-idea-and-production-but-not-in-gradle */ /* http://stackoverflow.com/questions/19653311/jpa-repository-works-in-idea-and-production-but-not-in-gradle */
sourceSets.main.output.resourcesDir = sourceSets.main.output.classesDir sourceSets.main.output.resourcesDir = sourceSets.main.java.outputDir
sourceSets.test.output.resourcesDir = sourceSets.test.output.classesDir sourceSets.test.output.resourcesDir = sourceSets.test.java.outputDir
/* Exclude maria db and embedded tomcat related files for non dev builds */ /* Exclude maria db and embedded tomcat related files for non dev builds */
if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) { if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) {
@@ -363,14 +379,14 @@ configurations {
integrationTestRuntime.extendsFrom testRuntime integrationTestRuntime.extendsFrom testRuntime
} }
task integrationTest(type:Test){ task integrationTest(type:Test) {
description = "Run integration tests (located in src/integrationTest/java). Starts tomcat in daemon mode before executing the tests." description = "Run integration tests (located in src/integrationTest/java). Starts Tomcat in daemon mode before executing the tests (and stops it after)."
it.dependsOn war dependsOn war
doFirst { dependsOn tomcatRunWarAsDaemonForIntegrationTest
tomcatRunWar.daemon = true tasks.findByName('tomcatRunWarAsDaemonForIntegrationTest').mustRunAfter 'war'
tomcatRunWar.execute() finalizedBy tomcatStopAfterIntegrationTest
}
testClassesDir = project.sourceSets.integrationTest.output.classesDir testClassesDirs = project.sourceSets.integrationTest.output.classesDirs
classpath = project.sourceSets.integrationTest.runtimeClasspath classpath = project.sourceSets.integrationTest.runtimeClasspath
} }
@@ -384,14 +400,7 @@ configurations {
driver driver
} }
dependencies { dependencies {
driver 'org.drizzle.jdbc:drizzle-jdbc:1.3' driver 'org.drizzle.jdbc:drizzle-jdbc:1.4'
}
test {
filter {
//includeTestsMatching "org.apache.fineract.infrastructure.configuration.spring.SpringConfigurationTest.*"
includeTestsMatching "org.apache.fineract.template.TemplateMergeServiceTest.*"
}
} }
URLClassLoader loader = GroovyObject.class.classLoader URLClassLoader loader = GroovyObject.class.classLoader
@@ -399,135 +408,30 @@ configurations.driver.each {File file ->
loader.addURL(file.toURL()) loader.addURL(file.toURL())
} }
task createDB<<{ task createDB {
description= "Creates the Database. Needs database name to be passed (like: -PdbName=someDBname)" description= "Creates the Database. Needs database name to be passed (like: -PdbName=someDBname)"
def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' ) doLast {
sql.execute( 'create database '+"`$dbName`" ) def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
sql.execute( 'create database '+"`$dbName`" )
}
} }
task dropDB<<{ task dropDB {
description= "Drops the specified database. The database name has to be passed (like: -PdbName=someDBname)" description= "Drops the specified database. The database name has to be passed (like: -PdbName=someDBname)"
def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' ) doLast {
sql.execute( 'DROP DATABASE '+"`$dbName`") def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
} sql.execute( 'DROP DATABASE '+"`$dbName`")
task setBlankPassword<<{
def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
sql.execute('USE `mifosplatform-tenants`')
sql.execute('UPDATE mifosplatform-tenants.tenants SET schema_server = \'localhost\', schema_server_port = \'3306\', schema_username = \'mifos\', schema_password = \'mysql\' WHERE id=1;')
}
apply plugin: 'flyway'
buildscript {
repositories {
mavenCentral()
} }
}
dependencies { task setBlankPassword {
classpath "org.flywaydb:flyway-gradle-plugin:3.0" // version upgraded during Spring Boot & MariaDB4j work, as prev. used v0.2 didn't work well after *.sql moved from fineract-db to fineract-provider/src/main/resources (new version also has clearer errors, e.g. in case of missing DB) doLast {
def sql = Sql.newInstance( 'jdbc:mysql:thin://localhost:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
// NOT classpath 'org.drizzle.jdbc:drizzle-jdbc:1.3' as it is not compatible with Flyway 3.1+ (only up to 3.0) sql.execute('USE `mifosplatform-tenants`')
// We require Flyway 3.1+ because =< 3.0 is not compatible with current Gradle versions (only ancient ones we originally used to use). sql.execute('UPDATE mifosplatform-tenants.tenants SET schema_server = \'localhost\', schema_server_port = \'3306\', schema_username = \'mifos\', schema_password = \'mysql\' WHERE id=1;')
// Using LGPL ConnectorJ ()org.mariadb.jdbc:mariadb-java-client) instead of the BSD licensed drizzle-jdbc *IS OK* at Apache.org,
// as long as it's only used as a test library by developers at build time, and not end-user distributed, and optional.
// So it's OK here, but would not be as a default runtime dependency and in the dist JAR/WAR.
// see https://issues.apache.org/jira/browse/LEGAL-462
// see https://issues.apache.org/jira/browse/FINERACT-761
// see https://github.com/flyway/flyway/issues/2332
// see https://github.com/krummas/DrizzleJDBC/issues/46
// see https://github.com/apache/fineract/pull/525
// see https://github.com/apache/fineract/pull/550
classpath 'org.mariadb.jdbc:mariadb-java-client:2.4.1'
} }
} }
flyway {
url = "jdbc:mariadb://localhost:3306/mifostenant-default"
driver = "org.mariadb.jdbc.Driver"
user = mysqlUser
password = mysqlPassword
}
task migrateTenantDB<<{
description="Migrates a Tenant DB. Optionally can pass dbName. Defaults to 'mifostenant-default' (Example: -PdbName=someTenantDBname)"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/core_db'
def tenantDbName = 'mifostenant-default';
if (rootProject.hasProperty("dbName")) {
tenantDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mariadb://localhost:3306/$tenantDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
/**We use ${ as the prefix for strecthy reporting, do not want them to be interpreted by Flyway**/
flyway.placeholderPrefix = "\$\${"
flywayMigrate.execute()
}
task showTenantDBInfo<<{
description="Shows the migration info for a Tenant DB. Optionally can pass dbName. Defaults to 'mifostenant-default' (Example: -PdbName=someTenantDBname)"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/core_db'
def tenantDbName = 'mifostenant-default';
if (rootProject.hasProperty("dbName")) {
tenantDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mariadb://localhost:3306/$tenantDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayInfo.execute()
}
task migrateTenantListDB<<{
description="Migrates a Tenant List DB. Optionally can pass dbName. Defaults to 'mifosplatform-tenants' (Example: -PdbName=someDBname)"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
def tenantsDbName = 'mifosplatform-tenants';
if (rootProject.hasProperty("dbName")) {
tenantsDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mariadb://localhost:3306/$tenantsDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayMigrate.execute()
}
task showTenantListDBInfo<<{
description="Shows the migration info for a List DB. Optionally can pass dbName. Defaults to 'mifosplatform-tenants' (Example: -PdbName=someDBname)"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
def tenantsDbName = 'mifosplatform-tenants';
if (rootProject.hasProperty("dbName")) {
tenantsDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mariadb://localhost:3306/$tenantsDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayInfo.execute()
}
task repairTenantDB<<{
description="repair migrate"
def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
def tenantsDbName = 'mifosplatform-tenants';
if (rootProject.hasProperty("dbName")) {
tenantsDbName = rootProject.getProperty("dbName")
}
flyway.url= "jdbc:mariadb://localhost:3306/$tenantsDbName"
flyway.driver = "org.mariadb.jdbc.Driver"
flyway.locations= [filePath]
flywayRepair.execute()
}
/* /*
* Support publication of artifacts versioned by topic branch. * Support publication of artifacts versioned by topic branch.
* CI builds supply `-P BRANCH_NAME=<TOPIC>` to gradle at build time. * CI builds supply `-P BRANCH_NAME=<TOPIC>` to gradle at build time.
@@ -547,8 +451,8 @@ def qualifyVersionIfNecessary(version) {
} }
springBoot { springBoot {
mainClass = 'org.apache.fineract.ServerWithMariaDB4jApplication' mainClassName = 'org.apache.fineract.ServerWithMariaDB4jApplication'
} }
bootRepackage { bootWar {
mainClass = 'org.apache.fineract.ServerWithMariaDB4jApplication' mainClassName = 'org.apache.fineract.ServerWithMariaDB4jApplication'
} }
+9 -10
View File
@@ -17,7 +17,7 @@
* under the License. * under the License.
*/ */
dependencies { dependencies {
def tomcatVersion = '7.0.54' def tomcatVersion = '7.0.94'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}", tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-log4j:${tomcatVersion}" // NOT tomcat-embed-logging-juli (http://stackoverflow.com/questions/23963049/classcircularityerror-java-util-logging-logrecord-running-gradle-webapp-with-ja) "org.apache.tomcat.embed:tomcat-embed-logging-log4j:${tomcatVersion}" // NOT tomcat-embed-logging-juli (http://stackoverflow.com/questions/23963049/classcircularityerror-java-util-logging-logrecord-running-gradle-webapp-with-ja)
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") { tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
@@ -27,23 +27,20 @@ dependencies {
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat:${springBootVersion}") providedRuntime("org.springframework.boot:spring-boot-starter-tomcat:${springBootVersion}")
providedCompile(
// [group: 'javax.servlet', name: 'servlet-api', version: '2.5'],
)
compile( compile(
// [group: 'ch.vorburger.mariaDB4j', name: 'mariaDB4j', version: '2.1.3'], // [group: 'ch.vorburger.mariaDB4j', name: 'mariaDB4j', version: '2.1.3'],
[group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion], [group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion],
[group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: springBootVersion], [group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: springBootVersion],
[group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion], [group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion],
[group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: springBootVersion],
//[group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.0.0'], //[group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.0.0'],
[group: 'org.springframework', name: 'spring-context-support', version: springVersion], [group: 'org.springframework', name: 'spring-context-support', version: springVersion],
[group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: springOauthVersion], [group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: springOauthVersion],
[group: 'org.apache.openjpa', name:'openjpa-all', version:'2.4.1'], [group: 'org.apache.openjpa', name:'openjpa', version: openJPAVersion],
//[group: 'org.apache.openjpa', name:'openjpa-maven-plugin', version:'2.4.1'],
//[group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1'], //[group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1'],
[group: 'com.sun.jersey', name: 'jersey-core', version: jerseyVersion], [group: 'com.sun.jersey', name: 'jersey-core', version: jerseyVersion],
[group: 'com.sun.jersey', name: 'jersey-servlet', version: jerseyVersion], [group: 'com.sun.jersey', name: 'jersey-servlet', version: jerseyVersion],
@@ -68,7 +65,7 @@ dependencies {
// no slf4j & logback here (anymore), as spring-boot-starter-logging already brings this now, better assembled (log4j-over-slf4j was originally forgotten here) // no slf4j & logback here (anymore), as spring-boot-starter-logging already brings this now, better assembled (log4j-over-slf4j was originally forgotten here)
//[group: 'mysql', name: 'mysql-connector-java', version: '5.1.27'], //[group: 'mysql', name: 'mysql-connector-java', version: '5.1.27'],
[group: 'org.drizzle.jdbc', name: 'drizzle-jdbc', version: '1.3'], [group: 'org.drizzle.jdbc', name: 'drizzle-jdbc', version: '1.4'],
// [group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: tomcatVersion], // [group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: tomcatVersion],
@@ -93,11 +90,13 @@ dependencies {
//[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0'] //[group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.0']
[group: 'io.swagger', name: 'swagger-jersey-jaxrs', version: '1.5.15'], [group: 'io.swagger', name: 'swagger-jersey-jaxrs', version: '1.5.15'],
[group: 'org.springframework', name:'spring-jms'], [group: 'org.springframework', name:'spring-jms', version: '4.0.7.RELEASE'],
[group: 'org.apache.activemq', name: 'activemq-broker'], [group: 'org.apache.activemq', name: 'activemq-broker', version: '5.9.1'],
[group: 'javax.validation', name: 'validation-api', version: '2.0.0.Final'] [group: 'javax.validation', name: 'validation-api', version: '2.0.0.Final']
) )
implementation 'org.apache.bval:org.apache.bval.bundle:2.0.2'
testCompile 'junit:junit:4.11', testCompile 'junit:junit:4.11',
'junit:junit-dep:4.11', 'junit:junit-dep:4.11',
'org.mockito:mockito-core:1.9.5', 'org.mockito:mockito-core:1.9.5',
Binary file not shown.
+1 -2
View File
@@ -1,6 +1,5 @@
#Fri Jan 29 13:04:36 IST 2016
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
Vendored Executable
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
+84
View File
@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@@ -3787,7 +3787,7 @@ public class ClientLoanIntegrationTest {
todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
Integer overdueFeeChargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec, Integer overdueFeeChargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
ChargesHelper.getLoanOverdueFeeJSONWithCalculattionTypePercentage()); ChargesHelper.getLoanOverdueFeeJSONWithCalculattionTypePercentage("10"));
Assert.assertNotNull(overdueFeeChargeId); Assert.assertNotNull(overdueFeeChargeId);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
@@ -22,6 +22,7 @@ import org.junit.Assert;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.fineract.integrationtests.common.HookHelper; import org.apache.fineract.integrationtests.common.HookHelper;
@@ -62,7 +63,8 @@ public class HookIntegrationTest {
// Subject to https://echo-webhook.herokuapp.com being up // Subject to https://echo-webhook.herokuapp.com being up
// See // See
// http://www.jamesward.com/2014/06/11/testing-webhooks-was-a-pain-so-i-fixed-the-glitch // http://www.jamesward.com/2014/06/11/testing-webhooks-was-a-pain-so-i-fixed-the-glitch
final String payloadURL = "http://echo-webhook.herokuapp.com:80/Z7RXoCBdLSFMDrpn?"; final String uniqueId = UUID.randomUUID().toString();
final String payloadURL = "http://echo-webhook.herokuapp.com:80/" + uniqueId + "?";
this.hookHelper.createHook(payloadURL); this.hookHelper.createHook(payloadURL);
final Integer createdOfficeID = this.officeHelper.createOffice("01 January 2012"); final Integer createdOfficeID = this.officeHelper.createOffice("01 January 2012");
try { try {
@@ -724,6 +724,70 @@ public class SchedulerJobsTestResults {
} }
@Test
public void testAvoidUnncessaryPenaltyWhenAmountZeroForOverdueLoansJobOutcome() throws InterruptedException {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
this.schedulerJobHelper = new SchedulerJobHelper(this.requestSpec, this.responseSpec);
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer overdueFeeChargeId = ChargesHelper
.createCharges(this.requestSpec, this.responseSpec, ChargesHelper.getLoanOverdueFeeJSONWithCalculattionTypePercentage("0.000001"));
Assert.assertNotNull(overdueFeeChargeId);
final Integer loanProductID = createLoanProduct(overdueFeeChargeId.toString());
Assert.assertNotNull(loanProductID);
final Integer loanID = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null);
Assert.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
ArrayList<HashMap> repaymentScheduleDataBefore = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec,
this.responseSpec, loanID);
String JobName = "Apply penalty to overdue loans";
Integer jobId = 12;
this.schedulerJobHelper.executeJob(JobName);
HashMap schedulerJob = this.schedulerJobHelper.getSchedulerJobById(this.requestSpec, this.responseSpec, jobId.toString());
Assert.assertNotNull(schedulerJob);
while ((Boolean) schedulerJob.get("currentlyRunning") == true) {
Thread.sleep(15000);
schedulerJob = this.schedulerJobHelper.getSchedulerJobById(this.requestSpec, this.responseSpec, jobId.toString());
Assert.assertNotNull(schedulerJob);
}
final HashMap chargeData = ChargesHelper.getChargeById(this.requestSpec, this.responseSpec, overdueFeeChargeId);
ArrayList<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec,
this.responseSpec, loanID);
Assert.assertEquals("Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job",
0, repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"));
final ArrayList loanCharges = this.loanTransactionHelper.getLoanCharges(this.requestSpec,
this.responseSpec, loanID);
Assert.assertNull("Verifying that charge isn't created when the amount is 0", loanCharges);
loanStatusHashMap = this.loanTransactionHelper.undoDisbursal(loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
}
@Test @Test
public void testUpdateOverdueDaysForNPA() throws InterruptedException { public void testUpdateOverdueDaysForNPA() throws InterruptedException {
this.schedulerJobHelper = new SchedulerJobHelper(this.requestSpec, this.responseSpec); this.schedulerJobHelper = new SchedulerJobHelper(this.requestSpec, this.responseSpec);
@@ -28,17 +28,24 @@ import java.io.File;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.Calendar;
import java.util.Locale;
import java.util.Random;
import java.util.TimeZone;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.response.Response;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.http.conn.HttpHostConnectException; import org.apache.http.conn.HttpHostConnectException;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
/** /**
* Util for RestAssured tests. This class here in src/integrationTest is * Util for RestAssured tests. This class here in src/integrationTest is
* copy/pasted to src/test; please keep them in sync. * copy/pasted to src/test; please keep them in sync.
@@ -46,13 +53,16 @@ import com.jayway.restassured.specification.ResponseSpecification;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class Utils { public class Utils {
private final static Logger logger = LoggerFactory.getLogger(Utils.class);
public static final String TENANT_PARAM_NAME = "tenantIdentifier"; public static final String TENANT_PARAM_NAME = "tenantIdentifier";
public static final String DEFAULT_TENANT = "default"; public static final String DEFAULT_TENANT = "default";
public static final String TENANT_IDENTIFIER = TENANT_PARAM_NAME + '=' + DEFAULT_TENANT; public static final String TENANT_IDENTIFIER = TENANT_PARAM_NAME + '=' + DEFAULT_TENANT;
public static final String TENANT_TIME_ZONE = "Asia/Kolkata"; public static final String TENANT_TIME_ZONE = "Asia/Kolkata";
private static final String LOGIN_URL = "/fineract-provider/api/v1/authentication?username=mifos&password=password&" + TENANT_IDENTIFIER; private static final String HEALTH_URL = "/fineract-provider/health";
private static final String LOGIN_URL = "/fineract-provider/api/v1/authentication?username=mifos&password=password&" + TENANT_IDENTIFIER;
public static void initializeRESTAssured() { public static void initializeRESTAssured() {
RestAssured.baseURI = "https://localhost"; RestAssured.baseURI = "https://localhost";
@@ -60,8 +70,51 @@ public class Utils {
RestAssured.keystore("src/main/resources/keystore.jks", "openmf"); RestAssured.keystore("src/main/resources/keystore.jks", "openmf");
} }
public static String loginIntoServerAndGetBase64EncodedAuthenticationKey() { private static void awaitSpringBootActuatorHealthyUp() {
int attempt = 0;
final int max_attempts = 10;
Response response = null;
Exception lastException = null;
do {
try {
response = RestAssured.get(HEALTH_URL);
int healthHttpStatus = response.statusCode();
if (healthHttpStatus == 200) {
logger.info("{} return HTTP 200, application is now ready for integration testing!", HEALTH_URL);
return;
} else {
logger.info("{} returned HTTP {}, going to wait and retry (attempt {})", new Object[] { HEALTH_URL, healthHttpStatus, attempt++ });
sleep(3);
}
} catch (Exception e) {
logger.info("{} caused {}, going to wait and retry (attempt {})", HEALTH_URL, new Object[] { e.getMessage(), attempt++ });
lastException = e;
sleep(3);
}
} while (attempt < max_attempts);
if (lastException != null) {
logger.error("{} still not reachable, giving up", HEALTH_URL, lastException);
throw new AssertionError(HEALTH_URL + " not reachable", lastException);
} else {
logger.error("{} still has not returned HTTP 200, giving up; (last) body: ", HEALTH_URL, response.prettyPrint());
fail(HEALTH_URL + " returned " + response.prettyPrint());
}
}
private static void sleep(int seconds) {
try { try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException e) {
logger.warn("Unexpected InterruptedException", e);
throw new IllegalStateException("Unexpected InterruptedException", e);
}
}
public static String loginIntoServerAndGetBase64EncodedAuthenticationKey() {
awaitSpringBootActuatorHealthyUp();
try {
logger.info("Logging in, for integration test...");
System.out.println("-----------------------------------LOGIN-----------------------------------------"); System.out.println("-----------------------------------LOGIN-----------------------------------------");
final String json = RestAssured.post(LOGIN_URL).asString(); final String json = RestAssured.post(LOGIN_URL).asString();
assertThat("Failed to login into fineract platform", StringUtils.isBlank(json), is(false)); assertThat("Failed to login into fineract platform", StringUtils.isBlank(json), is(false));
@@ -205,3 +258,4 @@ public class Utils {
return templateLocation.substring(1,templateLocation.length()-1); return templateLocation.substring(1,templateLocation.length()-1);
} }
} }
@@ -275,10 +275,10 @@ public class ChargesHelper {
return chargesCreateJson; return chargesCreateJson;
} }
public static String getLoanOverdueFeeJSONWithCalculattionTypePercentage() { public static String getLoanOverdueFeeJSONWithCalculattionTypePercentage(String penaltyPercentageAmount) {
final HashMap<String, Object> map = populateDefaultsForLoan(); final HashMap<String, Object> map = populateDefaultsForLoan();
map.put("penalty", ChargesHelper.penalty); map.put("penalty", ChargesHelper.penalty);
map.put("amount", "10"); map.put("amount", penaltyPercentageAmount);
map.put("chargePaymentMode", ChargesHelper.CHARGE_PAYMENT_MODE_REGULAR); map.put("chargePaymentMode", ChargesHelper.CHARGE_PAYMENT_MODE_REGULAR);
map.put("chargeTimeType", CHARGE_OVERDUE_INSTALLMENT_FEE); map.put("chargeTimeType", CHARGE_OVERDUE_INSTALLMENT_FEE);
map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST); map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST);
@@ -106,6 +106,12 @@ public class LoanTransactionHelper {
return (ArrayList) response.get("periods"); return (ArrayList) response.get("periods");
} }
public ArrayList getLoanCharges(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanID) {
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=charges&" + Utils.TENANT_IDENTIFIER;
return (ArrayList) Utils.performServerGet(requestSpec, responseSpec, URL, "charges");
}
public ArrayList getLoanFutureRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public ArrayList getLoanFutureRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanID) { final Integer loanID) {
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule,futureSchedule&" final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule,futureSchedule&"
@@ -29,6 +29,8 @@ import org.joda.time.LocalDate;
import org.joda.time.LocalTime; import org.joda.time.LocalTime;
import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.JdbcUtils;
import static org.apache.fineract.infrastructure.core.service.DateUtils.getDateTimeZoneOfTenant;
/** /**
* Support for retrieving possibly null values from jdbc recordset delegating to * Support for retrieving possibly null values from jdbc recordset delegating to
* springs {@link JdbcUtils} where possible. * springs {@link JdbcUtils} where possible.
@@ -44,6 +46,15 @@ public class JdbcSupport {
return dateTime; return dateTime;
} }
public static DateTime getLocalDateTime(final ResultSet rs, final String columnName) throws SQLException {
DateTime dateTime = null;
final Timestamp dateValue = rs.getTimestamp(columnName);
if (dateValue != null) {
dateTime = new DateTime(dateValue.getTime()).withZone(getDateTimeZoneOfTenant());
}
return dateTime;
}
public static LocalDate getLocalDate(final ResultSet rs, final String columnName) throws SQLException { public static LocalDate getLocalDate(final ResultSet rs, final String columnName) throws SQLException {
LocalDate localDate = null; LocalDate localDate = null;
final Date dateValue = rs.getDate(columnName); final Date dateValue = rs.getDate(columnName);
@@ -25,8 +25,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.slf4j.Logger;
import org.apache.commons.logging.LogFactory; import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy; import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy; import org.springframework.security.web.RedirectStrategy;
@@ -37,7 +37,7 @@ import org.springframework.util.Assert;
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
protected final Log logger = LogFactory.getLog(getClass()); protected final Logger logger = LoggerFactory.getLogger(getClass());
private String defaultFailureUrl; private String defaultFailureUrl;
private boolean forwardToDestination = false; private boolean forwardToDestination = false;
@@ -19,13 +19,13 @@
package org.apache.fineract.interoperation.data; package org.apache.fineract.interoperation.data;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import org.apache.bval.constraints.NotEmpty;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.interoperation.domain.InteropIdentifierType; import org.apache.fineract.interoperation.domain.InteropIdentifierType;
import org.apache.fineract.interoperation.domain.InteropTransactionRole; import org.apache.fineract.interoperation.domain.InteropTransactionRole;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -18,9 +18,9 @@
*/ */
package org.apache.fineract.interoperation.data; package org.apache.fineract.interoperation.data;
import org.apache.bval.constraints.NotEmpty;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.Map; import java.util.Map;
@@ -19,7 +19,6 @@
package org.apache.fineract.interoperation.util; package org.apache.fineract.interoperation.util;
import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.api.JsonCommand;
import serp.util.Strings;
import java.util.Locale; import java.util.Locale;
@@ -2490,6 +2490,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final LoanCharge loanCharge = LoanCharge.createNewFromJson(loan, chargeDefinition, command, entry.getValue()); final LoanCharge loanCharge = LoanCharge.createNewFromJson(loan, chargeDefinition, command, entry.getValue());
if (BigDecimal.ZERO.compareTo(loanCharge.amount()) == 0) {
continue;
}
LoanOverdueInstallmentCharge overdueInstallmentCharge = new LoanOverdueInstallmentCharge(loanCharge, installment, LoanOverdueInstallmentCharge overdueInstallmentCharge = new LoanOverdueInstallmentCharge(loanCharge, installment,
entry.getKey()); entry.getKey());
loanCharge.updateOverdueInstallmentCharge(overdueInstallmentCharge); loanCharge.updateOverdueInstallmentCharge(overdueInstallmentCharge);
@@ -39,9 +39,9 @@
<logger name="org.fineract.platform" level="debug" /> <logger name="org.fineract.platform" level="debug" />
<logger name="org.apache.fineract.infrastructure.security.filter" <logger name="org.apache.fineract.infrastructure.security.filter" level="info" />
level="info" />
<logger name="org.apache.fineract" level="debug" /> <logger name="org.apache.fineract" level="debug" />
<logger name="org.springframework.boot.actuate.audit.listener" level="debug" /> <!-- FINERACT-779 -->
<logger name="org.springframework.web" level="info" /> <logger name="org.springframework.web" level="info" />
<logger name="org.springframework.beans" level="info" /> <logger name="org.springframework.beans" level="info" />
<logger name="net.sf.ehcache" level="error" /> <logger name="net.sf.ehcache" level="error" />
@@ -40,6 +40,7 @@ import org.apache.fineract.useradministration.domain.RoleRepository;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
@org.junit.Ignore // see FINERACT-776
public class TopicTest { public class TopicTest {
@Mock @Mock
@@ -31,6 +31,13 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper; import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.portfolio.loanaccount.LoanScheduleTestDataHelper; import org.apache.fineract.portfolio.loanaccount.LoanScheduleTestDataHelper;
@@ -43,13 +50,6 @@ import org.joda.time.LocalDate;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
public class TemplateMergeServiceTest { public class TemplateMergeServiceTest {
private TemplateMergeService tms = new TemplateMergeService(); private TemplateMergeService tms = new TemplateMergeService();
@@ -89,8 +89,7 @@ public class TemplateMergeServiceTest {
String expectedOutput = Resources.toString(Resources.getResource("template-expected.html"), Charsets.UTF_8); String expectedOutput = Resources.toString(Resources.getResource("template-expected.html"), Charsets.UTF_8);
String output = compileTemplateText(templateText, scopes); String output = compileTemplateText(templateText, scopes);
// System.out.println(output); assertEquals(expectedOutput, output);
// assertEquals(expectedOutput, output);
} }
@Test @Test
+24
View File
@@ -0,0 +1,24 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Increased memory and disabled daemon are required by gradle-tomcat-plugin
# The daemon is more pain than gain, because the Tomcat in the Gradle process does not shut down cleanly.
# TODO remove this after https://issues.apache.org/jira/browse/FINERACT-764
org.gradle.jvmargs=-Xmx4g
org.gradle.daemon=false