<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
! CDDL HEADER START
!
! The contents of this file are subject to the terms of the
! Common Development and Distribution License, Version 1.0 only
! (the "License"). You may not use this file except in compliance
! with the License.
!
! You can obtain a copy of the license at
! See the License for the specific language governing permissions
! and limitations under the License.
!
! When distributing Covered Code, include this CDDL HEADER in each
! file and include the License file at
! trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
! add the following below this CDDL HEADER, with the fields enclosed
! by brackets "[]" replaced with your own identifying information:
! Portions Copyright [yyyy] [name of copyright owner]
!
! CDDL HEADER END
!
! Copyright 2009-2010 Sun Microsystems, Inc.
! Portions Copyright 2011-2012 ForgeRock AS.
! -->
<stax>
<defaultcall function="fractional-replication_setup"/>
<function name="fractional-replication_setup">
<function-map-args>
<function-arg-def name="topologyFile"
type="optional"
default="'%s/basic_topology.txt' % REPLICATION_CONFIG_DIR">
<function-arg-description>
Pathname to file describing the topology.
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="secureReplication"
type="optional"
default="None">
<function-arg-description>
Encrypt replication channels
</function-arg-description>
<function-arg-property name="type" value="boolean"/>
</function-arg-def>
<function-arg-def name="dataFile"
type="optional"
default="None">
<function-arg-description>
initialisation.
If no filename provided (default), the topology won't be initialised.
If a filename provided, after initialisation the suffix will be
backed up under masterBackupDir.
</function-arg-description>
<function-arg-property name="type" value="filename"/>
</function-arg-def>
<function-arg-def name="isolateLdapServers"
type="optional"
default="None">
<function-arg-description>
Break the cross-reference between Ldap Servers and Replication Servers
(i.e. make LS1 point to RS1 exclusively, LS2 to RS2, etc.)
</function-arg-description>
<function-arg-property name="type" value="boolean"/>
</function-arg-def>
<function-arg-def name="enableDebugLogs"
type="optional"
default="None">
<function-arg-description>
Enable de debug logs
</function-arg-description>
<function-arg-property name="type" value="boolean"/>
</function-arg-def>
</function-map-args>
<sequence>
<block name="'fractional-replication-startup'">
<testcase name="getTestCaseName('Fractional Repl Setup')">
<try>
<sequence>
<call function="'testCase_Preamble'"/>
<message>
'Create DS topology as described in %s' % topologyFile
</message>
<call function="'createTopology'">
{ 'topologyDescFile' : topologyFile,
'sharedDataFolder' : 'fractional-replication',
'splitReplicationServers' : globalSplitServers,
'fileExtensions' : ['template'],
}
</call>
<call function="'checkRC'">
{ 'returncode' : RC ,
'result' : STAXResult
}
</call>
<!-- Setup variables -->
<script>
client = _topologyServerList[0]
clientHost = client.getHostname()
clientPath = '%s/%s' % (client.getDir(),OPENDSNAME)
clientDataDir = '%s' % client.getDataDir()
server1 = _topologyServerList[0]
server2 = _topologyServerList[1]
master = _topologyServerList[0]
masterHost = master.getHostname()
masterReplicationServer = master.getChangelogServer()
masterPath = '%s/%s' % (master.getDir(),OPENDSNAME)
masterDataDir = master.getDataDir()
masterTempDir = master.getTmpDir()
synchroSuffix = master.getSynchronizedSuffixList()[0].getSuffixDn()
consumerList = _topologyServerList[1:]
domainMap = STAXGlobal({})
schemaMap = STAXGlobal({})
</script>
<if expr="dataFile">
<sequence>
<script>
importDataFile = '%s/fractional-replication/%s' % (masterDataDir, dataFile)
</script>
<message>
'Import data from %s into server %s:%s' \
% (importDataFile, masterHost, master.getPort())
</message>
<!-- Import data into "master" Directory Server -->
<call function="'ImportLdifWithScript'">
{ 'location' : masterHost,
'dsPath' : masterPath,
'backEnd' : DIRECTORY_INSTANCE_BE,
'ldifFile' : importDataFile
}
</call>
<!-- Backup "master" server -->
<call function="'backup'">
{ 'location' : masterHost,
'dsPath' : masterPath,
'backupDir' : masterBackupDir
}
</call>
</sequence>
</if>
<!-- Start the servers in the topology -->
<call function="'startServers'">
[_splitServerList]
</call>
<paralleliterate var="s" in="_splitServerList">
<sequence>
<script>
ls = '%s:%s' % (s.getHostname(), s.getPort())
</script>
<call function="'getSchemaDict'">
{ 'location' : s.getHostname(),
'dsPath' : '%s/%s' % (s.getDir(),OPENDSNAME),
'server' : s,
}
</call>
<if expr="STAXResult">
<script>
schemaMap[ls] = STAXResult
</script>
<else>
<sequence>
<message>'Failed getting the schema for ' % ls</message>
<break/>
</sequence>
</else>
</if>
</sequence>
</paralleliterate>
<if expr="len(_topologyReplServerList) != 0">
<paralleliterate var="replServer" in="_topologyReplServerList">
<!-- Remove userRoot backend from replication servers -->
<sequence>
<message>
'Remove userRoot backend from replication server %s:%s' % \
</message>
<call function="'dsconfig'">
{ 'location' : replServer.getHostname(),
'dsPath' : '%s/%s' \
% (replServer.getDir(),OPENDSNAME),
'dsInstanceHost' : replServer.getHostname(),
'dsInstanceAdminPort' : replServer.getAdminPort(),
'dsInstanceDn' : replServer.getRootDn(),
'dsInstancePswd' : replServer.getRootPwd(),
'subcommand' : 'delete-backend',
'objectType' : 'backend-name',
'objectName' : 'userRoot'
}
</call>
</sequence>
</paralleliterate>
</if>
<iterate var="server" in="_splitServerList[1:]">
<sequence>
<!-- Configure replication if required so by the server
! suffixes)
-->
<if expr="server.requiresSynchronization()">
<sequence>
<message>
'Instance requires REPLICATION configuration.'
</message>
<script>
if master.isOnlyLdapServer():
masterReplPort = None
else:
masterReplPort = masterReplicationServer.getPort()
if server.isOnlyLdapServer():
serverReplPort = None
else:
replicationServer = server.getChangelogServer()
serverReplPort = replicationServer.getPort()
if server.isOnlyReplServer():
suffixServer = master
else:
suffixServer = server
replicatedSuffixList = suffixServer.getSynchronizedSuffixList()
replicatedDnList = []
for suffix in replicatedSuffixList:
</script>
<message>
'Enable replication for server:\nHost: %s\nLdap port: %s\n\
Replication port: %s\nReplicated DN list: %s' \
% (server.getHostname(), server.getPort(),
serverReplPort, replicatedDnList)
</message>
<call function="'enableReplication'">
{ 'location' : clientHost,
'dsPath' : clientPath,
'refInstanceHost' : masterHost,
'refInstanceAdminPort' : master.getAdminPort(),
'refInstanceDn' : master.getRootDn(),
'refInstancePswd' : master.getRootPwd(),
'refReplicationPort' : masterReplPort,
'refSecureReplication' : secureReplication,
'refOnlyLdapServer' : master.isOnlyLdapServer(),
'refOnlyReplServer' : master.isOnlyReplServer(),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'dsReplicationPort' : serverReplPort,
'dsSecureReplication' : secureReplication,
'dsOnlyLdapServer' : server.isOnlyLdapServer(),
'dsOnlyReplServer' : server.isOnlyReplServer(),
'replicationDnList' : replicatedDnList
}
</call>
</sequence>
</if>
</sequence>
</iterate>
<if expr="isolateLdapServers">
<!-- Make each Ldap Server point only to its own Replication
! Server.
! This is used by the Conflict testsuite, in order to be able
! to simulate conflict scenarios -->
<paralleliterate var="server" in="_topologyServerList" indexvar="i">
<sequence>
<script>
ldapServer = '%s:%s' % (server.getHostname(),
</script>
<!-- Retrieve replication-domain name -->
<call function="'dsconfig'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'subcommand' : 'list-replication-domains',
'objectType' : 'provider-name',
'objectName' : 'Multimaster Synchronization',
'optionsString' : '--script-friendly'
}
</call>
<if expr='RC == 0'>
<script>
replicationDomains = STAXResult[0][1]
for line in replicationDomains.splitlines():
if line.find(synchroSuffix) != -1:
domain = line
domainMap[ldapServer] = domain
break
</script>
</if>
<script>
if globalSplitServers:
splitServer = _topologyReplServerList[i]
replicationServer = splitServer.getChangelogServer()
replServer = '%s:%s' % (splitServer.getHostname(),
else:
replicationServer = server.getChangelogServer()
replServer = '%s:%s' % (server.getHostname(),
options = '--domain-name "%s" --set replication-server:%s' \
% (domainMap[ldapServer], replServer)
</script>
<message>
'Removing references to other replication servers \nfor \
domain: %s \nfrom server: %s \nkeep replication server: %s' \
% (domain, ldapServer, replServer)
</message>
<!-- Remove peer RS from replicated domain -->
<call function="'dsconfig'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'subcommand' : 'set-replication-domain-prop',
'objectType' : 'provider-name',
'objectName' : 'Multimaster Synchronization',
'optionsString' : options
}
</call>
</sequence>
</paralleliterate>
</if>
<script>
assuredReplication = globalAssuredReplication
</script>
<if expr="assuredReplication">
<paralleliterate var="server" in="_topologyServerList">
<sequence>
<script>
ldapServer = '%s:%s' % (server.getHostname(),
</script>
<if expr="isolateLdapServers">
<!-- this means the domainMap has already been filled up -->
<script>
domain = domainMap[ldapServer]
</script>
<else>
<sequence>
<!-- Retrieve replication-domain name -->
<call function="'dsconfig'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'subcommand' : 'list-replication-domains',
'objectType' : 'provider-name',
'objectName' : 'Multimaster Synchronization',
'optionsString' : '--script-friendly'
}
</call>
<if expr='RC == 0'>
<script>
replicationDomains = STAXResult[0][1]
for line in replicationDomains.splitlines():
if line.find(synchroSuffix) != -1:
domain = line
domainMap[ldapServer] = domain
break
</script>
</if>
</sequence>
</else>
</if>
<script>
options = '--domain-name "%s" --set assured-type:%s' \
% (domain, assuredReplication)
</script>
<message>
'Setting replication assured-type to: %s for server: %s \
domain: %s' % (assuredReplication, ldapServer, domain)
</message>
<!-- Set assured -->
<call function="'dsconfig'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'subcommand' : 'set-replication-domain-prop',
'objectType' : 'provider-name',
'objectName' : 'Multimaster Synchronization',
'optionsString' : options
}
</call>
<if expr="assuredReplication == 'safe-data'">
<sequence>
<script>
assuredDataLevel = len(_topologyServerList)
options = '--domain-name "%s" --set assured-sd-level:%s' \
% (domain, assuredDataLevel)
</script>
<message>
'Setting safe-data level to: %s for server: %s \
domain: %s' % (assuredDataLevel, ldapServer, domain)
</message>
<!-- Set assured -->
<call function="'dsconfig'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'subcommand' : 'set-replication-domain-prop',
'objectType' : 'provider-name',
'objectName' : 'Multimaster Synchronization',
'optionsString' : options
}
</call>
</sequence>
</if>
</sequence>
</paralleliterate>
</if>
<if expr="dataFile">
<sequence>
<message>
'Initialise topology from %s:%s' \
% (masterHost, master.getPort())
</message>
<!-- Initialise the servers in the topology -->
<call function="'initializeReplication'">
{ 'location' : clientHost,
'dsPath' : clientPath,
'sourceInstanceHost' : masterHost,
'sourceInstanceAdminPort' : master.getAdminPort(),
'replicationDnList' : [synchroSuffix]
}
</call>
<if expr="0">
<iterate var="server" in="consumerList">
<sequence>
<!-- <call function="'initializeReplication'">
{ 'location' : clientHost,
'dsPath' : clientPath,
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'sourceInstanceHost' : masterHost,
'sourceInstanceAdminPort' : master.getAdminPort(),
'replicationDnList' : [synchroSuffix]
}
</call> -->
<!-- Search initialisation task to check its status -->
<call function="'ldapSearchWithScript'">
{
'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(), OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstancePort' : server.getPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'dsBaseDN' : 'cn=Tasks',
'dsFilter' : 'ds-task-initialize-domain-dn=%s' \
% synchroSuffix
}
</call>
<script>
searchRC = STAXResult[0][0]
searchResult = STAXResult[0][1]
resultLength = len(searchResult) > 0
</script>
<if expr="resultLength != 0">
<sequence>
<message>
'++++++++ INITIALISATION TASK for %s:%s ++++++++\n%s' \
% (server.getHostname(), server.getPort(), searchResult)
</message>
</sequence>
</if>
</sequence>
</iterate>
</if>
</sequence>
</if>
<if expr="enableDebugLogs">
<paralleliterate var="server" in="_topologyServerList">
<sequence>
<!-- Set the debug logger to "enabled" -->
<call function="'dsconfigSet'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'objectName' : 'log-publisher',
'propertyType' : 'publisher',
'propertyName' : 'File-based Debug Logger',
'attributeName' : 'enabled',
'attributeValue' : 'true'
}
</call>
<!-- Set the debug level to "info" -->
<call function="'dsconfigSet'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'objectName' : 'log-publisher',
'propertyType' : 'publisher',
'propertyName' : 'File-based Debug Logger',
'attributeName' : 'default-debug-level',
'attributeValue' : 'info'
}
</call>
<call function="'dsconfigSet'">
{ 'location' : server.getHostname(),
'dsPath' : '%s/%s' \
% (server.getDir(),OPENDSNAME),
'dsInstanceHost' : server.getHostname(),
'dsInstanceAdminPort' : server.getAdminPort(),
'dsInstanceDn' : server.getRootDn(),
'dsInstancePswd' : server.getRootPwd(),
'objectName' : 'log-publisher',
'propertyType' : 'publisher',
'propertyName' : 'File-based Debug Logger',
'attributeName' : 'log-file',
}
</call>
</sequence>
</paralleliterate>
</if>
<tcstatus result="'pass'"></tcstatus>
</sequence>
<catch exception="'STAXException'" typevar="eType" var="eInfo">
<sequence>
<message log="1" level="'fatal'">
'%s: Failed to cleanup. eInfo(%s)' % (eType,eInfo)
</message>
<throw exception="'STAFException.TestSuite.CleanupException'" />
</sequence>
</catch>
<finally>
<!-- Test Case postamble -->
<call function="'testCase_Postamble'"/>
</finally>
</try>
</testcase>
</block>
</sequence>
</function>
</stax>