PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/FIMPSClient.cs

#
C# | 341 lines | 234 code | 39 blank | 68 comment | 11 complexity | fdeb18c361c36223b3494bf38a0ee7d6 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.ServiceModel;
  6. using System.Security.Principal;
  7. using System.Xml.Schema;
  8. using Microsoft.ResourceManagement.Client;
  9. using Microsoft.ResourceManagement.ObjectModel;
  10. using Microsoft.ResourceManagement.ObjectModel.ResourceTypes;
  11. using Microsoft.ResourceManagement.Client.WsTransfer;
  12. using Microsoft.ResourceManagement.Client.WsEnumeration;
  13. using System.ServiceModel.Channels;
  14. using System.Net;
  15. using System.Management.Automation;
  16. using System.Management.Automation.Host;
  17. using System.Globalization;
  18. namespace Quest.FIMPowerShellSnapin
  19. {
  20. public class FIMPSClient
  21. {
  22. private const String _defaultResourceManagementPort = "5725";
  23. private const String _defaultSTSPort = "5726";
  24. private MexClient _mexClient;
  25. private WsTransferClient _wsTransferClient;
  26. private WsTransferFactoryClient _wsTransferFactoryClient;
  27. private WsEnumerationClient _wsEnumerationClient;
  28. private RmResourceFactory _resourceFactory;
  29. private RmRequestFactory _requestFactory;
  30. private PSHost _pSHost;
  31. private PSCredential _pSCreds;
  32. private string _fIMServer;
  33. private string _fIMPort;
  34. private string[] _defaultAttrNames;
  35. private bool _schemaCached;
  36. private SchemaCache _schemaCache;
  37. /// <summary>
  38. /// This class contains the names of the FIM web service endpoints. They are copied from
  39. /// Microsoft.ResourceManagement.Client.Constants.Endpoint, which is unfortunately marked internal, which makes
  40. /// them inaccessible.
  41. /// </summary>
  42. internal class EndpointNames
  43. {
  44. private EndpointNames() { }
  45. public const String MEX = "ResourceManagementService/MEX";
  46. public const String Resource = "ResourceManagementService/Resource";
  47. public const String ResourceFactory = "ResourceManagementService/ResourceFactory";
  48. public const String Enumeration = "ResourceManagementService/Enumeration";
  49. public const String Alternate = "ResourceManagementService/Alternate";
  50. }
  51. public FIMPSClient(string fIMserverParam, PSCredential creds, PSHost pSHost)
  52. {
  53. // Save reference to PS host environment
  54. _pSHost = pSHost;
  55. _pSCreds = creds;
  56. // Separate FIM server name and port if any, and save
  57. int colonPosition = fIMserverParam.IndexOf(':');
  58. if (colonPosition < 0)
  59. {
  60. _fIMServer = fIMserverParam.ToLower();
  61. _fIMPort = _defaultResourceManagementPort;
  62. }
  63. else
  64. {
  65. _fIMServer = fIMserverParam.Substring(0, colonPosition);
  66. _fIMPort = fIMserverParam.Substring(colonPosition + 1);
  67. /*!!! check _fIMPort for numeric value*/
  68. }
  69. _mexClient = CreateMexClient();
  70. _wsTransferClient = CreateTransferClient();
  71. _wsTransferFactoryClient = CreateTransferFactoryClient();
  72. _wsEnumerationClient = CreateEnumerationClient();
  73. _resourceFactory = new RmResourceFactory();
  74. _requestFactory = new RmRequestFactory();
  75. _schemaCache = new SchemaCache();
  76. }
  77. /// <summary>
  78. /// Refreshes the metadata from the service.
  79. /// </summary>
  80. public XmlSchemaSet RefreshSchema()
  81. {
  82. XmlSchemaSet metadata = _mexClient.Get();
  83. lock (_requestFactory)
  84. {
  85. _requestFactory = new RmRequestFactory(metadata);
  86. }
  87. lock (_resourceFactory)
  88. {
  89. _resourceFactory = new RmResourceFactory(metadata);
  90. }
  91. lock (_schemaCache)
  92. {
  93. _schemaCache = new SchemaCache(metadata);
  94. }
  95. _schemaCached = true;
  96. return metadata;
  97. }
  98. public SchemaCache Schema
  99. {
  100. get
  101. {
  102. if(!_schemaCached)
  103. {
  104. RefreshSchema();
  105. }
  106. return _schemaCache;
  107. }
  108. }
  109. #region ResourceTransfer
  110. /// <summary>
  111. /// Retrieves the object with the given ObjectId
  112. /// </summary>
  113. /// <param name="objectId">The ObjectId of the requested object.</param>
  114. /// <returns>The object or null if not found</returns>
  115. /// <exception cref="System.ServiceModel.FaultException">System.ServiceModel.FaultException thrown when failures occur.</exception>
  116. public RmResource Get(RmReference objectId)
  117. {
  118. return Get(objectId, null, null);
  119. }
  120. /// <summary>
  121. /// Retrieves the representation of an object with the given ObjectId in the given culture.
  122. /// </summary>
  123. /// <param name="objectId">The ObjectId of the requested object.</param>
  124. /// <param name="culture">The requested culture representation of the object.</param>
  125. /// <returns>The object or null if not found.</returns>
  126. public RmResource Get(RmReference objectId, CultureInfo culture)
  127. {
  128. return Get(objectId, culture, null);
  129. }
  130. /// <summary>
  131. /// Retrieves the object and the specified attributes with the given ObjectId.
  132. /// </summary>
  133. /// <param name="objectId">The ObjectId of the requested object.</param>
  134. /// <param name="attributes">The list of attributes on the object to return.</param>
  135. /// <returns></returns>
  136. public RmResource Get(RmReference objectId, String[] attributes)
  137. {
  138. return Get(objectId, null, attributes);
  139. }
  140. /// <summary>
  141. /// Retrieves the object and the specified attributes with the given ObjectId and in the specified culture.
  142. /// </summary>
  143. /// <param name="objectId">The ObjectId of the requested object.</param>
  144. /// <param name="culture">The requested culture representation of the object.</param>
  145. /// <param name="attributes">The list of attributes on the object to return.</param>
  146. /// <returns>The requested object, or null if it is not found.</returns>
  147. public RmResource Get(RmReference objectId, CultureInfo culture, String[] attributes)
  148. {
  149. GetRequest request = _requestFactory.CreateGetRequest(objectId, culture, attributes);
  150. GetResponse response = _wsTransferClient.Get(request);
  151. return _resourceFactory.CreateResource(response);
  152. }
  153. #endregion
  154. #region Enumeration
  155. /// <summary>
  156. /// Returns an enumerator that can traverse all objects matching the given filter.
  157. /// </summary>
  158. /// <param name="filter">The XPath filter of which objects to select.</param>
  159. /// <returns>An enumerator object which can be consumed in foreach statements.</returns>
  160. public IEnumerable<RmResource> Enumerate(String filter)
  161. {
  162. return this.Enumerate(filter, new string[] { });
  163. }
  164. /// <summary>
  165. /// Returns an enumerator that can traverse all objects matching the given filter.
  166. ///
  167. /// Each object only contains the specified attributes.
  168. /// </summary>
  169. /// <param name="filter">The XPath filter of which objects to select.</param>
  170. /// <param name="attributes">A list of attribute names to include in returned objects.</param>
  171. /// <returns>An enumerator object which can be consumed in foreach statements.</returns>
  172. public IEnumerable<RmResource> Enumerate(String filter, String[] attributes)
  173. {
  174. if (String.IsNullOrEmpty(filter))
  175. {
  176. throw new ArgumentNullException("filter");
  177. }
  178. return _requestFactory.CreateEnumeration(_wsEnumerationClient, _resourceFactory, filter, attributes);
  179. }
  180. #endregion
  181. #region Create
  182. /// <summary>
  183. /// Creates the given resource and returns its ObjectId.
  184. /// This method does not set the ObjectId of newResource.
  185. /// </summary>
  186. /// <param name="newResource">The resource to create.</param>
  187. /// <returns>The ObjectId of the resource.</returns>
  188. public RmReference Create(RmResource newResource)
  189. {
  190. if (newResource == null)
  191. throw new ArgumentNullException("newResource");
  192. CreateRequest request = _requestFactory.CreateCreateRequest(newResource);
  193. CreateResponse response = _wsTransferFactoryClient.Create(request);
  194. try
  195. {
  196. RmReference reference = new RmReference(response.ResourceCreated.EndpointReference.ReferenceProperties.ResourceReferenceProperty.Value);
  197. newResource.ObjectID = reference;
  198. return reference;
  199. }
  200. catch (NullReferenceException)
  201. {
  202. return new RmReference();
  203. }
  204. catch (FormatException)
  205. {
  206. return new RmReference();
  207. }
  208. }
  209. #endregion
  210. #region Put
  211. /// <summary>
  212. /// Saves changes made to an object recorded by the transaction to the service.
  213. /// </summary>
  214. /// <param name="transaction">The transaction object which recorded changes made to a Resource object.</param>
  215. /// <returns>True upon successful operation.</returns>
  216. public bool Put(RmResourceChanges transaction)
  217. {
  218. if (transaction == null)
  219. {
  220. throw new ArgumentNullException("transaction");
  221. }
  222. PutRequest request = _requestFactory.CreatePutRequest(transaction);
  223. PutResponse response = _wsTransferClient.Put(request);
  224. if (response == null)
  225. return false;
  226. else
  227. return true;
  228. }
  229. #endregion
  230. #region Delete
  231. /// <summary>
  232. /// Deletes the object with the given ObjectId.
  233. /// </summary>
  234. /// <param name="objectId">The ObjectId of the object to delete.</param>
  235. /// <returns>True upon successful deletion.</returns>
  236. public bool Delete(RmReference objectId)
  237. {
  238. DeleteRequest request = _requestFactory.CreateDeleteRequest(objectId);
  239. DeleteResponse response = _wsTransferClient.Delete(request);
  240. if (response == null)
  241. return false;
  242. else
  243. return true;
  244. }
  245. #endregion
  246. /// <summary>
  247. /// Returns true if the schema has been cached for this client.
  248. /// </summary>
  249. public bool SchemaCached
  250. {
  251. get
  252. {
  253. return _schemaCached;
  254. }
  255. }
  256. private MexClient CreateMexClient()
  257. {
  258. EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.MEX), CreateFIMSPNIdentity());
  259. WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
  260. binding.MaxReceivedMessageSize = Int32.MaxValue;
  261. return new MexClient(binding, remoteAddress);
  262. }
  263. private WsTransferClient CreateTransferClient()
  264. {
  265. EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.Resource), CreateFIMSPNIdentity());
  266. System.ServiceModel.WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
  267. binding.Security.Message.EstablishSecurityContext = false;
  268. binding.MaxReceivedMessageSize = Int32.MaxValue;
  269. WsTransferClient client = new WsTransferClient(binding, remoteAddress);
  270. client.ClientCredentials.Windows.ClientCredential = _pSCreds.GetNetworkCredential();
  271. return client;
  272. }
  273. private WsTransferFactoryClient CreateTransferFactoryClient()
  274. {
  275. EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.ResourceFactory), CreateFIMSPNIdentity());
  276. System.ServiceModel.WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
  277. binding.Security.Message.EstablishSecurityContext = false;
  278. binding.MaxReceivedMessageSize = Int32.MaxValue;
  279. WsTransferFactoryClient client = new WsTransferFactoryClient(binding, remoteAddress);
  280. client.ClientCredentials.Windows.ClientCredential = _pSCreds.GetNetworkCredential();
  281. return client;
  282. }
  283. private WsEnumerationClient CreateEnumerationClient()
  284. {
  285. EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.Enumeration), CreateFIMSPNIdentity());
  286. System.ServiceModel.WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
  287. binding.Security.Message.EstablishSecurityContext = false;
  288. binding.MaxReceivedMessageSize = Int32.MaxValue;
  289. WsEnumerationClient client = new WsEnumerationClient(binding, remoteAddress);
  290. client.ClientCredentials.Windows.ClientCredential = _pSCreds.GetNetworkCredential();
  291. return client;
  292. }
  293. private Uri CreateServiceEndpointURI(string serviceEndpointName)
  294. {
  295. return new Uri(String.Format("http://{0}:{1}/{2}", _fIMServer, _fIMPort, serviceEndpointName));
  296. }
  297. EndpointIdentity CreateFIMSPNIdentity()
  298. {
  299. return EndpointIdentity.CreateSpnIdentity("IdentityManagementService/" + _fIMServer);
  300. }
  301. }
  302. }