You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
366 lines
11 KiB
366 lines
11 KiB
using System;
|
|
using System.DirectoryServices;
|
|
|
|
namespace UDDI.ActiveDirectory
|
|
{
|
|
/// <summary>
|
|
/// This class manages the ServiceConnectionPoint publication into the AD
|
|
/// </summary>
|
|
public class UDDIServiceConnPoint
|
|
{
|
|
|
|
//------------------------- PUBLIC KEYWORDS -----------------------------
|
|
//
|
|
public const string kwdVendor = "Microsoft Corporation";
|
|
public const string kwdVendorGuid = "83C29870-1DFC-11D3-A193-0000F87A9099";
|
|
public const string kwdTechnology = "UDDI";
|
|
public const string kwdTechnologyVer = "2.0";
|
|
public const string kwdProduct = "UDDI Services";
|
|
public const string kwdProductGuid = "09A92664-D144-49DB-A600-2B3ED04BF639";
|
|
|
|
public const string kwdInquireAPI = "Inquire API";
|
|
public const string kwdInquireAPIGuid = "4CD7E4BC-648B-426D-9936-443EAAC8AE23";
|
|
public const string kwdInquireSvcClass = "UddiInquireUrl";
|
|
|
|
public const string kwdPublishAPI = "Publish API";
|
|
public const string kwdPublishAPIGuid = "64C756D1-3374-4E00-AE83-EE12E38FAE63";
|
|
public const string kwdPublishSvcClass = "UddiPublishUrl";
|
|
|
|
public const string kwdWebSiteSignature = "Web Site";
|
|
public const string kwdWebSiteGuid = "316F991C-2591-4F1A-8FF1-352A76669E37";
|
|
public const string kwdWebSiteSvcClass = "UddiWebSiteUrl";
|
|
|
|
public const string kwdDiscovery = "DiscoveryUrl";
|
|
public const string kwdDiscoveryGuid = "1276768A-1488-4C6F-A8D8-19556C6BE583";
|
|
public const string kwdDiscoverySvcClass= "UddiDiscoveryUrl";
|
|
|
|
public const string kwdAddWebRef = "Add Web Reference";
|
|
public const string kwdAddWebRefGuid = "CE653789-F6D4-41B7-B7F4-31501831897D";
|
|
public const string kwdAddWebRefSvcClass= "UddiAddWebReferenceUrl";
|
|
|
|
//-------------------------- PRIVATE DEFINITIONS --------------------------
|
|
//
|
|
// default keywords for the site node
|
|
// comma separates keywords
|
|
//
|
|
private const string szDefSiteKeywords = kwdTechnology + "," + kwdTechnologyVer + "," +
|
|
kwdVendor + "," + kwdVendorGuid + "," +
|
|
kwdProduct + "," + kwdProductGuid;
|
|
|
|
// INTERNAL representation of the path. Slashes will be replaced with CN's
|
|
// Do not remove or change the separators
|
|
private const char cADPathSeparator = '/';
|
|
private const string szADUDDIRootPath = "System/Microsoft/UDDI/Sites";
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Creates a new entry for the site, right under the root path
|
|
// above
|
|
//
|
|
static public DirectoryEntry CreateSiteEntry( string siteCN )
|
|
{
|
|
if ( siteCN == null )
|
|
throw new ArgumentNullException( "Site CN cannot be null" );
|
|
|
|
if ( siteCN.Length == 0 )
|
|
throw new ArgumentException( "Site CN cannot be empty" );
|
|
|
|
string[] ADPath = szADUDDIRootPath.Split( cADPathSeparator );
|
|
string nodeCN = NormalizeCN( siteCN );
|
|
|
|
DirectoryEntry adRootNode = CreateFullADPath (ADPath);
|
|
|
|
DirectoryEntry adSiteNode = null;
|
|
try
|
|
{
|
|
adSiteNode = adRootNode.Children.Find( nodeCN, "container" );
|
|
}
|
|
catch (Exception)
|
|
{
|
|
adSiteNode = null;
|
|
}
|
|
|
|
if ( adSiteNode == null )
|
|
{
|
|
adSiteNode = adRootNode.Children.Add( nodeCN, "container" );
|
|
adSiteNode.CommitChanges();
|
|
}
|
|
|
|
try
|
|
{
|
|
AddNodeKeywords( adSiteNode );
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
|
|
return adSiteNode;
|
|
}
|
|
|
|
//
|
|
// Removes the Site entry and all the children
|
|
//
|
|
public static void DeleteSiteEntry( string siteCN )
|
|
{
|
|
if ( siteCN == null )
|
|
throw new ArgumentNullException( "Site CN cannot be null" );
|
|
|
|
if ( siteCN.Length == 0 )
|
|
throw new ArgumentException( "Site CN cannot be empty" );
|
|
|
|
string nodeCN = NormalizeCN( siteCN );
|
|
string fullyQualifiedPath = GetFullyQualifiedPath( "" );
|
|
DirectoryEntry entry = new DirectoryEntry( fullyQualifiedPath );
|
|
|
|
DirectoryEntry sub = entry.Children.Find( nodeCN );
|
|
try
|
|
{
|
|
// first, try deleting the node as if it was a leaf
|
|
entry.Children.Remove (sub);
|
|
entry.CommitChanges ();
|
|
}
|
|
catch (Exception) // most likely this is a tree, or we don't have permissions
|
|
{
|
|
// retry deleting the whole tree
|
|
sub.DeleteTree ();
|
|
}
|
|
}
|
|
|
|
|
|
// Drop + Create the whole site node
|
|
public static DirectoryEntry ResetSiteEntry( string siteCN )
|
|
{
|
|
if ( siteCN == null )
|
|
throw new ArgumentNullException( "Site CN cannot be null" );
|
|
|
|
if ( siteCN.Length == 0 )
|
|
throw new ArgumentException( "Site CN cannot be empty" );
|
|
|
|
try
|
|
{
|
|
DeleteSiteEntry( siteCN );
|
|
}
|
|
catch(Exception)
|
|
{
|
|
}
|
|
|
|
return CreateSiteEntry( siteCN );
|
|
}
|
|
|
|
|
|
//
|
|
// Creates a Web Service entry point (e.g. Publish API)
|
|
//
|
|
public static void CreateEntryPoint( string siteCN,
|
|
string bindingKey, string accessPoint,
|
|
string serviceClass,
|
|
string displayName, string description,
|
|
params object[] additionalKeywords )
|
|
{
|
|
if ( siteCN == null || bindingKey == null || accessPoint == null || serviceClass == null)
|
|
throw new ArgumentNullException( "'Site CN', 'Binding Key', 'Acess Point' and 'Service Class' are required parameters" );
|
|
|
|
if ( siteCN.Length == 0 || bindingKey.Length == 0 )
|
|
throw new ArgumentException( "'Site CN', 'Binding Key', 'Acess Point' and 'Service Class' are required parameters" );
|
|
|
|
string entryKey = NormalizeCN( bindingKey );
|
|
|
|
//
|
|
// first, make sure the Site node is OK
|
|
//
|
|
DirectoryEntry siteNode = CreateSiteEntry( siteCN );
|
|
|
|
//
|
|
// then see whether the entry has been created already
|
|
//
|
|
DirectoryEntry svcEntry = null;
|
|
try
|
|
{
|
|
svcEntry = siteNode.Children.Find( entryKey, "serviceConnectionPoint" );
|
|
}
|
|
catch (Exception)
|
|
{
|
|
svcEntry = null;
|
|
}
|
|
|
|
//
|
|
// create a new entry if there is no one yet.
|
|
// Otherwise, just leave it alone
|
|
//
|
|
if ( svcEntry == null )
|
|
{
|
|
svcEntry = siteNode.Children.Add( entryKey, "serviceConnectionPoint" );
|
|
|
|
// now add all the rest
|
|
svcEntry.Properties[ "url" ].Add( accessPoint );
|
|
|
|
if ( displayName != null && displayName.Length > 0 )
|
|
svcEntry.Properties[ "displayName" ].Add( displayName );
|
|
|
|
if ( description != null && description.Length > 0 )
|
|
svcEntry.Properties[ "description" ].Add( description );
|
|
|
|
svcEntry.Properties[ "serviceClassName" ].Add( serviceClass );
|
|
svcEntry.Properties[ "serviceBindingInformation" ].Add( accessPoint );
|
|
|
|
//
|
|
// try to save...
|
|
//
|
|
svcEntry.CommitChanges();
|
|
}
|
|
|
|
// now set the keywords
|
|
try
|
|
{
|
|
AddNodeKeywords( svcEntry, additionalKeywords );
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Removes specific service "entry point" node for the Site
|
|
// E.g., one can drop "Publish API" entry but leave the rest intact
|
|
//
|
|
public static void RemoveEntryPoint( string siteCN, string bindingKey )
|
|
{
|
|
if ( siteCN == null || bindingKey == null )
|
|
throw new ArgumentNullException( "Neither 'Site CN' nor 'Binding Key' can be null" );
|
|
|
|
if ( siteCN.Length == 0 || bindingKey.Length == 0 )
|
|
throw new ArgumentException( "Neither 'Site CN' nor 'Binding Key' can be empty" );
|
|
|
|
string nodeCN = NormalizeCN( siteCN );
|
|
string subKey = NormalizeCN( bindingKey );
|
|
string fullyQualifiedPath = GetFullyQualifiedPath( nodeCN );
|
|
DirectoryEntry entry = new DirectoryEntry( fullyQualifiedPath );
|
|
|
|
DirectoryEntry sub = entry.Children.Find( subKey );
|
|
try
|
|
{
|
|
// first, try deleting the node as if it was a leaf
|
|
entry.Children.Remove (sub);
|
|
entry.CommitChanges ();
|
|
}
|
|
catch (Exception) // most likely this is a tree, or we don't have permissions
|
|
{
|
|
// retry deleting the whole tree
|
|
sub.DeleteTree ();
|
|
}
|
|
}
|
|
|
|
//***************************************************************************
|
|
// Internal helpers go here
|
|
//
|
|
|
|
//
|
|
// Verifies the AD path from the root and creates the missing nodes
|
|
// if necessary. Returns the AD Directory entry that corresponds to
|
|
// the last (rightmost) node in the path
|
|
//
|
|
protected static DirectoryEntry CreateFullADPath (string[] path)
|
|
{
|
|
DirectoryEntry objDE = new DirectoryEntry( "LDAP://RootDSE" );
|
|
string szNamingContext = objDE.Properties["defaultNamingContext"][0].ToString();
|
|
|
|
DirectoryEntry adOurRoot = new DirectoryEntry ("LDAP://" + szNamingContext);
|
|
DirectoryEntry adNode = adOurRoot;
|
|
|
|
if ( path.Length == 0 )
|
|
return adNode;
|
|
|
|
foreach (string pathCN in path)
|
|
{
|
|
string pathPart = NormalizeCN( pathCN );
|
|
|
|
DirectoryEntry subnode = null;
|
|
try
|
|
{
|
|
subnode = adNode.Children.Find( pathPart, "container" );
|
|
}
|
|
catch (Exception) // not found
|
|
{
|
|
subnode = null;
|
|
}
|
|
|
|
if ( subnode == null ) // not found, go create one
|
|
{
|
|
subnode = adNode.Children.Add( pathPart, "container" );
|
|
subnode.CommitChanges();
|
|
}
|
|
|
|
adNode = subnode;
|
|
}
|
|
|
|
return adNode;
|
|
}
|
|
|
|
//
|
|
// Makes sure the CN node is prepended with "cn="
|
|
//
|
|
static protected string NormalizeCN( string szCN )
|
|
{
|
|
string nodeCN = szCN.ToLower();
|
|
|
|
if ( !nodeCN.StartsWith( "cn=" ) )
|
|
nodeCN = "CN=" + szCN;
|
|
else
|
|
nodeCN = szCN;
|
|
|
|
return nodeCN;
|
|
}
|
|
|
|
|
|
//
|
|
// Composes a full "path" based on the defaule naming context and our "root" path
|
|
// Optionally, a "leaf" under the path can be specified
|
|
//
|
|
static protected string GetFullyQualifiedPath( string leafNode )
|
|
{
|
|
string[] ADPath = szADUDDIRootPath.Split( cADPathSeparator );
|
|
string fullyQualifiedPath = "";
|
|
|
|
if ( leafNode != null && leafNode.Length > 0 )
|
|
fullyQualifiedPath = NormalizeCN( leafNode ) + ",";
|
|
|
|
for (int i = ADPath.Length - 1; i >= 0; i-- )
|
|
{
|
|
fullyQualifiedPath += NormalizeCN( ADPath[i] );
|
|
fullyQualifiedPath += ",";
|
|
}
|
|
|
|
DirectoryEntry objRoot = new DirectoryEntry ("LDAP://RootDSE");
|
|
string szNamingContext = objRoot.Properties["defaultNamingContext"][0].ToString();
|
|
|
|
fullyQualifiedPath = "LDAP://" + fullyQualifiedPath + szNamingContext;
|
|
|
|
return fullyQualifiedPath;
|
|
}
|
|
|
|
|
|
//
|
|
// Attempts to add the required keywords to the node
|
|
// Sets up the "required" ones and then appends the "optional"
|
|
//
|
|
static protected void AddNodeKeywords( DirectoryEntry node, params object[] optionalKwds )
|
|
{
|
|
if ( node == null )
|
|
throw new ArgumentNullException ("'Node' cannot be null");
|
|
|
|
string[] keywords = szDefSiteKeywords.Split( ',' );
|
|
foreach ( string szKwd in keywords )
|
|
{
|
|
node.Properties[ "keywords" ].Add( szKwd );
|
|
}
|
|
|
|
foreach ( object szOptKwd in optionalKwds )
|
|
{
|
|
node.Properties[ "keywords" ].Add( szOptKwd.ToString() );
|
|
}
|
|
|
|
node.CommitChanges();
|
|
}
|
|
}
|
|
}
|