Example: Connected Data Source Extension for OLEDB Database access
This topic contains a code example to create a connected data source extension for connecting to a database by means of OLE/DB.
This example uses methods of the IMAEXtensibleFileImport interface to import data from an XML file and methods of the IMAExtensibleCallExport interface and the OLEDB Provider to export the information to a SQL database.
The following C# code example shows how to create a connected data source extension for call-based data sources.
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Collections;
using System.Collections.Specialized;
using Microsoft.MetadirectoryServices;
using System.Data;
using System.Data.SqlClient;
using System.Data.OleDb;
namespace Miis_CallExport
{
public class MACallExport :
IMAExtensibleFileImport,
IMAExtensibleCallExport
{
public MACallExport() {}
// ------------------ C O N S T A N T S ------------------------
private const string PARAM_SQLTABLENAME = "Table";
private const string PARAM_SQLWHERECLAUSE = "SQLWhereClause";
private const string PARAM_SQLDATABASE = "Database";
private const string PARAM_SQLTIMEOUT = "Timeout";
private const string PARAM_SQLSECURITY = "Security";
private const string PARAM_SQLPROVIDER = "Provider";
// Not needed: private const string
// PARAM_ESCAPEANCHOR = "EscapeAnchor";
// ------------------ I M P O R T -----------------------------
//
private string EscapeStringForImport(string escape)
{
if(escape == null)
return null;
escape.Replace("\"", "\"\"");
return String.Format("\"{0}\"", escape);
} // EscapeStringForImport
private string ConstructConnectionString
(
string connectTo,
string user,
string password,
ConfigParameterCollection configParameters
)
{
string connectionString = "";
if(configParameters[PARAM_SQLSECURITY].Value.ToUpper().Equals
("SSPI"))
{
connectionString = String.Format("Provider={0};
Persist Security Info=False;Integrated Security=SSPI;
Initial Catalog={1};Data Source={2};Connect Timeout={3}",
configParameters[PARAM_SQLPROVIDER].Value,
configParameters[PARAM_SQLDATABASE].Value,
connectTo,
configParameters[PARAM_SQLTIMEOUT].Value);
}
else
{
connectionString = String.Format("Provider={0};
Persist Security Info=False;User ID={1};Password={2};
Initial Catalog={3};Data Source={4};Connect Timeout={5}",
configParameters[PARAM_SQLPROVIDER].Value,
user,
password,
configParameters[PARAM_SQLDATABASE].Value,
connectTo,
configParameters[PARAM_SQLTIMEOUT].Value);
}
return connectionString;
} //ConstructConnectionString
public void GenerateImportFile
(
string filename,
string connectTo,
string user,
string password,
ConfigParameterCollection configParameters,
bool fullImport,
TypeDescriptionCollection types,
ref string customData
)
{
if(!fullImport)
{
throw new TerminateRunException
("This MA only supports full import");
}
//---------------------------------------------------------------
// Construct the columns to select from the SQL table by
// enumerating through the attributes of the first object type.
// This assumes that the DB MA schema exposes all attributes
// available for all object types
//---------------------------------------------------------------
string sqlColumns = "";
string objectType = "";
ArrayList attributeList = new ArrayList();
foreach(TypeDescription t in types)
{
objectType = t.Name;
foreach(AttributeDescription a in t.Attributes)
{
sqlColumns = sqlColumns + a.Name + ",";
attributeList.Add(a.Name);
}
break;
}
if(sqlColumns.Equals(""))
{
throw new TerminateRunException(
"No attributes in schema definition");
}
// remove last comma
sqlColumns = sqlColumns.Substring(0, sqlColumns.Length-1);
//----------------------------------------------------------------
// Construct the SQL Select statement for the intermediate import
// file.
//----------------------------------------------------------------
string commandString = String.Format("SELECT {0} FROM {1}",
sqlColumns,
configParameters[PARAM_SQLTABLENAME].Value);
try
{
if(!configParameters[PARAM_SQLWHERECLAUSE].Value.Equals(""))
{
commandString = String.Format("{0} WHERE {1}", commandString,
configParameters[PARAM_SQLWHERECLAUSE].Value);
}
}
// Ignore if the parameter "SQLWhereClause" doesn't exist
catch { }
//----------------------------------------------------------------
// Construct the connection string and connect to the SQL database
//----------------------------------------------------------------
string connectionString = ConstructConnectionString(connectTo,
user, password, configParameters);
OleDbConnection myConnection = new OleDbConnection
(connectionString);
OleDbCommand myCommand = new OleDbCommand(commandString,
myConnection);
//--------------------------------------------------------------
// Open the SQL database and create the intermediate file
// Note that this code only supports String, Integer, GUID, and
// DBNULL values
// Further datatypes must be added by extending the code.
//---------------------------------------------------------------
myConnection.Open();
OleDbDataReader result = myCommand.ExecuteReader
(CommandBehavior.CloseConnection);
StreamWriter stream = new StreamWriter(filename, false,
System.Text.Encoding.Unicode);
while(result.Read())
{
for(int i=0; i<result.FieldCount;i++)
{
if(result[i] is string)
stream.WriteLine(String.Format("{0}: {1}", attributeList[i],
result[i]));
else if (result[i] is System.Int64)
stream.WriteLine(String.Format("{0}: {1}", attributeList[i],
result[i]));
else if(result[i] is System.Guid)
stream.WriteLine(String.Format("{0}: {{{1}}}", attributeList[i],
System.Convert.ToString(result[i])));
else if (result[i] is System.DBNull)
; // no output --> NULL value
else
throw new UnexpectedDataException(String.Format
("Unknown type in SQL Column: {0}", attributeList[i])); }
stream.WriteLine(); // new record, separate by new line
}
stream.Close();
} //GenerateImportFile
// ------------------ E X P O R T -------------------------------
// Globals for Export routines
private string ExportConnectionString;
private string ExportTableName;
private OleDbConnection ExportConnection;
private TypeDescriptionCollection ExportTypes;
// not needed: private bool ExportEscapeAnchor;
public void BeginExport
(
string connectTo,
string user,
string password,
ConfigParameterCollection configParameters,
TypeDescriptionCollection types
)
{
//----------------------------------------------------------------
// Construct the connection string and connect to the SQL database
//----------------------------------------------------------------
ExportConnectionString = ConstructConnectionString(connectTo, user,
password, configParameters);
ExportConnection = new OleDbConnection(ExportConnectionString);
ExportConnection.Open();
// Save Type (Schema) information for later to determine
// the anchor for a given object type
ExportTypes = types;
// Save the Database table name ro run the Insert/Update/Deletes
ExportTableName = configParameters[PARAM_SQLTABLENAME].Value;
// Save for later if in the where clause the anchor needs to get
// enclosed in ''
// not needed: ExportEscapeAnchor = configParameters
// [PARAM_ESCAPEANCHOR].Value.ToLower().Equals("yes") ?
// true : false;
}
public void ExportEntry
(
ModificationType modificationType,
string[] changedAttributes,
CSEntry csentry
)
{
switch(modificationType)
{
case ModificationType.Replace:
UpdateEntry(changedAttributes, csentry);
break;
case ModificationType.Add:
InsertEntry(changedAttributes, csentry);
break;
case ModificationType.Delete:
DeleteEntry(csentry);
break;
}
} //ExportEntry
private string EscapeStringForExport(string escape)
{
if(escape == null)
return null;
return escape.Replace("'", "''");
} // EscapeStringForExport
private string GetAnchorAttributeName(CSEntry cs)
{
TypeDescription t = ExportTypes[cs.ObjectType];
//-----------------------------------------------------------
// Note that this MA only supports one Anchor attribute
//-----------------------------------------------------------
if(t.AnchorAttributes.Count > 1)
throw new TerminateRunException(String.Format("ObjectType {0}
has more than one anchor attribute", cs.ObjectType));
foreach(AttributeDescription attr in t.AnchorAttributes)
{
return attr.Name;
}
return null;
} // GetAnchorAttributeName
private bool EscapeAnchorAttribute(CSEntry cs)
{
TypeDescription t = ExportTypes[cs.ObjectType];
//-----------------------------------------------------------
// Note that this MA only supports one Anchor attribute
//-----------------------------------------------------------
if(t.AnchorAttributes.Count > 1)
throw new TerminateRunException(String.Format("ObjectType {0}
has more than one anchor attribute", cs.ObjectType));
foreach(AttributeDescription attr in t.AnchorAttributes)
{
switch (attr.DataType)
{
case AttributeType.String:
return true;
case AttributeType.Integer:
return false;
case AttributeType.Binary:
return true;
default:
throw new TerminateRunException(String.Format("Anchor type
unsupported. ObjectType: {0}, Attribute: {1}, Type: {2}",
cs.ObjectType, attr.Name, attr.DataType.ToString()));
}
}
return true;
} // EscapeAnchorAttribute
private void UpdateEntry(string[] changedAttributes, CSEntry cs)
{
//----------------------------------------------------------------
// Build the SQL Update Query
//----------------------------------------------------------------
string commandString = String.Format("UPDATE {0} SET",
ExportTableName);
foreach(string attribName in changedAttributes)
{
string val = "";
Attrib attr = cs[attribName];
if(attr.IsPresent)
{
switch(attr.DataType)
{
case AttributeType.String:
val = "'" + EscapeStringForExport(attr.StringValue) + "'";
break;
case AttributeType.Integer:
val = System.Convert.ToString(attr.IntegerValue, 10);
break;
default:
throw new UnexpectedDataException(String.Format("Unknown data
type for export update. Attr: {0}, Type: {1}", attribName,
attr.DataType.ToString()));
}
}
else
{
val = "NULL";
}
commandString = commandString + String.Format(" {0}={1},",
attribName, val);
}
commandString = commandString.Substring(0, commandString.Length-1);
// remove last comma
string anchor = GetAnchorAttributeName(cs);
string anchorValue = cs[anchor].Value.ToString();
if(EscapeAnchorAttribute(cs))
{
anchorValue = String.Format("'{0}'", anchorValue);
}
commandString = commandString + String.Format(" WHERE {0}={1}",
anchor, anchorValue);
//----------------------------------------------------------------
// Build the SQL Update Query
//----------------------------------------------------------------
//----------------------------------------------------------------
// Execute SQL Update Query
//----------------------------------------------------------------
OleDbCommand myCommand = new OleDbCommand(commandString,
ExportConnection);
try { myCommand.ExecuteNonQuery(); }
catch { throw; } // need better exception to report back the
command sent to SQL
} // UpdateEntry
private void InsertEntry(string[] changedAttributes, CSEntry cs)
{
//---------------------------------------------------------------
// Build the SQL Insert Query
//---------------------------------------------------------------
string commandString = String.Format("INSERT INTO {0}
(", ExportTableName);
foreach(string attribName in changedAttributes)
{
commandString = commandString + attribName + ",";
}
commandString = commandString.Substring(0, commandString.Length-1);
// remove last comma
commandString = commandString + ") VALUES (";
foreach(string attribName in changedAttributes)
{
string val = "";
Attrib attr = cs[attribName];
if(attr.IsPresent)
{
switch(attr.DataType)
{
case AttributeType.String:
val = "'" + EscapeStringForExport(attr.StringValue) + "'";
break;
case AttributeType.Integer:
val = System.Convert.ToString(attr.IntegerValue, 10);
break;
case AttributeType.Binary: // assuming GUID value (e.g. Anchor)
val = "'" + attr.Value.ToString() + "'";
break;
default:
throw new UnexpectedDataException(String.Format("Unknown data
type for export add. Attr: {0} Type: {1}" + attribName,
attr.DataType.ToString()));
}
}
else
{
val = "NULL";
}
commandString = commandString + val + ",";
}
commandString = commandString.Substring(0, commandString.Length-1);
// remove last comma
commandString = commandString + ")";
//---------------------------------------------------------------
// Build the SQL Insert Query
//---------------------------------------------------------------
//---------------------------------------------------------------
// Execute the SQL Insert Query
//---------------------------------------------------------------
OleDbCommand myCommand = new OleDbCommand(commandString,
ExportConnection);
try { myCommand.ExecuteNonQuery(); }
catch { throw; } // need better exception to report back the command
sent to SQL
} // insert entry
private void DeleteEntry(CSEntry cs)
{
string anchor = GetAnchorAttributeName(cs);
string anchorValue = cs[anchor].Value.ToString();
if(EscapeAnchorAttribute(cs))
{
anchorValue = String.Format("'{0}'", anchorValue);
}
// Build the SQL Delete Query
string commandString = String.Format("DELETE FROM {0}
WHERE {1}={2}", ExportTableName, anchor, anchorValue);
// Execute the SQL Delete Query
OleDbCommand myCommand = new OleDbCommand(commandString,
ExportConnection);
try { myCommand.ExecuteNonQuery(); }
catch { throw; } // need better exception to report back the
command sent to SQL
}
// DeleteEntry
public void EndExport()
{
ExportConnection.Close();
}
}
}
The example assumes that the call-based data source consumes an XML file in the following format:
- <export-ma server="FABRIKAM" export-date="2004-07-12 20:20:56.033">
- <!-- WARNING>
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!
!! The contents of this file should not be edited.
!! Any modifications to this file may result in errors during import.
!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
</WARNING
-->
- <ma-data>
<format-version>1</format-version>
<id>{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}</id>
<name>OLEDB Database MA</name>
<category>Extensible</category>
<subtype />
<ma-listname />
<ma-companyname />
<creation-time>2004-07-12 19:11:08.183</creation-time>
<last-modification-time>2004-07-12 20:17:57.336_
</last-modification-time>
<version>4</version>
<password-sync-allowed>0</password-sync-allowed>
- <schema>
- <dsml:dsml xmlns:dsml="http://www.fabrikam.com/DSML"_
xmlns:ms-dsml="http://www.fabrikam.com/MMS/DSML">
- <dsml:directory-schema _
ms-dsml:no-objectclass-validation="true">
- <dsml:class id="person" type="structural">
<dsml:name>person</dsml:name>
<dsml:attribute ref="#accountType" required="false" />
<dsml:attribute ref="#company" required="false" />
<dsml:attribute ref="#costCenter" required="false" />
<dsml:attribute ref="#department" required="false" />
<dsml:attribute ref="#displayName" required="false" />
<dsml:attribute ref="#domainName" required="false" />
<dsml:attribute ref="#employeeID" required="true" />
<dsml:attribute ref="#firstname" required="false" />
<dsml:attribute ref="#identityGuid" required="false" />
<dsml:attribute ref="#lastname" required="false" />
<dsml:attribute ref="#logonName" required="false" />
<dsml:attribute ref="#mail" required="false" />
<dsml:attribute ref="#mailNickname" required="false" />
<dsml:attribute ref="#managerEmployeeID" required="false" />
<dsml:attribute ref="#objectType" required="false" />
<dsml:attribute ref="#phoneNumber" required="false" />
<dsml:attribute ref="#samAccountName" required="false" />
<dsml:attribute ref="#title" required="false" />
<dsml:attribute ref="#pager" required="false" />
<dsml:attribute ref="#mobile" required="false" />
<dsml:attribute ref="#export_password" required="false" />
</dsml:class>
- <dsml:attribute-type id="accountType" single-value="true">
<dsml:name>accountType</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="company" single-value="true">
<dsml:name>company</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="costCenter" single-value="true">
<dsml:name>costCenter</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="department" single-value="true">
<dsml:name>department</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="displayName" single-value="true">
<dsml:name>displayName</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="domainName" single-value="true">
<dsml:name>domainName</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="employeeID" single-value="true"_
ms-dsml:immutable="true">
<dsml:name>employeeID</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="firstname" single-value="true">
<dsml:name>firstname</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="identityGuid" single-value="true">
<dsml:name>identityGuid</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="lastname" single-value="true">
<dsml:name>lastname</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="logonName" single-value="true">
<dsml:name>logonName</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="mail" single-value="true">
<dsml:name>mail</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="mailNickname" single-value="true">
<dsml:name>mailNickname</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="managerEmployeeID" _
single-value="true">
<dsml:name>managerEmployeeID</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="objectType" single-value="true">
<dsml:name>objectType</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="phoneNumber" single-value="true">
<dsml:name>phoneNumber</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="samAccountName" single-value="true">
<dsml:name>samAccountName</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="title" single-value="true">
<dsml:name>title</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="pager" single-value="true">
<dsml:name>pager</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="mobile" single-value="true">
<dsml:name>mobile</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
- <dsml:attribute-type id="export_password" _
single-value="true" ms-dsml:encrypted="true" _
ms-dsml:export-only="true">
<dsml:name>export_password</dsml:name>
<dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax>
</dsml:attribute-type>
</dsml:directory-schema>
</dsml:dsml>
</schema>
- <attribute-inclusion>
<attribute>accountType</attribute>
<attribute>company</attribute>
<attribute>costCenter</attribute>
<attribute>department</attribute>
<attribute>displayName</attribute>
<attribute>domainName</attribute>
<attribute>employeeID</attribute>
<attribute>firstname</attribute>
<attribute>identityGuid</attribute>
<attribute>lastname</attribute>
<attribute>logonName</attribute>
<attribute>mail</attribute>
<attribute>mailNickname</attribute>
<attribute>managerEmployeeID</attribute>
<attribute>objectType</attribute>
<attribute>phoneNumber</attribute>
<attribute>samAccountName</attribute>
<attribute>title</attribute>
<attribute>pager</attribute>
<attribute>mobile</attribute>
<attribute>export_password</attribute>
</attribute-inclusion>
<stay-disconnector />
- <join>
- <join-profile cd-object-type="person">
- <join-criterion id="{45B13AEB-A596-4AFC-B0CD-D9465D835D76}">
- <search mv-object-type="person">
- <attribute-mapping mv-attribute="employeeID">
- <direct-mapping>
<src-attribute>employeeID</src-attribute>
</direct-mapping>
</attribute-mapping>
</search>
- <resolution type="none">
<script-context />
</resolution>
</join-criterion>
</join-profile>
</join>
- <projection>
- <class-mapping type="declared" id="_
{7D985F8D-0FF3-430B-B207-E77F01844AE0}" cd-object-type="person">
<mv-object-type>person</mv-object-type>
</class-mapping>
</projection>
<export-attribute-flow />
- <provisioning-cleanup type="declared">
<action>make-normal-disconnector</action>
</provisioning-cleanup>
<extension />
- <controller-configuration>
<application-protection>high</application-protection>
</controller-configuration>
<description />
- <ma-ui-settings>
- <account-joiner-queries>
- <attributes>
- <cs>
<attribute name="employeeID" header="employeeID" size="100" />
<attribute name="accountType" header="accountType" size="100" />
<attribute name="company" header="company" size="100" />
</cs>
<mv/>
</attributes>
<filters max_mv_search_results="" />
</account-joiner-queries>
</ma-ui-settings>
- <private-configuration>
- <MAConfig>
- <ui-data>
- <xmlwizard>
- <properties>
<sample_file>C:\import.csv</sample_file>
<code_page_description>Unicode</code_page_description>
</properties>
- <partitions>
- <partition cd_name="default" guid="_
{483FBBF8-E722-4DB4-9D2F-1CC58D9CB3E6}" version="3">
<object_class>person</object_class>
</partition>
</partitions>
- <primary_class_mappings>
- <mapping object_class="person" primary_class="person"_
user_define="-1">
<attribute>accountType</attribute>
<attribute>company</attribute>
<attribute>costCenter</attribute>
<attribute>department</attribute>
<attribute>displayName</attribute>
<attribute>domainName</attribute>
<attribute>employeeID</attribute>
<attribute>firstname</attribute>
<attribute>identityGuid</attribute>
<attribute>lastname</attribute>
<attribute>logonName</attribute>
<attribute>mail</attribute>
<attribute>mailNickname</attribute>
<attribute>managerEmployeeID</attribute>
<attribute>objectType</attribute>
<attribute>phoneNumber</attribute>
<attribute>samAccountName</attribute>
<attribute>title</attribute>
<attribute>pager</attribute>
<attribute>mobile</attribute>
</mapping>
</primary_class_mappings>
- <object_classes>
- <object_class cd_name="person" selected="-1" _
user_define="-1" configured="-1" anchor="" dn_as_anchor="0">
<attribute mandatory="0">accountType</attribute>
<attribute mandatory="0">company</attribute>
<attribute mandatory="0">costCenter</attribute>
<attribute mandatory="0">department</attribute>
<attribute mandatory="0">displayName</attribute>
<attribute mandatory="0">domainName</attribute>
<attribute mandatory="-1">employeeID</attribute
<attribute mandatory="0">firstname</attribute>
<attribute mandatory="0">identityGuid</attribute>
<attribute mandatory="0">lastname</attribute>
<attribute mandatory="0">logonName</attribute>
<attribute mandatory="0">mail</attribute>
<attribute mandatory="0">mailNickname</attribute>
<attribute mandatory="0">managerEmployeeID</attribute>
<attribute mandatory="0">objectType</attribute>
<attribute mandatory="0">phoneNumber</attribute>
<attribute mandatory="0">samAccountName</attribute>
<attribute mandatory="0">title</attribute>
<attribute mandatory="0">pager</attribute>
<attribute mandatory="0">mobile</attribute>
</object_class>
</object_classes>
- <attributes>
<attribute cd_name="accountType" binary="0" sample_data="53"_
multi_valued="0" file_reference="0" selected="-1" _
type="String" lower_bound="" upper_bound="" user_define="0" />
<attribute cd_name="company" binary="0" _
sample_data="CONTOSO" multi_valued="0" file_reference="0" _
selected="-1" type="String" lower_bound="" upper_bound="" _
user_define="0" />
<attribute cd_name="costCenter" binary="0" sample_data="90622"_
multi_valued="0" file_reference="0" selected="-1" _
type="String" lower_bound="" upper_bound="" user_define="0" />
<attribute cd_name="department" binary="0" _
sample_data="US-SAP Analysis & Support" multi_valued="0" _
file_reference="0" selected="-1" type="String" lower_bound="_
" upper_bound="" user_define="0" />
<attribute cd_name="displayName" binary="0" _
sample_data=" (US-SAP Analysis & Support)"_
multi_valued="0" file_reference="0" selected="-1" type="String"_
lower_bound="" upper_bound="" user_define="0" />
<attribute cd_name="domainName" binary="0" _
sample_data="DomainName" multi_valued="0" file_reference="0" _
selected="-1" type="String" lower_bound="" upper_bound="" _
user_define="0" />
<attribute cd_name="employeeID" binary="0" _
sample_data="216959" multi_valued="0" file_reference="0" _
selected="-1" type="String" lower_bound="" upper_bound="" _
user_define="0" />
<attribute cd_name="firstname" binary="0" _
sample_data="Wright" multi_valued="0" file_reference="0" _
selected="-1" type="String" lower_bound="" upper_bound="_
" user_define="0" />
<attribute cd_name="identityGuid" binary="0" _
sample_data="{371df4cd-ac02-4e82-82cf-00eebcf31d38}" _
multi_valued="0" file_reference="0" selected="-1" _
type="String" lower_bound="" upper_bound="" user_define="0" />
<attribute cd_name="lastname" binary="0" _
sample_data="Steven 123" multi_valued="0" file_reference="0"_
selected="-1" type="String" lower_bound="" upper_bound="_
" user_define="0" />
<attribute cd_name="logonName" binary="0" _
sample_data="DomainName\t-steven" multi_valued="0" _
file_reference="0" selected="-1" type="String" _
lower_bound="" upper_bound="" user_define="0" />
<attribute cd_name="mail" binary="0" _
sample_data="t-steven@contoso.com" multi_valued="0" _
file_reference="0" selected="-1" type="String" lower_bound="_
" upper_bound="" user_define="0" />
<attribute cd_name="mailNickname" binary="0" _
sample_data="t-steven" multi_valued="0" file_reference="0"_
selected="-1" type="String" lower_bound="" upper_bound="_
" user_define="0" />
<attribute cd_name="managerEmployeeID" binary="0" _
sample_data="114635" multi_valued="0" file_reference="0" _
selected="-1" type="String" lower_bound="" upper_bound="_
" user_define="0" />
<attribute cd_name="objectType" binary="0" _
sample_data="MSPerson" multi_valued="0" file_reference="0" _
selected="-1" type="String" lower_bound="" upper_bound="_
" user_define="0" />
<attribute cd_name="phoneNumber" binary="0" _
sample_data="+1 (555) 5550123 X50123" multi_valued="0" _
file_reference="0" selected="-1" type="String" _
lower_bound="" upper_bound="" user_define="0" />
<attribute cd_name="samAccountName" binary="0" _
sample_data="t-steven" multi_valued="0" file_reference="0"_
selected="-1" type="String" lower_bound="" upper_bound="_
" user_define="0" />
<attribute cd_name="title" binary="0" _
sample_data="WINTER PROGRAM MANAGER INTERN" multi_valued="0"_
file_reference="0" selected="-1" type="String" lower_bound="_
" upper_bound="" user_define="0" />
<attribute cd_name="pager" binary="0" _
sample_data="555-555-0196" multi_valued="0" file_reference="0"_
selected="-1" type="String" lower_bound="" upper_bound="_
" user_define="0" />
<attribute cd_name="mobile" binary="0" _
sample_data="555-555-0145" multi_valued="0" _
file_reference="0" selected="-1" type="String" _
lower_bound="" upper_bound="" user_define="0" />
</attributes>
</xmlwizard>
</ui-data>
- <importing>
- <dn>
<attribute>employeeID</attribute>
</dn>
- <anchor>
<attribute>employeeID</attribute>
</anchor>
<per-class-settings />
<default_object_class>person</default_object_class>
</importing>
<exporting />
<ldap-dn>0</ldap-dn>
- <attribute_value_pair_format>
<code_page>1200</code_page>
</attribute_value_pair_format>
- <primary_class_mappings>
- <mapping>
<primary_class>person</primary_class>
<oc-value>person</oc-value>
</mapping>
</primary_class_mappings>
- <password-extension-config>
<password-extension-enabled>0</password-extension-enabled>
<dll />
<password-set-enabled />
<password-change-enabled />
- <connection-info>
<connect-to />
<user />
</connection-info>
<timeout />
</password-extension-config>
- <extension-config>
<filename>OLEDB Database MAExtension.dll</filename>
<export-mode>call-based</export-mode>
<import-enabled>1</import-enabled>
<export-enabled>1</export-enabled>
- <connection-info>
<connect-to>localhost</connect-to>
<user>sa</user>
</connection-info>
- <attributes>
<attribute name="Database">MIISSA</attribute>
<attribute name="Table">IdentityStore</attribute>
<attribute name="SQLWhereClause">CostCenter in ('90622')_
</attribute>
<attribute name="Provider">SQLOLEDB</attribute>
<attribute name="Security">SSPI</attribute>
<attribute name="Timeout">30</attribute>
</attributes>
</extension-config>
<file-type>AVP</file-type>
</MAConfig>
</private-configuration>
- <ma-partition-data>
- <partition>
<id>{483FBBF8-E722-4DB4-9D2F-1CC58D9CB3E6}</id>
<name>default</name>
<creation-time>2004-07-12 19:11:08.183</creation-time>
<last-modification-time>2004-07-12 20:17:57.327_
</last-modification-time>
<version>4</version>
<selected>1</selected>
- <filter>
- <object-classes>
<object-class>person</object-class>
</object-classes>
- <containers>
<exclusions />
- <inclusions>
<inclusion />
</inclusions>
</containers>
</filter>
<allowed-operations>31</allowed-operations>
- <current>
<batch-number>1</batch-number>
<sequence-number>0</sequence-number>
</current>
<last-successful-batch>0</last-successful-batch>
- <filter-hints>
- <object-classes>
- <object-class>
<name>person</name>
- <hierarchy>
<object-class>person</object-class>
</hierarchy>
<included>1</included>
</object-class>
</object-classes>
</filter-hints>
</partition>
</ma-partition-data>
- <ma-run-data>
- <run-configuration>
<id>{1D98F06C-094E-4236-9F0F-A5981BCE687D}</id>
<name>Export</name>
<creation-time>2004-07-12 20:14:01.940</creation-time>
<version>1</version>
<last-modification-time>2004-07-12 20:14:01.940_
</last-modification-time>
- <configuration>
- <step>
<step-type type="export" />
<threshold />
<partition>{483FBBF8-E722-4DB4-9D2F-1CC58D9CB3E6}</partition>
- <custom-data>
- <run-config>
<input-file />
<timeout>0</timeout>
</run-config>
</custom-data>
</step>
</configuration>
</run-configuration>
- <run-configuration>
<id>{74374014-3FDB-44EC-A194-00FF139AB44F}</id>
<name>Export+FullImport+DeltaSync</name>
<creation-time>2004-07-12 20:14:01.940</creation-time>
<version>1</version>
<last-modification-time>2004-07-12 20:14:01.940_
</last-modification-time>
- <configuration>
- <step>
<step-type type="export" />
<threshold />
<partition>{483FBBF8-E722-4DB4-9D2F-1CC58D9CB3E6}</partition>
- <custom-data>
- <run-config>
<input-file />
<timeout>0</timeout>
</run-config>
</custom-data>
</step>
- <step>
<step-type type="full-import" />
<threshold />
<partition>{483FBBF8-E722-4DB4-9D2F-1CC58D9CB3E6}</partition>
- <custom-data>
- <run-config>
<input-file>import.avp.txt</input-file>
<delete-file-after-use>0</delete-file-after-use>
<timeout>0</timeout>
</run-config>
</custom-data>
</step>
</configuration>
</run-configuration>
- <run-configuration>
<id>{18B8482E-BE7A-456B-B084-23DB27D14027}</id>
<name>FullImport+DeltaSync</name>
<creation-time>2004-07-12 20:14:01.930</creation-time>
<version>2</version>
<last-modification-time>2004-07-12 20:14:32.903_
</last-modification-time>
- <configuration>
- <step>
<step-type type="full-import" />
<threshold />
<partition>{483FBBF8-E722-4DB4-9D2F-1CC58D9CB3E6}</partition>
- <custom-data>
- <run-config>
<input-file>import.avp.txt</input-file>
<delete-file-after-use>0</delete-file-after-use>
<timeout>0</timeout>
</run-config>
</custom-data>
</step>
</configuration>
</run-configuration>
</ma-run-data>
<capabilities-mask>7b801</capabilities-mask>
<export-type>3</export-type>
- <dn-construction>
<attribute>employeeID</attribute>
</dn-construction>
- <password-sync>
<maximum-retry-count>10</maximum-retry-count>
<retry-interval>60</retry-interval>
<allow-low-security>0</allow-low-security>
</password-sync>
</ma-data>
- <mv-data>
- <import-attribute-flow>
- <import-flow-set mv-object-type="person">
- <import-flows mv-attribute="displayName" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}_
" cd-object-type="person" id="_
{B1F95D79-E7EE-4983-A52C-EFE4DD2EA2B6}">
- <direct-mapping>
<src-attribute>displayName</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}_
" cd-object-type="person" id="_
{792C99AA-0ED3-4F48-9932-91327D92ADED}">
- <direct-mapping>
<src-attribute>displayName</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="givenName" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}_
" cd-object-type="person" id="_
{F20E677D-B5E7-4EC4-A30E-E8E56CF01DD1}">
- <direct-mapping>
<src-attribute>firstname</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}" _
cd-object-type="person" id="_
{8E7C124A-D0E6-4B18-A9A3-EE20DE019250}">
- <direct-mapping>
<src-attribute>first</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="sn" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="_
{662F7FFC-AC3B-4D2F-BBC2-7098B6E07DDD}">
- <direct-mapping>
<src-attribute>lastname</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="company" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="_
{EAF1F4B2-AD8F-4A1C-8526-74B8655F0F8E}">
- <direct-mapping>
<src-attribute>company</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}" _
cd-object-type="person" id="_
{5990AB3C-0FED-4EA0-809C-944A71DBBFB5}">
- <direct-mapping>
<src-attribute>company</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="mailNickname" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="_
{F31E1BF1-2815-4097-90F9-43027A2BD47F}">
- <direct-mapping>
<src-attribute>samAccountName</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="_
{C4908202-6AE6-44FB-B91E-8627F2846A0B}">
- <direct-mapping>
<src-attribute>mailNickname</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}" _
cd-object-type="person" id="_
{350D4BA7-AFC2-4610-BC76-FAD46C1AFE72}">
- <direct-mapping>
<src-attribute>samAccountName</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="department" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="_
{AE8AED48-ABA5-4D13-BCF6-7F087341448B}">
- <direct-mapping>
<src-attribute>department</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}" _
cd-object-type="person" id="_
{5C7CE82C-9402-4CF3-A05E-CFCD1B0A9F00}">
- <direct-mapping>
<src-attribute>department</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="employeeType" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="_
{C763C66B-3E19-491E-AD41-B8FAF6F1ED69}">
- <direct-mapping>
<src-attribute>accountType</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}" _
cd-object-type="person" id="_
{AD0E35CC-C0F2-4DFF-9483-F324342E6EAD}">
- <scripted-mapping>
<src-attribute>accountType</src-attribute>
<script-context>cd.person:accountType->mv.person:_
employeeType</script-context>
</scripted-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="division" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="_
{B7EEDD5F-FB0F-4BD0-B55C-BF2E6F6018B6}">
- <direct-mapping>
<src-attribute>costCenter</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}" _
cd-object-type="person" id="{5A324740-68F4-46D6-8C22-09F9C3D34D77}">
- <direct-mapping>
<src-attribute>costCenter</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="employeeID" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" cd-object-type="person" id="{6BF349C1-A81E-4672-89A0-E585027DDE59}">
- <direct-mapping>
<src-attribute>employeeID</src-attribute>
</direct-mapping>
</import-flow>
- <import-flow src-ma="{54686980-A9D6-463D-859F-32AFAC045B1A}" cd-object-type="person" id="{DB2559CA-52C6-4448-BE31-4FFF84F9B27A}">
- <direct-mapping>
<src-attribute>employeeID</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="mail" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}"_
cd-object-type="person" id="_
{38642D45-5F34-49F7-B94D-1CA56DBB4146}">
- <direct-mapping>
<src-attribute>mail</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="mobile" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}"_
cd-object-type="person" id="_
{43EFC2E5-823D-4A21-BE50-B2C22C211334}">
- <direct-mapping>
<src-attribute>mobile</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="pager" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}"_
cd-object-type="person" id="_
{84C099ED-0414-48EB-92E1-E62C9D545429}">
- <direct-mapping>
<src-attribute>pager</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="telephoneNumber" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}" _
cd-object-type="person" id="{11C5EA30-A173-4A5B-814E-BF4266AC1F90}">
- <direct-mapping>
<src-attribute>phoneNumber</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
- <import-flows mv-attribute="title" type="ranked">
- <import-flow src-ma="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}"_
cd-object-type="person" id="_
{DAB2FB28-E7C6-477E-B083-9F4DC989A390}">
- <direct-mapping>
<src-attribute>title</src-attribute>
</direct-mapping>
</import-flow>
</import-flows>
</import-flow-set>
- <per-ma-options>
- <ma-options ma-id="{54686980-A9D6-463D-859F-32AFAC045B1A}">
<enable-recall>true</enable-recall>
</ma-options>
- <ma-options ma-id="{1F41DB0A-8E02-4BF8-B77A-81AF5C6FB2F6}">
<enable-recall>true</enable-recall>
</ma-options>
- <ma-options ma-id="{9DCAE092-8BF0-4483-A943-BBF1BD0C2CE7}">
<enable-recall>true</enable-recall>
</ma-options>
</per-ma-options>
</import-attribute-flow>
</mv-data>
</export-ma>
The example then generates a comma-delimited file whose contents are imported into the metaverse and then exported to a call-based data source.
Send comments about this topic to Microsoft
Build date: 2/16/2009