appRootDir/
build.properties
conf/
META-INF/persistence.xml
system-config.xml
web/
build.gradle
setting.gradle
app/
build.gradle
module1/
module2/
install
bundle/
seed/
seed.xml
sites/
resources
bundle/
test/
src/
test-automation/webdriver/
proguard.conf
LICENSE.txt
NOTICE.txt
RELEASE_NOTES.txt
It has root project (web), conf, install and test. A module is a subproject that can be a
separate project (e.g., svn project or git repository) that has its own versioning.
software.group=com.cmobilecom software.name=cmobilecom-af-examples software.displayName=Cmobilecom AF Examples software.version=1.2 # module versions module-hr.version=1.2The property naming convention for module versions is
module-<module_name_lowercase>.version
settings.gradle defines subprojects. For example,
rootProject.name = 'myapp-web' include 'app' include 'module-module1' project(':module-module1').projectDir = new File('../module1') include 'module-module2' project(':module-module2').projectDir = new File('../module2') include 'test' project(':test').projectDir = new File('../test')The root project build.gradle needs to verify that environment variable CMOBILECOM_AF_DIR is defined, unzip the cmobilecom-af zip if needed, and apply the root.gradle from cmobilecom-af that will configure subprojects, create tasks for installation and test automation, etc.
// define properties before applying root.gradle, see web/build.gradle of Cmobilecom AF examples. apply from : "$cmobilecomAFBuildCommonDir/root.gradle"
apply from : "${rootProject.cmobilecomAFBuildCommonDir}/app.gradle"
<seed> <!-- seed sql files for system instance --> <!-- seed sql path: [module]/db/[dbmsType]/seed.sql --> <seedSql>system/db/@DBMS_TYPE@/seed-user.sql</seedSql> <seedSql>system/db/@DBMS_TYPE@/seed.sql</seedSql> <seedSql>system/db/@DBMS_TYPE@/seed-sys.sql</seedSql> <seedSql>website/db/@DBMS_TYPE@/seed.sql</seedSql> <!-- configuration files --> <copy dir="conf" todir="#{cmobilecom.home}" target="conf"/> <!-- copy main site --> <copy dir="sites/hr/main" todir="#{cmobilecom.home}/dau/hr/www" target="main"/> </seed>@DBMS_TYPE@ will be replaced by the target database name(e.g., mysql, oracle) during installation. Database seed will be skipped during installation if answer property "install.init.db" is false. If database is not initialized during installation, it will be initialized from module seed sql file list when application starts.
cmobilecom-af-examples=Cmobilecom AF Examples cmobilecom-af-examples.description=This installer will guide you to install \ Cmobilecom AF Examples {0}{1} on this computer.cmobilecom-af-examples is the software name specified in build.properties. {0} and {1} will be resolved to software version and target platform respectively.
appRootDir/resources/
bundle/messages.properties
messages_*.properties
images/
Application resource bundles (resources/bundle/*) are used for resolving instance-type
display names and expression #{bundle.Key} in system-config.xml. For example,
conf/system-config.xml:
<system-config> <description><![CDATA[ #{bundle.About_CmobilecomAF_Examples} <p> <a href="http://Cmobilecom-AF-Examples.com" target="_blank">http://Cmobilecom-AF-Examples.com</a> ]]> </description> ... </system-config>The description is shown as application overview in help page. #{bundle.About_CmobilecomAF_Examples} will be resolved by application resource bundles. For example, appRootDir/resources/bundle/messages.properties:
CmobilecomAF_Examples=Cmobilecom AF Examples About_CmobilecomAF_Examples=Cmobilecom AF examples demonstrate how to develop a \ Cmobilecom AF application.
test/ src/test/ java/ resources/ test-automation/ webdriver/ chromedriver.exe edgedriver.exe fileupload/ <installation-dir>/The subdirectory "test-automation" contains web drivers, files to upload, and installation directories for test automation. Download web drivers (correct versions) for the web browsers used for testing. Put files for upload under fileupload directory if they are needed for test automation. When running installer for test automation, the app will be installed under a subdirectory(e.g., win64_mysql) of the test-automation directory.
If running tests using docker Selenium Grid, the webdriver directory is not needed.
See Testing on how to write code for test automation.
Profile Web App Test Client ----------------------------------------------------------------- debug debug N/A production production N/A debug_test (dt) debug non-debug production_test (pt) production non-debug debug_test_debug (dtd) debug debug production_test_debug (ptd) production debugChange current working directory to the root project web/docker directory to run docker commands.
cd appRootDir/web/docker
# run production version (profile: production) docker-compose --profile production up http://localhost:8080
# run debug version (profile: debug) docker-compose --profile debug up http://localhost:8080 attach debugger to port 8787
# test web app debug version docker-compose --profile dt up # test web app production version docker-compose --profile pt up # test web app debug version and test client debug # debugging test client: set environment TEST_DEBUG_JVM=true, # and attach debugger to port 5005 docker-compose --profile dtd up # test web app production version and test client debug # debugging test client: set environment TEST_DEBUG_JVM=true, # and attach debugger to port 5005 docker-compose --profile ptd up # see running sessions (password: secret) of Selenium Grid http://localhost:4444 http://localhost:7900 # view test reports on host appRootDir/test/build/reports/tests/test/index.htmlEnvironment variables for test options:
cmobilecomAFDistsDir/cmobilecom-af-<version> (CMOBILECOM_AF_DIR)
Linux: export CMOBILECOM_AF_DIR=/path/cmobilecom-af-<version> Windows: set CMOBILECOM_AF_DIR=C:\path\cmobilecom-af-<version>
cd web gradle wrapper
gradlew :app:assemble [options] options: -Pdebug: debug build (for building war only) -Psnapshot: snapshot build -Psnapshot.date: snapshot timestamp(YYYYMMDD), default current dateSnapshot build will append timestamp to the versions of all modules and app.
gradlew deployWarToLocal [options]
gradlew startServer gradlew stopServer
gradlew enableServerDebugIt will enable server(tomcat) JVM debug(listen on port 8787), and change the log level to DEBUG in ${cmobilecom.home}/conf/logback.xml. Server restart is required.
gradlew stopServer gradlew startServer
Log files are under ${cmobilecom.home}/log/ and ${cmobilecom.home}/tomcat-<version>/logs/.
gradlew copySystemConfigToLocalRestart server to load the new configuration.
gradlew cleanInstall gradlew clean cleanInstall // clean both build and install
gradlew copySitesToLocal
gradlew generateSchema -Ppu=hr -PjdbcUrl=jdbc:mysql://localhost:3306/test_db_hr -PjdbcUser=test_user -PjdbcPassword=welcome -Psystem.schema=test_db -Puser.schema=test_dboracle db:
gradlew generateSchema -Ppu=hr -PjdbcUrl=jdbc:oracle:thin:@//localhost:1521/XEPDB1 -PjdbcUser=test_db_hr -PjdbcPassword=welcome -Psystem.schema=test_db -Puser.schema=test_dbproperties:
pu: persistence unit name jdbcUrl: JDBC connection URL jdbcUser: JDBC connection user jdbcPassword: JDBC connection password system.schema: system instance schema name for resolving expression #{system.schema} in orm.xml. default: empty string. user.schema: user table schema name for resolving expression #{user.schema} in orm.xml. default: empty string.Both drop and create actions will be taken to generate schema objects in database and files. For database, all schema objects will be dropped before creating new schema objects. Create new empty database schemas for schema object generation. Database privileges required include: create tables, drop tables. Generated schema drop and create sql files are put under
rootProjectDir/build/schema-gen/<persistence-unit-name>/
Run silent install:
gradlew install [options] -Pcmobilecom.home=<name>: installation directory, overriding default and environment variable CMOBILECOM_HOME. default is ../test/test-automation/install/<os_dbms>. -Pos=[win32|win64|linux]: operating system. empty for platform-independent without application server bundled. Override environment CMOBILECOM_AF_OS. -Pdbms=[mysql|oracle]: database type. Override environment CMOBILECOM_AF_DBMS. -Pdbms.host=<host_name>: dbms host name or ip address. default: localhost. -Pdbms.port=<port_number>: dbms port number overriding default port number. -Pdb.schemaName=<name>: specify database schema name overriding default generated name. If the database schema already exists, it will be used without change. -Pdb.rootPassword=<password>: db root password, overriding that in answer properties. Must match database root password. -Pdb.username=<username>: db username, overriding that in answer properties. Do not override username if it is the same as schema name (e.g., oracle database). -Pdb.password=<password>: db password for the user, overriding that in answer properties. The password for an existing user will be correct. -Pdb.userHost=<host_name>: db client host or ip address. default: localhost. For example, user <db.username>@<db.userHost> will be created for mysql database. -Pas.port.http=<port_number>: application server HTTP port overriding that in answer properties. -Pas.port.https=<port_number>: application server HTTPS port overriding that in answer properties. -Pinstall.init.db=[true|false] whether to init database during installation. If false, database will be initialized when application is started. Default is true. -Ptest.automation[=true|false]: whether to enable/disable test automation. Default is false. -Ptest.noInternet[=true|false]: whether to turn off all features that require internet connection (e.g., captcha) for test automation. Default is false.For example: install, start server and run test automation:
gradlew install startServer -Ptest.automation=true gradlew :test:test
Windows: C:\Windows\System32\drivers\etc\hosts Linux: /etc/hosts
appRootDir/test/test-automation/ webdriver/ chromedriver.exe edgedriver.exe geckodriver.exe ...
gradlew :test:test [--tests filter]Open test report html on host web browser for local test, remote test or test with docker-compose:
gradlew :test:openReport
gradlew :test:test -Prerun -PuserNo=<userNumber> -PgotoExec=<execPoint> userNo: the user number for the previous test. gotoExec: run from an exec point, e.g. Main.HR.create_expenseClaims.ExecPoint format: instanceIdentifier.moduleName.execPointName.
docker-compose --profile dt up gradlew clean cleanInstall install -Ptest.automation=true gradlew :test:test -Premote=true [-PremoteURL=<testServerURL>]If remoteURL is not specified, default to:
http://localhost:4444The browser and web driver on the remote test server (docker image) will be used.
Live remote test sessions: http://localhost:4444
Test reports are on host as if running a local test.gradlew assemble [options] // build all installer zips gradlew installerZip_[targetOs] // build installer zip for one target OS gradlew installerZip // build installer zip (platform-independent) without tomcat targetOs: win32, win64 or linux. options: -Psnapshot: snapshot build -Psnapshot.date: snapshot timestamp(YYYYMMDD), default current dateTo build installer zip for a targetOS, cmobilecom-af-<version>-<targetOS>.zip needs to be downloaded and put under cmobilecomAFDistsDir (the parent directory of CMOBILECOM_AF_DIR). For example,
cmobilecomAFDistsDir/ cmobilecom-af-<version>.zip cmobilecom-af-<version>-linux.zip cmobilecom-af-<version>-win32.zip cmobilecom-af-<version>-win64.zip cmobilecom-af-<version>/ (CMOBILECOM_AF_DIR)
ext { // docker map for task createDockerFiles docker = [ dockerignoreDir : '..', // relative to rootProject.projectDir ignoreNginxConf : false, env : [ // docker-compose.yml dir: ./docker BUILD_CONTEXT : '../..', // relative to docker-compose.yml DOCKER_FILE_DIR : 'web/docker', // relative to build context IMAGE_NAME : 'foo/bar', DB_ROOT_PASSWORD : 'welcome1', DB_PASSWORD : 'welcome2', ], PREPARE_BUILD : ''' WORKDIR $CMOBILECOM_APP_DIR/$SOFTWARE_NAME COPY . . WORKDIR web ''' ] }Generate Dockerfile, docker-compose.yml, .env, .dockerignore and nginx.conf files:
gradlew createDockerFilesDockerfile and docker-compose.yml are generated into subdirectory "docker" from templates under $CMOBILECOM_AF_DIR/build-common/docker, and all the name/value pairs in the docker.env will be added to the .env files overriding default values.
Dockerfile multi-stage build:
build-prepare ------------- | build-release ----------------- / | \ web-production build-debug test-client-non-debug -------------- ----------- --------------------- / \ web-debug test-client-debug --------- -----------------Replacement blocks in Dockerfile:
# --BEGIN_PREPARE_BUILD # --END_PREPARE_BUILD
# --BEGIN_PREPARE_BUILD_RELEASE # --END_PREPARE_BUILD_RELEASE
# --BEGIN_PREPARE_BUILD_DEBUG # --END_PREPARE_BUILD_DEBUG
# --BEGIN_PREPARE_TEST_CLIENT_NON_DEBUG # --END_PREPARE_TEST_CLIENT_NON_DEBUG
# --BEGIN_PREPARE_TEST_CLIENT_DEBUG # --END_PREPARE_TEST_CLIENT_DEBUG
# --BEGIN_COPY_NGINX_CONF # --END_COPY_NGINX_CONF
-Pdb.rootPassword=password1 -Pdb.password=password2 -PlogLevel=info