In a previous post, we talked about automating the installation of fusion middleware binaries. Now let’s review how we can create ADF Domain using scripts. This process will create single node domain, but you can extend it to meet your needs.
You can download necessary scripts from HERE.
If you are on Windows use createDomain.bat and for Unix use createDomain.sh. Both scripts have variables defined in first 21 lines, modify them according to your requirements before execution.
Here are scripts for quick reference.
createWLSDomain.py
from java.util import Date from java.lang import System def fdLog(methodName, message): print str(Date()) + " - " + str(methodName) + " - " + str(message) # Using java.lang.System as os.getenv has issues at times # in WLST script def fdGetEnv(environmentKey): val=System.getenv(environmentKey) if val == None: raise "Environment variable not found " + str(environmentKey) return val def fdGetEnvOfDefault(environmentKey, defaultValue): val=System.getenv(environmentKey) if val == None: val=defaultValue return val def fdDisconnect(): thisMethodName="fdDisconnect" fdLog(thisMethodName, "Entering") disconnect() fdLog(thisMethodName, "Exiting") def fdConnect(): thisMethodName="fdConnect" fdLog(thisMethodName, "Entering") user=fdGetEnv('FDWLS_ADMIN_USER') password=fdGetEnv('FDWLS_ADMIN_PASSWORD') listenaddress=fdGetEnv('FDWLS_ADMIN_LISTEN_ADDRESS') listenport=fdGetEnv('FDWLS_ADMIN_LISTEN_PORT') isusessl=fdGetEnvOfDefault('FDWLS_ADMIN_USE_SSL', False) adminurl="t3://" + str(listenaddress) + ":" + str(listenport) if isusessl == True: adminurl="t3s://" + str(listenaddress) + ":" + str(listenport) connect(user,password,adminurl) fdLog(thisMethodName, "Exiting") def fdReadDomain(): thisMethodName="fdReadDomain" domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "Reading domain from " + str(domainDir)) if os.path.exists(domainDir) == False: raise "Domain directory does not exists " + str(domainDir) readDomain(domainDir) def fdWriteDomain(): thisMethodName="fdWriteDomain" domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "Writing domain to " + str(domainDir)) writeDomain(domainDir) def fdUpdateDomain(): thisMethodName="fdWriteDomain" domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "Updating domain " + str(domainDir)) updateDomain() closeDomain() def createBootPropertiesFile(directoryPath, fileName, username, password): # writing unencryted credentials, it will be encrypted when server is started. thisMethodName="createBootPropertiesFile" fdLog(thisMethodName, "Create " + str(fileName) + " file in " + str(directoryPath)) serverDir = File(directoryPath) bool = serverDir.mkdirs() fileNew=open(directoryPath + '/'+fileName, 'w') fileNew.write('username=%s\n' % username) fileNew.write('password=%s\n' % password) fileNew.flush() fileNew.close() # FIXME - implement derive logic to support 11g def deriveWebLogicTemplateFilePath(): thisMethodName="deriveWebLogicTemplateFilePath" oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') templateFilePath=oracleMWHome + "/wlserver/common/templates/wls/wls.jar" fdLog(thisMethodName, "WebLogic template file path " + str(templateFilePath)) if os.path.exists(templateFilePath) == False: raise "WebLogic template not found " + str(templateFilePath) return templateFilePath # FIXME - implement derive logic to support 11g and other version of 12c def deriveADFTemplateFilePath(): thisMethodName="deriveADFTemplateFilePath" oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') templateFilePath=oracleMWHome + "/oracle_common/common/templates/wls/oracle.jrf_template_12.1.3.jar" fdLog(thisMethodName, "ADF template file path " + str(templateFilePath)) if os.path.exists(templateFilePath) == False: raise "ADF template not found " + str(templateFilePath) return templateFilePath # FIXME - implement derive logic to support 11g and other version of 12c def deriveFMWEMTemplateFilePath(): thisMethodName="deriveFMWEMTemplateFilePath" oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') templateFilePath=oracleMWHome + "/em/common/templates/wls/oracle.em_wls_template_12.1.3.jar" fdLog(thisMethodName, "FMW EM template file path " + str(templateFilePath)) if os.path.exists(templateFilePath) == False: raise "FMW EM template not found " + str(templateFilePath) return templateFilePath # Common code - ends here.... thisMethodName="main" # update these variables if necessary DEVELOPMENT_MODE=False # first get all values that we may need ( using Property names defined by FlexDeploy ) domainName=fdGetEnv('FDWLS_DOMAIN_NAME') fdLog(thisMethodName, "domainName=" + str(domainName)) domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "domainDir=" + str(domainDir)) adminServerUser=fdGetEnv('FDWLS_ADMIN_USER') fdLog(thisMethodName, "adminServerUser=" + str(adminServerUser)) adminServerPassword=fdGetEnv('FDWLS_ADMIN_PASSWORD') adminServerListenaddress=fdGetEnv('FDWLS_ADMIN_LISTEN_ADDRESS') fdLog(thisMethodName, "adminServerListenaddress=" + str(adminServerListenaddress)) adminServerListenport=fdGetEnv('FDWLS_ADMIN_LISTEN_PORT') fdLog(thisMethodName, "adminServerListenport=" + str(adminServerListenport)) oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') fdLog(thisMethodName, "oracleMWHome=" + str(oracleMWHome)) applicationsHome=fdGetEnv('FDWLS_BASE_INSTALL_DIRECTORY') fdLog(thisMethodName, "applicationsHome=" + str(applicationsHome)) nmHost=fdGetEnv('FDWLS_NODEMANAGER_HOST') fdLog(thisMethodName, "nmHost=" + str(nmHost)) nmName=nmHost.split('.')[0] fdLog(thisMethodName, "nmName=" + str(nmName)) nmPort=fdGetEnv('FDWLS_NODEMANAGER_PORT') fdLog(thisMethodName, "nmPort=" + str(nmPort)) nmUser=fdGetEnv('FDWLS_NODEMANAGER_USER') fdLog(thisMethodName, "nmUser=" + str(nmUser)) nmPassword=fdGetEnv('FDWLS_NODEMANAGER_PASSWORD') nmType=fdGetEnv('FDWLS_NODEMANAGER_TYPE') fdLog(thisMethodName, "nmType=" + str(nmType)) if domainDir.endswith(domainName) == False: raise "invalid domain dir, domain name must be last folder " + str(domainDir) if applicationsHome.endswith(domainName) == False: raise "invalid applications dir, domain name must be last folder " + str(applicationsHome) wlsTemplateFilePath=deriveWebLogicTemplateFilePath() fdLog(thisMethodName, "Start domain creation with - " + str(wlsTemplateFilePath)) readTemplate(wlsTemplateFilePath) fdLog(thisMethodName, "Update weblogic mode") if DEVELOPMENT_MODE == True: cmo.setProductionModeEnabled(False) else: cmo.setProductionModeEnabled(True) fdLog(thisMethodName, "Setup AdminServer.") cd('/Servers/AdminServer') # name of adminserver set('Name', 'AdminServer') cd('/Servers/AdminServer') set('ListenAddress', adminServerListenaddress) set('ListenPort', int(adminServerListenport)) cd('/Servers/AdminServer') create('AdminServer','SSL') cd('SSL/AdminServer') set('Enabled', 'False') set('HostNameVerificationIgnored', 'True') fdLog(thisMethodName, "Setup NodeManager.") cd('/') create(nmName,'UnixMachine') cd('UnixMachine/' + nmName) create(nmName,'NodeManager') cd('NodeManager/' + nmName) set('ListenAddress', nmHost) set('ListenPort', int(nmPort)) set('NMType', nmType) fdLog(thisMethodName, "Assign NodeManager for AdminServer.") cd('/Servers/AdminServer') set('Machine',nmName) setOption( "AppDir", applicationsHome ) fdLog(thisMethodName, "Setup weblogic user credentials.") cd('/') cd('Security/base_domain/User/weblogic') # template has weblogic user, but we may have some other user name, so update it set('Name', adminServerUser) cmo.setPassword(adminServerPassword) if DEVELOPMENT_MODE == True: setOption('ServerStartMode', 'dev') else: setOption('ServerStartMode', 'prod') fdWriteDomain() closeTemplate() applicationsHomeFileObject=File(applicationsHome) fdLog(thisMethodName, "Creating " + str(applicationsHome)) applicationsHomeFileObject.mkdirs() # admin server boot.properties, so that we don't have to enter password on start createBootPropertiesFile(domainDir + '/servers/AdminServer/security','boot.properties', adminServerUser, adminServerPassword) # node manager user and password, so that communication would work between AdminServer and Node Manager createBootPropertiesFile(domainDir+'/config/nodemanager', 'nm_password.properties', nmUser, nmPassword) # read and update node manager credentials fdReadDomain() #nmPasswordEncrypted = encrypt(nmPassword, domainDir) cd('/SecurityConfiguration/' + domainName) #set('NodeManagerUsername', nmUser) cmo.setNodeManagerUsername(nmUser) cmo.setNodeManagerPasswordEncrypted(nmPassword) #set('NodeManagerPasswordEncrypted', nmPasswordEncrypted) cd('/') setOption( "AppDir", applicationsHome ) fdUpdateDomain()
createADFDomain.py
from java.util import Date from java.lang import System def fdLog(methodName, message): print str(Date()) + " - " + str(methodName) + " - " + str(message) # Using java.lang.System as os.getenv has issues at times # in WLST script def fdGetEnv(environmentKey): val=System.getenv(environmentKey) if val == None: raise "Environment variable not found " + str(environmentKey) return val def fdGetEnvOfDefault(environmentKey, defaultValue): val=System.getenv(environmentKey) if val == None: val=defaultValue return val def fdDisconnect(): thisMethodName="fdDisconnect" fdLog(thisMethodName, "Entering") disconnect() fdLog(thisMethodName, "Exiting") def fdConnect(): thisMethodName="fdConnect" fdLog(thisMethodName, "Entering") user=fdGetEnv('FDWLS_ADMIN_USER') password=fdGetEnv('FDWLS_ADMIN_PASSWORD') listenaddress=fdGetEnv('FDWLS_ADMIN_LISTEN_ADDRESS') listenport=fdGetEnv('FDWLS_ADMIN_LISTEN_PORT') isusessl=fdGetEnvOfDefault('FDWLS_ADMIN_USE_SSL', False) adminurl="t3://" + str(listenaddress) + ":" + str(listenport) if isusessl == True: adminurl="t3s://" + str(listenaddress) + ":" + str(listenport) connect(user,password,adminurl) fdLog(thisMethodName, "Exiting") def fdReadDomain(): thisMethodName="fdReadDomain" domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "Reading domain from " + str(domainDir)) if os.path.exists(domainDir) == False: raise "Domain directory does not exists " + str(domainDir) readDomain(domainDir) def fdWriteDomain(): thisMethodName="fdWriteDomain" domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "Writing domain to " + str(domainDir)) writeDomain(domainDir) def fdUpdateDomain(): thisMethodName="fdWriteDomain" domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "Updating domain " + str(domainDir)) updateDomain() closeDomain() def createBootPropertiesFile(directoryPath,fileName, username, password): # writing unencryted credentials, it will be encrypted when server is started. thisMethodName="createBootPropertiesFile" fdLog(thisMethodName, "Create boot.properties file in " + str(directoryPath)) serverDir = File(directoryPath) bool = serverDir.mkdirs() fileNew=open(directoryPath + '/'+fileName, 'w') fileNew.write('username=%s\n' % username) fileNew.write('password=%s\n' % password) fileNew.flush() fileNew.close() # FIXME - implement derive logic to support 11g def deriveWebLogicTemplateFilePath(): thisMethodName="deriveWebLogicTemplateFilePath" oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') templateFilePath=oracleMWHome + "/wlserver/common/templates/wls/wls.jar" fdLog(thisMethodName, "WebLogic template file path " + str(templateFilePath)) if os.path.exists(templateFilePath) == False: raise "WebLogic template not found " + str(templateFilePath) return templateFilePath # FIXME - implement derive logic to support 11g and other version of 12c def deriveADFTemplateFilePath(): thisMethodName="deriveADFTemplateFilePath" oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') templateFilePath=oracleMWHome + "/oracle_common/common/templates/wls/oracle.jrf_template_12.1.3.jar" fdLog(thisMethodName, "ADF template file path " + str(templateFilePath)) if os.path.exists(templateFilePath) == False: raise "ADF template not found " + str(templateFilePath) return templateFilePath # FIXME - implement derive logic to support 11g and other version of 12c def deriveFMWEMTemplateFilePath(): thisMethodName="deriveFMWEMTemplateFilePath" oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') templateFilePath=oracleMWHome + "/em/common/templates/wls/oracle.em_wls_template_12.1.3.jar" fdLog(thisMethodName, "FMW EM template file path " + str(templateFilePath)) if os.path.exists(templateFilePath) == False: raise "FMW EM template not found " + str(templateFilePath) return templateFilePath # Common code - ends here.... thisMethodName="main" # update these variables if necessary DEVELOPMENT_MODE=False # first get all values that we may need ( using Property names defined by FlexDeploy ) domainName=fdGetEnv('FDWLS_DOMAIN_NAME') fdLog(thisMethodName, "domainName=" + str(domainName)) domainDir=fdGetEnv('FDWLS_ADMIN_DOMAIN_DIRECTORY') fdLog(thisMethodName, "domainDir=" + str(domainDir)) adminServerUser=fdGetEnv('FDWLS_ADMIN_USER') fdLog(thisMethodName, "adminServerUser=" + str(adminServerUser)) adminServerPassword=fdGetEnv('FDWLS_ADMIN_PASSWORD') adminServerListenaddress=fdGetEnv('FDWLS_ADMIN_LISTEN_ADDRESS') fdLog(thisMethodName, "adminServerListenaddress=" + str(adminServerListenaddress)) adminServerListenport=fdGetEnv('FDWLS_ADMIN_LISTEN_PORT') fdLog(thisMethodName, "adminServerListenport=" + str(adminServerListenport)) oracleMWHome=fdGetEnv('FD_ORACLE_MW_HOME') fdLog(thisMethodName, "oracleMWHome=" + str(oracleMWHome)) applicationsHome=fdGetEnv('FDWLS_BASE_INSTALL_DIRECTORY') fdLog(thisMethodName, "applicationsHome=" + str(applicationsHome)) nmHost=fdGetEnv('FDWLS_NODEMANAGER_HOST') fdLog(thisMethodName, "nmHost=" + str(nmHost)) nmName=nmHost.split('.')[0] fdLog(thisMethodName, "nmName=" + str(nmName)) nmPort=fdGetEnv('FDWLS_NODEMANAGER_PORT') fdLog(thisMethodName, "nmPort=" + str(nmPort)) nmUser=fdGetEnv('FDWLS_NODEMANAGER_USER') fdLog(thisMethodName, "nmUser=" + str(nmUser)) nmPassword=fdGetEnv('FDWLS_NODEMANAGER_PASSWORD') nmType=fdGetEnv('FDWLS_NODEMANAGER_TYPE') fdLog(thisMethodName, "nmType=" + str(nmType)) if domainDir.endswith(domainName) == False: raise "invalid domain dir, domain name must be last folder " + str(domainDir) if applicationsHome.endswith(domainName) == False: raise "invalid applications dir, domain name must be last folder " + str(applicationsHome) rcuDbUrl=fdGetEnv('FLX_INSTALL_RCU_DB_URL') fdLog(thisMethodName, "rcuDbUrl=" + str(rcuDbUrl)) rcuDbUser=fdGetEnv('FLX_INSTALL_RCU_DB_USER') fdLog(thisMethodName, "rcuDbUser=" + str(rcuDbUser)) if rcuDbUser.upper().endswith('_STB') == False: raise "RCU user must end with _STB " + str(rcuDbUser) rcuDbPassword=fdGetEnv('FLX_INSTALL_RCU_DB_PASSWORD') # read and update domain with adf related templates fdReadDomain() adfTemplateFilePath=deriveADFTemplateFilePath() fdLog(thisMethodName, "Update domain with - " + str(adfTemplateFilePath)) addTemplate(adfTemplateFilePath) fdLog(thisMethodName, "Read database services information from RCU schemas") cd('/JDBCSystemResource/LocalSvcTblDataSource/JdbcResource/LocalSvcTblDataSource/JDBCDriverParams/NO_NAME_0') set('DriverName', 'oracle.jdbc.OracleDriver') set('URL', rcuDbUrl) set('PasswordEncrypted', rcuDbPassword) cd('Properties/NO_NAME_0/Property/user') set('Value', rcuDbUser) fdLog(thisMethodName, "Read database services by calling getDatabaseDefaults.") getDatabaseDefaults() fmwEMTemplateFilePath=deriveFMWEMTemplateFilePath() fdLog(thisMethodName, "Update domain with - " + str(fmwEMTemplateFilePath)) addTemplate(fmwEMTemplateFilePath) setOption( "AppDir", applicationsHome ) fdUpdateDomain()
createDomain.bat
REM MODIFY FOLLOWING VALUES HERE BEFORE START REM modify if you have installed software in different folder set ORACLE_INSTALL_HOME=c:/u01/oracle/products/fmw1213 set JAVA_HOME=C:/installs/Java/jdk1.7.0_65 REM modify this to use different domain name set DOMAIN_LOGICAL_NAME=adf1 set DOMAIN_PASSWORD=welcome1 set WLS_SCHEMA_PASSWORD=welcome1 REM fill in sys password here set SYS_DB_PASSWORD=welcome1 REM fill in value here (either host:port:sid or host:port@servicename) set DB_CONNECT_STRING=localhost:1521:xe REM modify if you are using different folder structure, domain will be created under this structure set ORACLE_CONFIG_DIRECTORY=c:/u01/oracle/config set FDWLS_ADMIN_LISTEN_ADDRESS=%COMPUTERNAME% set FDWLS_ADMIN_LISTEN_PORT=7001 set FDWLS_NODEMANAGER_HOST=%COMPUTERNAME% set FDWLS_NODEMANAGER_PORT=5556 set FDWLS_NODEMANAGER_TYPE=SSL REM Process starts here echo > PasswordFile.txt echo %SYS_DB_PASSWORD%>PasswordFile.txt echo %WLS_SCHEMA_PASSWORD%>>PasswordFile.txt set WLS_SCHEMA_PREFIX=%DOMAIN_LOGICAL_NAME% call %ORACLE_INSTALL_HOME%/oracle_common/bin/rcu.bat -silent -databaseType ORACLE -createRepository -connectString %DB_CONNECT_STRING% -dbUser sys -dbRole SYSDBA -useSamePasswordForAllSchemaUsers true -schemaPrefix %WLS_SCHEMA_PREFIX% -component STB -component MDS -component IAU -component IAU_APPEND -component IAU_VIEWER -component OPSS -component WLS -f < PasswordFile.txt del PasswordFile.txt set FDWLS_DOMAIN_NAME=%DOMAIN_LOGICAL_NAME%_domain set FDWLS_ADMIN_DOMAIN_DIRECTORY=%ORACLE_CONFIG_DIRECTORY%/domains/%FDWLS_DOMAIN_NAME% set FDWLS_ADMIN_USER=weblogic set FDWLS_ADMIN_PASSWORD=%DOMAIN_PASSWORD% set FD_ORACLE_MW_HOME=%ORACLE_INSTALL_HOME% set FDWLS_BASE_INSTALL_DIRECTORY=%ORACLE_CONFIG_DIRECTORY%/applications/%FDWLS_DOMAIN_NAME% set FDWLS_NODEMANAGER_USER=weblogic set FDWLS_NODEMANAGER_PASSWORD=%DOMAIN_PASSWORD% REM FILL IN JDBC URL HERE to RCU schema database, For example - jdbc:oracle:thin:@host:port:sid or jdbc:oracle:thin:@host:port/servicename set FLX_INSTALL_RCU_DB_URL=jdbc:oracle:thin:@%DB_CONNECT_STRING% set FLX_INSTALL_RCU_DB_USER=%WLS_SCHEMA_PREFIX%_STB set FLX_INSTALL_RCU_DB_PASSWORD=%WLS_SCHEMA_PASSWORD% call %FD_ORACLE_MW_HOME%/wlserver/common/bin/wlst.cmd createWLSDomain.py call %FD_ORACLE_MW_HOME%/wlserver/common/bin/wlst.cmd createADFDomain.py
createDomain.sh
# FILL IN VALUES HERE BEFORE START # modify if you have installed software in different folder export ORACLE_INSTALL_HOME=/u01/oracle/products/fmw1213 export JAVA_HOME=/u01/oracle/products/java/jdk1.7.0_65 # modify this to use different domain name export DOMAIN_LOGICAL_NAME=adf1 export DOMAIN_PASSWORD=welcome1 export WLS_SCHEMA_PASSWORD=welcome1 # fill in sys password here export SYS_DB_PASSWORD=welcome1 # fill in value here (either host:port:sid or host:port@servicename) export DB_CONNECT_STRING=localhost:1521:xe # modify if you are using different folder structure, domain will be created under this structure export ORACLE_CONFIG_DIRECTORY=/u01/oracle/config export FDWLS_ADMIN_LISTEN_ADDRESS=`hostname` export FDWLS_ADMIN_LISTEN_PORT=7001 export FDWLS_NODEMANAGER_HOST=`hostname` export FDWLS_NODEMANAGER_PORT=5556 export FDWLS_NODEMANAGER_TYPE=SSL # Process starts here > PasswordFile.txt chmod 700 PasswordFile.txt echo $SYS_DB_PASSWORD>PasswordFile.txt echo $WLS_SCHEMA_PASSWORD>>PasswordFile.txt export WLS_SCHEMA_PREFIX=${DOMAIN_LOGICAL_NAME} ${ORACLE_INSTALL_HOME}/oracle_common/bin/rcu -silent -databaseType ORACLE -createRepository -connectString ${DB_CONNECT_STRING} -dbUser sys -dbRole SYSDBA -useSamePasswordForAllSchemaUsers true -schemaPrefix ${WLS_SCHEMA_PREFIX} -component STB -component MDS -component IAU -component IAU_APPEND -component IAU_VIEWER -component OPSS -component WLS -f < PasswordFile.txt rm PasswordFile.txt export FDWLS_DOMAIN_NAME=${DOMAIN_LOGICAL_NAME}_domain export FDWLS_ADMIN_DOMAIN_DIRECTORY=${ORACLE_CONFIG_DIRECTORY}/domains/${FDWLS_DOMAIN_NAME} export FDWLS_ADMIN_USER=weblogic export FDWLS_ADMIN_PASSWORD=${DOMAIN_PASSWORD} export FD_ORACLE_MW_HOME=${ORACLE_INSTALL_HOME} export FDWLS_BASE_INSTALL_DIRECTORY=${ORACLE_CONFIG_DIRECTORY}/applications/${FDWLS_DOMAIN_NAME} export FDWLS_NODEMANAGER_USER=weblogic export FDWLS_NODEMANAGER_PASSWORD=${DOMAIN_PASSWORD} # FILL IN JDBC URL HERE to RCU schema database, For example - jdbc:oracle:thin:@host:port:sid or jdbc:oracle:thin:@host:port/servicename export FLX_INSTALL_RCU_DB_URL=jdbc:oracle:thin:@${DB_CONNECT_STRING} export FLX_INSTALL_RCU_DB_USER=${WLS_SCHEMA_PREFIX}_STB export FLX_INSTALL_RCU_DB_PASSWORD=${WLS_SCHEMA_PASSWORD} ${FD_ORACLE_MW_HOME}/wlserver/common/bin/wlst.sh createWLSDomain.py ${FD_ORACLE_MW_HOME}/wlserver/common/bin/wlst.sh createADFDomain.py
Here is example of Windows execution.
You can start AdminServer and NodeManager as shown below.
You can customize the provided files to create multiple node domain easily.
Additional Resources: