using System;
using Microsoft.MetadirectoryServices;
using Microsoft.DeveloperAndPlatformEvangelism.Demonstrations.TaskVisionII.Utility;
namespace Mms_Metaverse
{
//Rules extension projects must be configured so as to compile into the \Program Files\Microsoft Identity
// Integration Server\Extensions
//When a rules extension project is created using MIIS, it is automatically configured in that way.
/// <summary>
/// Provisions users in the TaskVisionII application directory partition of ADAM.
/// </summary>
public class MVExtensionObject: CLoggingRuleExtension, IMVSynchronization
{
private const string c_sFile_Log = @"Provision_ADAM_TaskVisionII.log";
private const byte c_byThreshold_Log = 10;
private const string c_stAgent_Contributing = @"ActiveDirectory";
private const string c_stAgent_Target = @"ADAM_TaskVisionII";
private const string c_stContainer_Target = @"CN=Users,O=TaskVisionII,C=US";
public MVExtensionObject()
{
base.sFile_Log = MVExtensionObject.c_sFile_Log;
base.byThreshold_Log = MVExtensionObject.c_byThreshold_Log;
}
void IMVSynchronization.Initialize ()
{
//
// TODO: Add initialization logic here
//
}
void IMVSynchronization.Terminate ()
{
//
// TODO: Add termination logic here
//
}
void IMVSynchronization.Provision (MVEntry rCurrentConnector)
{
try
{
/*
* In \Program Files\Microsoft Identity Integration Server\Extensions, there is a library
* assembly called, "Logging.DLL" that can be used to output debug messages.
*
* In this class, methods have been programmed to wrap those of the logging assembly.
*
* For some reason, if one removes the reference to the Logging assembly, then the assembly itself
* gets deleted from the disk. Happily, the source code is in
* \Program Files\Microsoft Identity Integration Server\SourceCode\Logging, so one can compile
* it to get a new copy.
*
* By default, when one creates a rules extension project from the MIIS user interface, a reference
* to the assembly, \Program Files\Microsoft Identity Integration
* Server\bin\assemblies\Microsoft.MetadirectoryServices.dll.
* That assembly exposes the classes that one will need to write a rules extension: in particular,
* it contains the types passed to the rules extension as parameters. However, the Logging assembly
* exposes the same namespace of classes, so if one will be doing any logging, then that is the
* only assembly one requires.
*
*/
this.Log(@"Provisioning ... ");
/*
* Visual Studio.NET, cannot interogate the types exposed from the MIIS assemblies properly, so
* their methods do not show up either in Intellisense or in the Object Browser. However, the
* documentation in the MIIS developer's reference, identifying properties and methods that cannot
* be seen are accurate, and correct references to those properties and methods will compile.
*
*/
this.Log(string.Concat("Object type: ",rCurrentConnector.ObjectType));
switch(rCurrentConnector.ObjectType)
{
case @"person":
case @"group":
break;
default:
return;
}
try
{
string sName = rCurrentConnector[@"cn"].Value;
}
catch(Exception)
{
return;
}
this.Log(string.Concat("Last Contributing Agent: ",rCurrentConnector[@"cn"].LastContributingMA.Name));
if(string.Compare(rCurrentConnector[@"cn"].LastContributingMA.Name,MVExtensionObject.c_stAgent_Contributing,true)!=0)
{
return;
}
ConnectedMA rAgent = rCurrentConnector.ConnectedMAs[MVExtensionObject.c_stAgent_Target];
this.Log(string.Concat(@"Agent: ",rAgent.Name));
int cConnectors = rAgent.Connectors.Count;
string sRelativeDistinguishedName = null;
try
{
sRelativeDistinguishedName = string.Concat(@"CN=",rCurrentConnector[@"cn"].Value);
}
catch(Exception rException)
{
this.Log(string.Concat(@"Exception: ",rException.Message));
return;
}
this.Log(string.Concat(@"Provisioning ",rCurrentConnector[@"cn"].Value));
ReferenceValue rDistinguishedName = rAgent.EscapeDNComponent(sRelativeDistinguishedName).Concat
(MVExtensionObject.c_stContainer_Target);
this.Log(string.Concat(@"DN: ",rDistinguishedName.ToString()));
CSEntry rProvisioned = null;
switch(cConnectors)
{
case 0:
this.Log(@"Starting new connector.");
string sObjectType = null;
switch(rCurrentConnector.ObjectType)
{
case @"person":
sObjectType = "user";
break;
case @"group":
sObjectType = "group";
break;
default:
throw new UnexpectedDataException("Unexpected object type!");
}
rProvisioned = rAgent.Connectors.StartNewConnector(sObjectType);
rProvisioned.DN = rDistinguishedName;
rProvisioned.CommitNewConnector();
break;
case 1:
this.Log(@"Modifying existing connector.");
rProvisioned = rAgent.Connectors.ByIndex[0];
rProvisioned.DN = rDistinguishedName;
break;
default:
throw new UnexpectedDataException("Multiple Connectors on Management Agent!");
}
}
catch(Exception rException)
{
//All exceptions are caught and displayed by the MIIS user interface,
//so this block is merely for the sake of centralizing control over the exception.
this.Log(((rException.Message == null)||(rException.Message == string.Empty))?@"Unknown exception.":string.Concat("Exception: ",rException.Message));
throw rException;
}
}
bool IMVSynchronization.ShouldDeleteFromMV (CSEntry csentry, MVEntry mventry)
{
//
// TODO: Add MV deletion logic here
//
}
}
}