This is an automated email from the ASF dual-hosted git repository. vorburger pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 357820a7a755dce27d6d2707f29ffd21c71f54d1 Author: conradsp <[email protected]> AuthorDate: Thu Jun 20 08:37:18 2019 -0500 Create one-touch deploy with docker --- docker/Dockerfile | 28 +++ docker/README.md | 25 ++ docker/build.gradle | 553 +++++++++++++++++++++++++++++++++++++++++ docker/docker-compose.yml | 24 ++ docker/initdb/01-databases.sql | 6 + docker/server.xml | 191 ++++++++++++++ 6 files changed, 827 insertions(+) diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..5488e6f --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,28 @@ +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 git clone https://github.com/apache/fineract.git +COPY build.gradle fineract/fineract-provider + +# To use for local fineract development (instead of installing from the latest code from Github) +# 1) Copy Dockerfile, docker-compose.yml, and the initdb directory to the root of your project (/fineract) +# 2) Edit Dockerfile in /fineract - comment out the 2 lines above (RUN git clone and COPY build.gradle) +# 3) Uncomment the 2 lines below +# 4) Update your local copy of build.gradle and replace all references to localhost with fineractmysql + +#RUN mkdir fineract +#COPY . fineract + +WORKDIR fineract +RUN ./gradlew clean war +RUN mv 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" +COPY server.xml /opt/bitnami/tomcat/conf +RUN chmod 664 /opt/bitnami/tomcat/conf/server.xml +WORKDIR /opt/bitnami/tomcat/lib +RUN wget http://central.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/1.3/drizzle-jdbc-1.3.jar + diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..aae3739 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,25 @@ +Installing Fineract with Docker and docker-compose + +Prerequisites +============= +* docker and docker-compose installed on your machine + + +Installing a new Fineract instance +================================== + +* Clone the Fineract Github repository +* Navigate to the docker directory +* Run the following commands: + * docker-compose build + * docker-compose up -d +* Fineract will run at https://localhost:8443/fineract-provider + + +Using docker-compose for development +==================================== + +* Copy Dockerfile, docker-compose.yml, and the initdb directory to the root of your project (/fineract) +* Edit Dockerfile in /fineract - comment out the 2 lines (RUN git clone and COPY build.gradle) +* Uncomment the 2 lines in Dockerfile (RUN mkdir fineract, COPY . fineract) +* Update your local copy of build.gradle and replace all references to localhost with fineractmysql diff --git a/docker/build.gradle b/docker/build.gradle new file mode 100644 index 0000000..d0964e8 --- /dev/null +++ b/docker/build.gradle @@ -0,0 +1,553 @@ +/** + * 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 = '''\ +Run as: +gradle clean tomcatrunwar +''' +buildscript { + repositories { + jcenter() + mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } + } + + dependencies { + classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:1.0', + 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0', + 'org.zeroturnaround:gradle-jrebel-plugin:1.1.2', + 'org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE' // also change springDataJpaVersion below + classpath 'org.apache.openjpa:openjpa-all:2.4.1' + classpath 'at.schmutterer.oss.gradle:gradle-openjpa:0.2.0' + classpath 'gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.2.2' + } +} + +apply plugin: "org.nosphere.apache.rat" +apply plugin: 'rebel' +apply plugin: 'license' +apply plugin: 'war' +apply plugin: 'spring-boot' +apply plugin: 'eclipse' +apply plugin: 'idea' +apply plugin: 'tomcat' +apply plugin: 'project-report' +apply plugin: 'java' +apply plugin: 'openjpa' +apply plugin: 'pmd' +apply plugin: 'findbugs' + +/* define the valid syntax level for source files */ +sourceCompatibility = JavaVersion.VERSION_1_8 +/* define binary compatibility version */ +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.mysqlPassword='mysql' + + +group = 'org.apache.fineract' +buildDir = new File(rootProject.projectDir, "../build") +repositories { + jcenter() + // 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' + + } + enforcePropertyRestrictions = true +} + +rat { + xmlOutput = false + htmlOutput = false + plainOutput = true + verbose = false +// inputDir = './..' + reportDir = new File(buildDir,'reports/rat') + excludes = [ + '**/licenses/**', + '**/*.md', + '**/*.github/*', + '**/MANIFEST.MF', + '**/*.txt', + '**/*.log', + '**/fineractdev-eclipse-preferences.epf', + '**/template-expected.html', + '**/template.mustache', + '**/.classpath', + '**/.project', + '**/.idea/**', + '**/*.ipr', + '**/*.iws', + '**/.settings/**', + '**/bin/**', + '**/.git/**', + '**/.gitignore', + '**/.gitkeep', + '**/*.iml', + //Notice files + '**/NOTICE_RELEASE', + '**/NOTICE_SOURCE', + // Swagger License + '**/src/main/resources/swagger-ui/**', + // gradle + '**/.gradle/**', + '**/gradlew', + '**/gradlew.bat', + '**/gradle/wrapper/gradle-wrapper.properties', + '**/caches/**', + '**/daemon/**', + '**/native/**', + '**/wrapper/**', + '**/build/**', + + //Api Docs + '**/api-docs/*.*', + '**/docs/system-architecture/.htaccess', + '**/docs/system-architecture/404.html', + '**/docs/system-architecture/index.html', + '**/docs/system-architecture/**/*.xml', + '**/bootstrap-3.0.0/assets/application.js', + '**/system-architecture/js/plugins.js', + + //Apache License + '**/bootstrap-3.0.0/assets/less.js', + '**/css/bootstrap-3.0.0/**/*.*', + + //Public Domain See http://www.JSON.org/js.html + '**/bootstrap-3.0.0/assets/json2.js.htm', + + // MIT License + '**/modernizr-2.6.2.min.js', + '**/css/normalize.css', + '**/assets/filesaver.js', + '**/css/fonts/glyphicons-halflings-regular.svg', + '**/assets/jszip.js', + '**/assets/jquery.js', + '**/api-docs/jquery-1.7.min.js', + '**/css/toc-0.1.2/**/*.*', + '**/docs/system-architecture/css/main.css', + '**/system-architecture/js/vendor/jquery-1.9.1.min.js', + '**/system-architecture/js/vendor/toc-0.1.2/jquery.toc.min.js', + '**/assets/respond.min.js', + '**/assets/html5shiv.js', + + //BSD License + '**/assets/uglify.js', + //Ignore out folder + '**/out/**' + ] +} + +configurations { + providedRuntime // needed for Spring Boot executable WAR + providedCompile + 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: 'bval-core' + exclude module: 'org.apache.bval.bundle' + exclude module: 'bval-jsr303' + 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' + exclude module: 'jcl-over-slf4j' + exclude module: 'jul-to-slf4j' + exclude module: 'serp' + } + runtime + all*.exclude group: 'commons-logging' +} +/* Pick up dependencies based on the environemnt, defaults to production */ +if (project.hasProperty('env') && project.getProperty('env') == 'dev') { + apply from: 'dev-dependencies.gradle' +} else { + apply from: 'dependencies.gradle' +} + +/* Enable Oauth2 authentication based on environment, default to HTTP basic auth */ +if (project.hasProperty('security') && project.getProperty('security') == 'oauth') { + if(project.hasProperty('twofactor') && project.getProperty('twofactor') == 'enabled') { + copy { + from './properties/oauth/twofactor/' + into 'src/main/resources/' + include '*.properties' + } + } else { + copy { + from './properties/oauth/' + into 'src/main/resources/' + include '*.properties' + } + } +} else { + if(project.hasProperty('twofactor') && project.getProperty('twofactor') == 'enabled') { + copy { + from './properties/basicauth/twofactor/' + into 'src/main/resources/' + include '*.properties' + } + } else { + copy { + from './properties/basicauth/' + into 'src/main/resources/' + include '*.properties' + } + } +} + +task dist(type:Zip){ + baseName = 'fineractplatform' + version = qualifyVersionIfNecessary(releaseVersion) + includeEmptyDirs = true + from('../') { + fileMode = 0755 + include '*.md' + } + from('src/main/dist') { + fileMode = 0755 + include '*' + } + from('../apps') { + fileMode = 0755 + include '**/*' + into('apps') + } + from('../api-docs/') { + fileMode = 0755 + include '*' + into('api-docs') + } + from('../fineract-db/') { + fileMode = 0755 + include '*.sql' + into('database') + } + from('src/main/resources/sql/migrations') { + fileMode = 0755 + include '**/*' + into('database/migrations') + } + + from war.outputs.files + into(baseName + '-' + version) +} + +compileJava{ + dependsOn rat +} +pmd { + sourceSets = [sourceSets.main] + ignoreFailures = true +} +findbugs { + ignoreFailures = true + sourceSets = [sourceSets.main] +} + +war { + from('../licenses/binary/') { // notice the parens + into "WEB-INF/licenses/binary/" // no leading slash + } + from('../LICENSE_RELEASE') { // notice the parens + into "WEB-INF/" // no leading slash + } + from('../NOTICE_RELEASE') { // notice the parens + into "WEB-INF/" // no leading slash + } + rename ('LICENSE_RELEASE', 'LICENSE') + rename ('NOTICE_RELEASE', 'NOTICE') + + from('../DISCLAIMER') { // notice the parens + into "WEB-INF/" // no leading slash + } + war.finalizedBy(bootRepackage) +} + +license { + header rootProject.file('../APACHE_LICENSETEXT.md') + excludes(["**/*.html", "**/*.mustache", "**/package-info.java", "**/keystore.jks", "**/swagger-ui/**"]) + strictCheck true +} + +task licenseFormatBuildScripts (type:nl.javadude.gradle.plugins.license.License) { + source = fileTree(dir: '../', includes: ['**/*.bat', '**/*.sh', '**/*.sql']) +} +licenseFormat.dependsOn licenseFormatBuildScripts + +tomcatRun { + httpPort = 8080 + httpsPort = 8443 + stopPort = 8081 + stopKey= 'stopKey' + enableSSL = true + configFile = file('src/test/resources/META-INF/context.xml') +} + +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') +} + +/* 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.test.output.resourcesDir = sourceSets.test.output.classesDir + +/* Exclude maria db and embedded tomcat related files for non dev builds */ +if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) { +sourceSets { + main { + java { + exclude '**/Server*' + exclude '**/MariaDB4j*' + exclude '**/EmbeddedTomcatWithSSLConfiguration.java' + } + } + test { + java { + exclude '**/core/boot/tests/**' + } + } +} +} + +sourceSets { + integrationTest { + compileClasspath += main.output + test.output + runtimeClasspath += main.output + test.output + } +} + +configurations { + integrationTestCompile.extendsFrom testCompile + integrationTestRuntime.extendsFrom testRuntime +} + +task integrationTest(type:Test){ + description = "Run integration tests (located in src/integrationTest/java). Starts tomcat in daemon mode before executing the tests." + it.dependsOn war + doFirst { + tomcatRunWar.daemon = true + tomcatRunWar.execute() + } + testClassesDir = project.sourceSets.integrationTest.output.classesDir + classpath = project.sourceSets.integrationTest.runtimeClasspath +} + + +import groovy.sql.Sql + +repositories { + mavenCentral() +} +configurations { + driver +} +dependencies { + driver 'org.drizzle.jdbc:drizzle-jdbc:1.3' +} + +test { + filter { + //includeTestsMatching "org.apache.fineract.infrastructure.configuration.spring.SpringConfigurationTest.*" + includeTestsMatching "org.apache.fineract.template.TemplateMergeServiceTest.*" + } +} + +URLClassLoader loader = GroovyObject.class.classLoader +configurations.driver.each {File file -> + loader.addURL(file.toURL()) +} + +task createDB<<{ + description= "Creates the Database. Needs database name to be passed (like: -PdbName=someDBname)" + def sql = Sql.newInstance( 'jdbc:mysql:thin://fineractmysql:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' ) + sql.execute( 'create database '+"`$dbName`" ) +} + +task dropDB<<{ + description= "Drops the specified database. The database name has to be passed (like: -PdbName=someDBname)" + def sql = Sql.newInstance( 'jdbc:mysql:thin://fineractmysql:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' ) + sql.execute( 'DROP DATABASE '+"`$dbName`") +} +task setBlankPassword<<{ + def sql = Sql.newInstance( 'jdbc:mysql:thin://fineractmysql:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' ) + sql.execute('USE `mifosplatform-tenants`') + sql.execute('UPDATE mifosplatform-tenants.tenants SET schema_server = \'fineractmysql\', schema_server_port = \'3306\', schema_username = \'mifos\', schema_password = \'mysql\' WHERE id=1;') +} + + +apply plugin: 'flyway' +buildscript { + repositories { + mavenCentral() + } + + dependencies { + 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) + + // NOT classpath 'org.drizzle.jdbc:drizzle-jdbc:1.3' as it is not compatible with Flyway 3.1+ (only up to 3.0) + // We require Flyway 3.1+ because =< 3.0 is not compatible with current Gradle versions (only ancient ones we originally used to use). + // 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://fineractmysql: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://fineractmysql: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://fineractmysql: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://fineractmysql: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://fineractmysql: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://fineractmysql:3306/$tenantsDbName" + flyway.driver = "org.mariadb.jdbc.Driver" + flyway.locations= [filePath] + flywayRepair.execute() +} + +/* +* Support publication of artifacts versioned by topic branch. +* CI builds supply `-P BRANCH_NAME=<TOPIC>` to gradle at build time. +* If <TOPIC> starts with 'MIFOSX-', change version +* from BUILD-SNAPSHOT => <TOPIC>-SNAPSHOT +* e.g. 1.1.0.BUILD-SNAPSHOT => 1.0.0.MIFOSX-1234-SNAPSHOT +*/ +def qualifyVersionIfNecessary(version) { + + if (rootProject.hasProperty("BRANCH_NAME")) { + def qualifier = rootProject.getProperty("BRANCH_NAME") + if (qualifier.startsWith("MIFOSX-")) { + return version.replace('BUILD', qualifier) + } + } + return version +} + +springBoot { + mainClass = 'org.apache.fineract.ServerWithMariaDB4jApplication' +} +bootRepackage { + mainClass = 'org.apache.fineract.ServerWithMariaDB4jApplication' +} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..912124b --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,24 @@ +version: '3.7' +services: + fineractmysql: + image: mysql:5.7 + volumes: + - dbdata:/var/lib/mysql + - ./initdb:/docker-entrypoint-initdb.d + restart: always + environment: + MYSQL_ROOT_PASSWORD: mysql + MYSQL_USER: root + MYSQL_PASSWORD: mysql + ports: + - "3306:3306" + fineract-server: + build: + context: . + target: fineract + ports: + - 443:443 + depends_on: + - fineractmysql +volumes: + dbdata: \ No newline at end of file diff --git a/docker/initdb/01-databases.sql b/docker/initdb/01-databases.sql new file mode 100644 index 0000000..e4fa5fb --- /dev/null +++ b/docker/initdb/01-databases.sql @@ -0,0 +1,6 @@ +# create databases +CREATE DATABASE IF NOT EXISTS `mifosplatform-tenants`; +CREATE DATABASE IF NOT EXISTS `mifostenant-default`; + +# create root user and grant rights +GRANT ALL ON *.* TO 'root'@'%'; \ No newline at end of file diff --git a/docker/server.xml b/docker/server.xml new file mode 100644 index 0000000..3b4a0fc --- /dev/null +++ b/docker/server.xml @@ -0,0 +1,191 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<!-- Note: A "Server" is not itself a "Container", so you may not + define subcomponents such as "Valves" at this level. + Documentation at /docs/config/server.html + --> +<Server port="8005" shutdown="SHUTDOWN"> + <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> + <!-- Security listener. Documentation at /docs/config/listeners.html + <Listener className="org.apache.catalina.security.SecurityListener" /> + --> + <!--APR library loader. Documentation at /docs/apr.html --> + <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> + <!-- Prevent memory leaks due to use of particular java/javax APIs--> + <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> + <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> + <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> + + <!-- Global JNDI resources + Documentation at /docs/jndi-resources-howto.html + --> + <GlobalNamingResources> + <!-- Editable user database that can also be used by + UserDatabaseRealm to authenticate users + --> + <Resource type="javax.sql.DataSource" + name="jdbc/mifosplatform-tenants" + factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" + driverClassName="org.drizzle.jdbc.DrizzleDriver" + url="jdbc:mysql:thin://fineractmysql:3306/mifosplatform-tenants" + username="root" + password="mysql" + initialSize="3" + maxActive="10" + maxIdle="6" + minIdle="3" + validationQuery="SELECT 1" + testOnBorrow="true" + testOnReturn="true" + testWhileIdle="true" + timeBetweenEvictionRunsMillis="30000" + minEvictableIdleTimeMillis="60000" + logAbandoned="true" + suspectTimeout="60" + /> + </GlobalNamingResources> + + <!-- A "Service" is a collection of one or more "Connectors" that share + a single "Container" Note: A "Service" is not itself a "Container", + so you may not define subcomponents such as "Valves" at this level. + Documentation at /docs/config/service.html + --> + <Service name="Catalina"> + + <!--The connectors can use a shared executor, you can define one or more named thread pools--> + <!-- + <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" + maxThreads="150" minSpareThreads="4"/> + --> + + + <!-- A "Connector" represents an endpoint by which requests are received + and responses are returned. Documentation at : + Java HTTP Connector: /docs/config/http.html + Java AJP Connector: /docs/config/ajp.html + APR (HTTP/AJP) Connector: /docs/apr.html + Define a non-SSL/TLS HTTP/1.1 Connector on port 8080 + --> + <Connector port="8080" protocol="HTTP/1.1" + connectionTimeout="20000" + redirectPort="8443" /> + <!-- A "Connector" using the shared thread pool--> + <!-- + <Connector executor="tomcatThreadPool" + port="8080" protocol="HTTP/1.1" + connectionTimeout="20000" + redirectPort="8443" /> + --> + <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 + This connector uses the NIO implementation. The default + SSLImplementation will depend on the presence of the APR/native + library and the useOpenSSL attribute of the + AprLifecycleListener. + Either JSSE or OpenSSL style configuration may be used regardless of + the SSLImplementation selected. JSSE style configuration is used below. + --> + <Connector protocol="org.apache.coyote.http11.Http11Protocol" + port="8443" maxThreads="200" scheme="https" + secure="true" SSLEnabled="true" + keystoreFile="/opt/bitnami/tomcat/tomcat.keystore" + keystorePass="xyz123" + clientAuth="false" sslProtocol="TLS" + URIEncoding="UTF-8" + compression="force" + compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css"/> + <!-- + <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" + maxThreads="150" SSLEnabled="true"> + <SSLHostConfig> + <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" + type="RSA" /> + </SSLHostConfig> + </Connector> + --> + <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 + This connector uses the APR/native implementation which always uses + OpenSSL for TLS. + Either JSSE or OpenSSL style configuration may be used. OpenSSL style + configuration is used below. + --> + <!-- + <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" + maxThreads="150" SSLEnabled="true" > + <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> + <SSLHostConfig> + <Certificate certificateKeyFile="conf/localhost-rsa-key.pem" + certificateFile="conf/localhost-rsa-cert.pem" + certificateChainFile="conf/localhost-rsa-chain.pem" + type="RSA" /> + </SSLHostConfig> + </Connector> + --> + + <!-- Define an AJP 1.3 Connector on port 8009 --> + <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> + + + <!-- An Engine represents the entry point (within Catalina) that processes + every request. The Engine implementation for Tomcat stand alone + analyzes the HTTP headers included with the request, and passes them + on to the appropriate Host (virtual host). + Documentation at /docs/config/engine.html --> + + <!-- You should set jvmRoute to support load-balancing via AJP ie : + <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> + --> + <Engine name="Catalina" defaultHost="localhost"> + + <!--For clustering, please take a look at documentation at: + /docs/cluster-howto.html (simple how to) + /docs/config/cluster.html (reference documentation) --> + <!-- + <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> + --> + + <!-- Use the LockOutRealm to prevent attempts to guess user passwords + via a brute-force attack --> + <Realm className="org.apache.catalina.realm.LockOutRealm"> + <!-- This Realm uses the UserDatabase configured in the global JNDI + resources under the key "UserDatabase". Any edits + that are performed against this UserDatabase are immediately + available for use by the Realm. --> + <Realm className="org.apache.catalina.realm.UserDatabaseRealm" + resourceName="UserDatabase"/> + </Realm> + + <Host name="localhost" appBase="webapps" + unpackWARs="true" autoDeploy="true"> + + <!-- SingleSignOn valve, share authentication between web applications + Documentation at: /docs/config/valve.html --> + <!-- + <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> + --> + + <!-- Access log processes all example. + Documentation at: /docs/config/valve.html + Note: The pattern used is equivalent to using pattern="common" --> + <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" + prefix="localhost_access_log" suffix=".txt" + pattern="%h %l %u %t "%r" %s %b" /> + + </Host> + </Engine> + </Service> +</Server> \ No newline at end of file
