Files
cbsnexora-backend/fineract-provider/build.gradle
T

566 lines
18 KiB
Groovy

/**
* 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.
*/
description = 'Fineract Provider'
apply plugin: 'org.zeroturnaround.gradle.jrebel'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'com.gorylenko.gradle-git-properties'
apply plugin: 'io.swagger.core.v3.swagger-gradle-plugin'
apply plugin: 'com.google.cloud.tools.jib'
apply plugin: 'org.springframework.boot'
apply plugin: 'se.thinkcode.cucumber-runner'
check.dependsOn('cucumber')
tasks.register('staticWeaveJpa', JavaExec) {
dependsOn classes
def classesDir = layout.buildDirectory.dir("classes/java/main").get().asFile
def outputDir = layout.buildDirectory.dir("weaved-classes").get().asFile
def persistenceInfo = layout.buildDirectory.dir('static-weaving').get()
copy {
from file("src/main/resources/jpa/static-weaving/module/provider/persistence.xml")
into "${persistenceInfo}/META-INF/"
}
mainClass.set("org.eclipse.persistence.tools.weaving.jpa.StaticWeave")
classpath = sourceSets.main.runtimeClasspath
args = [
'-persistenceinfo', persistenceInfo,
classesDir.absolutePath,
outputDir.absolutePath
]
}
tasks.register("weavedJar", Jar) {
archiveClassifier.set("")
dependsOn staticWeaveJpa
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from(layout.buildDirectory.dir("weaved-classes"))
exclude("META-INF/persistence.xml")
}
tasks.register("weavedPlainJar", Jar) {
archiveClassifier.set("plain")
dependsOn staticWeaveJpa
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from(layout.buildDirectory.dir("weaved-classes"))
exclude("META-INF/persistence.xml")
}
// Configure the default jar task to depend on weavedJar and use its output
tasks.named('jar') {
dependsOn weavedPlainJar
enabled = false // Disable the default jar task
// The weavedJar will be used as the primary artifact
}
// Make sure the assemble task depends on weavedJar
tasks.named('assemble') {
dependsOn weavedJar
}
tasks.named('staticWeaveJpa') {
mustRunAfter tasks.named('resolve')
}
compileJava {
dependsOn ':fineract-avro-schemas:buildJavaSdk'
}
// Configuration for Swagger documentation generation task
// https://github.com/swagger-api/swagger-core/tree/master/modules/swagger-gradle-plugin
import org.apache.tools.ant.filters.ReplaceTokens
tasks.register('prepareInputYaml') {
outputs.file("${buildDir}/tmp/swagger/fineract-input.yaml")
doLast {
copy {
from file("${projectDir}/config/swagger/fineract-input.yaml.template")
into file("${buildDir}/tmp/swagger")
rename { String filename -> return 'fineract-input.yaml' }
filter(ReplaceTokens, tokens: [VERSION: "${project.version}".toString()])
}
}
}
resolve {
logging.captureStandardOutput LogLevel.INFO
outputFileName = 'fineract'
outputFormat = 'JSONANDYAML'
prettyPrint = false
classpath = sourceSets.main.runtimeClasspath
buildClasspath = classpath
outputDir = file("${buildDir}/classes/java/main/static")
openApiFile = file("${buildDir}/tmp/swagger/fineract-input.yaml")
sortOutput = true
dependsOn(prepareInputYaml)
}
configurations {
providedRuntime // needed for Spring Boot executable WAR
providedCompile
implementation
testImplementation
cucumberRuntime {
extendsFrom testImplementation
}
compile() {
exclude module: 'hibernate-entitymanager'
exclude module: 'hibernate-validator'
exclude module: 'activation'
exclude module: 'bcmail-jdk14'
exclude module: 'bcprov-jdk14'
exclude module: 'bctsp-jdk14'
exclude module: 'c3p0'
exclude module: 'stax-api'
exclude module: 'jaxb-api'
exclude module: 'jaxb-impl'
exclude module: 'jboss-logging'
exclude module: 'itext-rtf'
exclude module: 'classworlds'
}
runtime
}
dependencies {
implementation project(':fineract-core')
implementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.mockito:mockito-core'
implementation 'org.mockito:mockito-junit-jupiter'
implementation 'org.junit.jupiter:junit-jupiter-api'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.liquibase:liquibase-core'
}
apply from: 'dependencies.gradle'
// Configuration for the modernizer plugin
// https://github.com/andygoossens/gradle-modernizer-plugin
modernizer {
ignoreClassNamePatterns = [
'.*AbstractPersistableCustom',
'.*EntityTables',
'.*domain.*'
]
}
// If we are running Gradle within Eclipse to enhance classes with OpenJPA,
// set the classes directory to point to Eclipse's default build directory
if (project.hasProperty('env') && project.getProperty('env') == 'eclipse') {
sourceSets.main.java.outputDir = new File(rootProject.projectDir, "fineract-provider/bin/main")
}
eclipse {
project {
buildCommand([ LaunchConfigHandle: "<project>/.externalToolBuilders/OpenJPA Enhance Builder.launch" ], 'org.eclipse.ui.externaltools.ExternalToolBuilder')
}
}
if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) {
sourceSets {
test {
java {
exclude '**/core/boot/tests/**'
}
}
}
}
// Configuration for SQL tasks
// https://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html
import groovy.sql.Sql
project.ext.mysqlUser='root'
project.ext.mysqlPassword='mysql'
project.ext.pgUser='root'
project.ext.pgPassword='postgres'
configurations {
driver
}
dependencies {
driver 'org.mariadb.jdbc:mariadb-java-client'
driver 'org.postgresql:postgresql'
driver 'com.mysql:mysql-connector-j'
}
URLClassLoader loader = GroovyObject.class.classLoader
configurations.driver.each {File file ->
loader.addURL(file.toURL())
}
tasks.register('createDB') {
description = "Creates the MariaDB Database. Needs database name to be passed (like: -PdbName=someDBname)"
doLast {
def sql = Sql.newInstance('jdbc:mariadb://localhost:3306/', mysqlUser, mysqlPassword, 'org.mariadb.jdbc.Driver')
sql.execute('CREATE DATABASE ' + "`$dbName` CHARACTER SET utf8mb4")
}
}
tasks.register('dropDB') {
description = "Drops the specified MariaDB database. The database name has to be passed (like: -PdbName=someDBname)"
doLast {
def sql = Sql.newInstance('jdbc:mariadb://localhost:3306/', mysqlUser, mysqlPassword, 'org.mariadb.jdbc.Driver')
sql.execute('DROP DATABASE ' + "`$dbName`")
}
}
tasks.register('createPGDB') {
description = "Creates the PostgreSQL Database. Needs database name to be passed (like: -PdbName=someDBname)"
doLast {
def sql = Sql.newInstance('jdbc:postgresql://localhost:5432/', pgUser, pgPassword, 'org.postgresql.Driver')
sql.execute('create database ' + "$dbName")
}
}
tasks.register('dropPGDB') {
description = "Drops the specified PostgreSQL database. The database name has to be passed (like: -PdbName=someDBname)"
doLast {
def sql = Sql.newInstance('jdbc:postgresql://localhost:5432/', pgUser, pgPassword, 'org.postgresql.Driver')
sql.execute('DROP DATABASE ' + "$dbName")
}
}
tasks.register('createMySQLDB') {
description = "Creates the MySQL Database. Needs database name to be passed (like: -PdbName=someDBname)"
doLast {
def sql = Sql.newInstance('jdbc:mysql://localhost:3306/', mysqlUser, mysqlPassword, 'com.mysql.cj.jdbc.Driver')
sql.execute('CREATE DATABASE ' + "`$dbName` CHARACTER SET utf8mb4")
}
}
tasks.register('dropMySQLDB') {
description = "Drops the specified MySQL database. The database name has to be passed (like: -PdbName=someDBname)"
doLast {
def sql = Sql.newInstance('jdbc:mysql://localhost:3306/', mysqlUser, mysqlPassword, 'com.mysql.cj.jdbc.Driver')
sql.execute('DROP DATABASE ' + "`$dbName`")
}
}
tasks.register('setBlankPassword') {
doLast {
def sql = Sql.newInstance('jdbc:mariadb://localhost:3306/', mysqlUser, mysqlPassword, 'org.mariadb.jdbc.Driver')
sql.execute('USE `fineract_tenants`')
sql.execute('UPDATE fineract_tenants.tenants SET schema_server = \'localhost\', schema_server_port = \'3306\', schema_username = \'mifos\', schema_password = \'mysql\' WHERE id=1;')
}
}
tasks.register("mergeWeavedOutput", Copy) {
dependsOn staticWeaveJpa
from layout.buildDirectory.dir("weaved-classes")
into layout.buildDirectory.dir("merged-weaved-classes/java/main")
// Optional: exclude files like persistence.xml
exclude("META-INF/persistence.xml")
}
bootRun {
dependsOn mergeWeavedOutput
def weavedClasses = layout.buildDirectory.dir("weaved-classes").get().asFile
classpath = files(weavedClasses) + sourceSets.main.runtimeClasspath.filter { file ->
file.name.endsWith('.jar')
}
jvmArgs = [
"-Dspring.output.ansi.enabled=ALWAYS"
]
dependencies {
implementation 'org.mariadb.jdbc:mariadb-java-client'
implementation 'org.postgresql:postgresql'
}
}
springBoot {
mainClass = 'org.apache.fineract.ServerApplication'
}
// Create a new weavedBootJar task that extends BootJar
tasks.register("weavedBootJar", org.springframework.boot.gradle.tasks.bundling.BootJar) {
group = "build"
description = "Builds a bootable JAR with weaved classes"
dependsOn staticWeaveJpa
dependsOn resolve
archiveClassifier.set("")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
//Required for bootable JAR
mainClass.set("org.apache.fineract.ServerApplication")
targetJavaVersion.set(JavaVersion.VERSION_21)
// Replace default classes with weaved ones
into("BOOT-INF/classes") {
from(layout.buildDirectory.dir("weaved-classes"))
}
manifest {
attributes(
'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher',
'Implementation-Title': 'Apache Fineract',
'Implementation-Version': project.version,
'Start-Class': 'org.apache.fineract.ServerApplication'
)
}
classpath configurations.runtimeClasspath
}
// Configure the bootJar task to include all dependencies
tasks.withType(org.springframework.boot.gradle.tasks.bundling.BootJar) {
// This ensures the launcher is included
requiresUnpack '**/*.jar'
// This ensures the launcher classes are included
launchScript()
}
// Make assemble depend on weavedBootJar instead of bootJar
tasks.named('assemble') {
dependsOn 'weavedBootJar'
}
// Disable the default bootJar task
bootJar {
dependsOn weavedBootJar
enabled = false
}
// Ensure jib uses the weaved classes
tasks.named('jibDockerBuild') {
dependsOn 'staticWeaveJpa'
}
// Ensure staticWeaveJpa runs before jib
tasks.named('jib') {
dependsOn 'staticWeaveJpa'
}
jib {
from {
image = 'azul/zulu-openjdk-alpine:21'
platforms {
platform {
architecture = System.getProperty("os.arch").equals("aarch64")?"arm64":"amd64"
os = 'linux'
}
}
}
to {
image = 'fineract'
tags = [
"${project.version}",
'latest'
]
}
container {
creationTime = 'USE_CURRENT_TIMESTAMP'
mainClass = 'org.apache.fineract.ServerApplication'
extraClasspath = ['/app/plugins/*']
args = [
'-Duser.home=/tmp',
'-Dfile.encoding=UTF-8',
'-Duser.timezone=UTC',
'-Djava.security.egd=file:/dev/./urandom'
]
ports = ['8080/tcp', '8443/tcp']
labels = [maintainer: 'Aleksandar Vidakovic <aleks@apache.org>']
user = 'nobody:nogroup'
}
extraDirectories {
paths {
path {
from = layout.buildDirectory.dir("weaved-classes").get().asFile
into = '/app/classes'
}
}
}
allowInsecureRegistries = true
dependencies {
implementation 'org.mariadb.jdbc:mariadb-java-client'
implementation 'org.postgresql:postgresql'
}
pluginExtensions {
pluginExtension {
implementation = 'com.google.cloud.tools.jib.gradle.extension.layerfilter.JibLayerFilterExtension'
configuration {
filters {
filter {
glob = '/app/resources/**'
}
}
}
}
}
}
tasks.register('migrateDatabase') {
doFirst {
println 'Executing liquibase database migration to version ' + "$dbVersion"
def dbUrl = 'jdbc:' + "$dbType" + '://' + "$dbHost" + ':' + "$dbPort" + '/' + "$dbName"
def changeLogFilePath = 'fineract-provider/src/main/resources/db/changelog/tenant/upgrades/0000_upgrade_to_' + "$dbVersion" + '.xml'
liquibase {
activities {
main {
changeLogFile changeLogFilePath
url dbUrl
username project.ext.mysqlUser
password project.ext.mysqlPassword
}
}
}
}
}
cucumber {
tags = 'not @ignore'
main = 'io.cucumber.core.cli.Main'
shorten = 'argfile'
plugin = [
'pretty',
'html:build/reports/cucumber/report.html',
'json:build/reports/cucumber/report.json',
'junit:build/reports/cucumber/report.xml'
]
}
tasks.jibDockerBuild.dependsOn(bootJar)
// Configuration for git properties gradle plugin
// https://github.com/n0mer/gradle-git-properties
gitProperties {
gitPropertiesResourceDir = file("$buildDir/classes/java/main")
dateFormat = "yyyy-MM-dd'T'HH:mmZ"
dateFormatTimeZone = "GMT"
failOnNoGitDirectory = false
}
// make sure the generateGitProperties task always executes (even when git.properties is not changed)
generateGitProperties.outputs.upToDateWhen { false }
// NOTE: Gradle suggested these dependencies
jar.dependsOn resolve
test.dependsOn resolve
checkstyleMain.dependsOn resolve
checkstyleTest.dependsOn resolve
rat.dependsOn prepareInputYaml
spotbugsTest.dependsOn resolve
compileTestJava.dependsOn ':fineract-client:processResources', ':fineract-avro-schemas:processResources'
resolveMainClassName.dependsOn resolve
processResources.dependsOn compileJava
javadoc {
dependsOn resolve
}
tasks.register('devRun', org.springframework.boot.gradle.tasks.run.BootRun) {
description = 'Runs the application quickly for development by skipping quality checks'
group = 'Application'
// Configure the build to skip quality checks
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(devRun)) {
tasks.matching { task ->
task.name in ['checkstyle', 'checkstyleMain', 'checkstyleTest',
'spotlessCheck', 'spotlessApply',
'spotbugsMain', 'spotbugsTest',
'javadoc', 'javadocJar',
'modernizer',
'testClasses']
}.configureEach {
enabled = false
}
// Also disable error prone compilation flags
tasks.withType(JavaCompile).configureEach {
options.errorprone.enabled = false
}
}
}
// Inherit all bootRun settings
classpath = bootRun.classpath
mainClass = bootRun.mainClass
jvmArgs = bootRun.jvmArgs
doFirst {
println "Running in development mode - quality checks are disabled"
}
}
tasks.named("test") {
dependsOn staticWeaveJpa
def testClasses = layout.buildDirectory.dir("classes/java/test").get().asFile
def weavedClasses = layout.buildDirectory.dir("weaved-classes").get().asFile
def testResources = layout.buildDirectory.dir("resources/test").get().asFile
classpath = files(
weavedClasses,
testClasses,
testResources,
configurations.testRuntimeClasspath
)
}
tasks.register("weavedCucumberTest", JavaExec) {
group = "verification"
description = "Runs Cucumber tests with weaved classes"
dependsOn staticWeaveJpa, compileTestJava, processTestResources
def weavedClasses = layout.buildDirectory.dir("weaved-classes").get().asFile
def testClasses = layout.buildDirectory.dir("classes/java/test").get().asFile
def testResources = layout.buildDirectory.dir("resources/test").get().asFile
classpath = files(
weavedClasses,
testClasses,
testResources,
configurations.testRuntimeClasspath
)
mainClass.set("io.cucumber.core.cli.Main") // Cucumber JUnit 5 CLI entrypoint
args = [
'--glue', 'org.apache.fineract', // your step defs package
'src/test/resources/features' // your feature files path
]
jvmArgs = ["-Dspring.output.ansi.enabled=ALWAYS"]
}
tasks.named("cucumber") {
dependsOn weavedCucumberTest
enabled = false
}