Leaked source code of windows server 2003
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.

653 lines
18 KiB

  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Data;
  5. using System.Data.SqlClient;
  6. using System.Xml;
  7. using System.Xml.Serialization;
  8. using System.Windows.Forms;
  9. using System.Security.Principal;
  10. using Microsoft.Win32;
  11. using UDDI;
  12. using UDDI.API;
  13. using UDDI.API.Business;
  14. using UDDI.Replication;
  15. namespace UDDI.Tools
  16. {
  17. class FixDefaultURL
  18. {
  19. //
  20. // Enumerated Types
  21. //
  22. enum LogType
  23. {
  24. ConsoleAndLog,
  25. ConsoleOnly,
  26. LogOnly
  27. }
  28. //
  29. // Constants
  30. //
  31. const string LogFileName = "fixdefaulturl.log.txt";
  32. const string ExceptionFileName = "fixdefaulturl.exceptions.txt";
  33. //
  34. // Globals
  35. //
  36. static StreamWriter logFile;
  37. static StreamWriter exceptionsFile;
  38. static void FixDefaultURLs()
  39. {
  40. //
  41. // Get a list of business keys that have non-default discovery URLs.
  42. //
  43. ArrayList businessEntities = GetBusinessEntities();
  44. int total = businessEntities.Count;
  45. int current = 1;
  46. int numberFixed = 0;
  47. foreach( BusinessEntity businessEntity in businessEntities )
  48. {
  49. //
  50. // Get values for this business.
  51. //
  52. businessEntity.Get();
  53. //
  54. // BusinessEntity.Get() may add the default one, we don't want it.
  55. //
  56. DiscoveryUrlCollection originalList = new DiscoveryUrlCollection();
  57. originalList.Get( businessEntity.BusinessKey );
  58. businessEntity.DiscoveryUrls = originalList;
  59. Log( "*** Processing " + current++ + "/" + total + " *** " );
  60. LogStartBusinessEntity( businessEntity );
  61. DiscoveryUrlCollection filteredList = GetFilterList( businessEntity );
  62. if( filteredList.Count < businessEntity.DiscoveryUrls.Count )
  63. {
  64. try
  65. {
  66. numberFixed++;
  67. LogFixStart( filteredList );
  68. ConnectionManager.BeginTransaction();
  69. //
  70. // Remove duplicate discovery URLs
  71. //
  72. businessEntity.DiscoveryUrls = filteredList;
  73. //
  74. // Fix change records
  75. //
  76. FixChangeRecords( businessEntity );
  77. //
  78. // Fix data. Saving the BusinessEntity will also create a ChangeRecordNew data in our replication stream.
  79. // Other operators will consume this change record, which will update their databases.
  80. //
  81. FixData( businessEntity );
  82. #if never
  83. ChangeRecordNewData changeRecordNewData = new ChangeRecordNewData( businessEntity );
  84. ChangeRecord fixData = new ChangeRecord( changeRecordNewData );
  85. fixData.Process();
  86. #endif
  87. ConnectionManager.Commit();
  88. LogFixEnd( businessEntity );
  89. }
  90. catch( Exception e)
  91. {
  92. WriteException( e );
  93. ConnectionManager.Abort();
  94. }
  95. }
  96. LogDoneBusinessEntity( businessEntity );
  97. }
  98. Log( "BusinessEntities fixed: " + numberFixed );
  99. }
  100. static void FixData( BusinessEntity businessEntity )
  101. {
  102. Log( "\t\tSTART Fixing Data" );
  103. //
  104. // Save the current user ID
  105. //
  106. string currentUserID = Context.User.ID;
  107. try
  108. {
  109. //
  110. // Set the current user to this user to the PUID for this business entity.
  111. //
  112. Context.User.ID = GetPUIDForBusinessEntity( businessEntity.BusinessKey );
  113. //
  114. // Save our business
  115. //
  116. businessEntity.Save();
  117. Log( "\t\tDONE Fixing Data" );
  118. }
  119. finally
  120. {
  121. //
  122. // Restore the ID
  123. //
  124. Context.User.ID = currentUserID;
  125. }
  126. }
  127. static string GetPUIDForBusinessEntity( string businessKey )
  128. {
  129. SqlStoredProcedureAccessor puidSP = new SqlStoredProcedureAccessor();
  130. puidSP.ProcedureName = "net_getPUIDForBusinessEntity";
  131. puidSP.Parameters.Add( "@businessKey", SqlDbType.UniqueIdentifier );
  132. puidSP.Parameters.SetGuidFromString( "@businessKey", businessKey );
  133. SqlDataReaderAccessor reader = puidSP.ExecuteReader();
  134. string puid = "";
  135. try
  136. {
  137. reader.Read();
  138. puid = reader.GetString( 0 );
  139. }
  140. finally
  141. {
  142. reader.Close();
  143. }
  144. return puid;
  145. }
  146. static void FixChangeRecords( BusinessEntity businessEntity )
  147. {
  148. //
  149. // Get all related change records
  150. //
  151. ArrayList newDataChangeRecords = GetChangeRecordsForEntity( businessEntity );
  152. //
  153. // Create and process a correction for each change record.
  154. //
  155. Log( "\t\tSTART Processing Corrections" );
  156. foreach( ChangeRecord changeRecord in newDataChangeRecords )
  157. {
  158. ChangeRecord changeRecordCorrection = CreateCorrection( changeRecord, businessEntity );
  159. changeRecordCorrection.Process();
  160. LogChangeRecordCorrection( changeRecord, changeRecordCorrection );
  161. }
  162. Log( "\t\tDONE Processing Corrections" );
  163. }
  164. static ChangeRecord CreateCorrection( ChangeRecord originalChangeRecord, BusinessEntity businessEntity )
  165. {
  166. ChangeRecordNewData changeRecordNewData = originalChangeRecord.Payload as ChangeRecordNewData;
  167. changeRecordNewData.Entity = businessEntity;
  168. ChangeRecordCorrection changeRecordCorrection = new ChangeRecordCorrection();
  169. changeRecordCorrection.ChangeRecord = originalChangeRecord;
  170. return new ChangeRecord( changeRecordCorrection );
  171. }
  172. static ArrayList GetChangeRecordsForEntity( BusinessEntity businessEntity )
  173. {
  174. string contextID = Guid.NewGuid().ToString();
  175. string operatorKey = Config.GetString( "OperatorKey" );
  176. ArrayList changeRecords = new ArrayList();
  177. SqlDataReaderAccessor resultsReader = null;
  178. try
  179. {
  180. //
  181. // Get all the ChangeRecordNewData change records associated with this entity.
  182. //
  183. SqlStoredProcedureAccessor findSP = new SqlStoredProcedureAccessor();
  184. findSP.ProcedureName = "net_find_changeRecordsByChangeType";
  185. findSP.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
  186. findSP.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
  187. findSP.Parameters.Add( "@entityKey", SqlDbType.UniqueIdentifier );
  188. findSP.Parameters.Add( "@changeTypeID", SqlDbType.TinyInt );
  189. findSP.Parameters.Add( "@rows", SqlDbType.Int, ParameterDirection.Output );
  190. findSP.Parameters.SetGuidFromString( "@contextID", contextID );
  191. findSP.Parameters.SetGuidFromString( "@operatorKey", operatorKey );
  192. findSP.Parameters.SetGuidFromString( "@entityKey", businessEntity.BusinessKey );
  193. findSP.Parameters.SetShort( "@changeTypeID", ( short )ChangeRecordPayloadType.ChangeRecordNewData );
  194. findSP.ExecuteNonQuery();
  195. //
  196. // Retrieve results
  197. //
  198. SqlStoredProcedureAccessor resultsSP = new SqlStoredProcedureAccessor();
  199. resultsSP.ProcedureName = "net_find_changeRecords_commit";
  200. resultsSP.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
  201. resultsSP.Parameters.Add( "@responseLimitCount", SqlDbType.Int );
  202. resultsSP.Parameters.SetGuidFromString( "@contextID", contextID );
  203. resultsSP.Parameters.SetInt( "@responseLimitCount", 0 );
  204. //
  205. // Read our results and create change records from them.
  206. //
  207. resultsReader = resultsSP.ExecuteReader();
  208. while( resultsReader.Read() )
  209. {
  210. ChangeRecord changeRecord = CreateChangeRecord( resultsReader );
  211. if( null != changeRecord )
  212. {
  213. changeRecords.Add( changeRecord );
  214. }
  215. else
  216. {
  217. throw new Exception( "Could not create change record!" );
  218. }
  219. }
  220. }
  221. catch
  222. {
  223. //
  224. // Cleanup on failure.
  225. //
  226. SqlStoredProcedureAccessor cleanupSP = new SqlStoredProcedureAccessor();
  227. cleanupSP.ProcedureName = "net_find_changeRecords_cleanup";
  228. cleanupSP.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
  229. cleanupSP.Parameters.SetGuidFromString( "@contextID", contextID );
  230. cleanupSP.ExecuteNonQuery();
  231. }
  232. finally
  233. {
  234. if( null != resultsReader )
  235. {
  236. resultsReader.Close();
  237. }
  238. }
  239. return changeRecords;
  240. }
  241. static ChangeRecord CreateChangeRecord( SqlDataReaderAccessor reader )
  242. {
  243. ChangeRecord changeRecord = null;
  244. XmlSerializer serializer = null;
  245. switch( (ChangeRecordPayloadType)reader.GetShort( "changeTypeID" ) )
  246. {
  247. case ChangeRecordPayloadType.ChangeRecordNull:
  248. serializer = new XmlSerializer( typeof( ChangeRecordNull ) );
  249. break;
  250. case ChangeRecordPayloadType.ChangeRecordNewData:
  251. serializer = new XmlSerializer( typeof( ChangeRecordNewData ) );
  252. break;
  253. case ChangeRecordPayloadType.ChangeRecordDelete:
  254. serializer = new XmlSerializer( typeof( ChangeRecordDelete ) );
  255. break;
  256. case ChangeRecordPayloadType.ChangeRecordPublisherAssertion:
  257. serializer = new XmlSerializer( typeof( ChangeRecordPublisherAssertion ) );
  258. break;
  259. case ChangeRecordPayloadType.ChangeRecordHide:
  260. serializer = new XmlSerializer( typeof( ChangeRecordHide ) );
  261. break;
  262. case ChangeRecordPayloadType.ChangeRecordDeleteAssertion:
  263. serializer = new XmlSerializer( typeof( ChangeRecordDeleteAssertion ) );
  264. break;
  265. case ChangeRecordPayloadType.ChangeRecordAcknowledgement:
  266. serializer = new XmlSerializer( typeof( ChangeRecordAcknowledgement ) );
  267. break;
  268. case ChangeRecordPayloadType.ChangeRecordCorrection:
  269. serializer = new XmlSerializer( typeof( ChangeRecordCorrection ) );
  270. break;
  271. }
  272. StringReader stringReader = new StringReader( reader.GetString( "changeData" ) );
  273. try
  274. {
  275. changeRecord = new ChangeRecord();
  276. changeRecord.AcknowledgementRequested = ( reader.GetInt( "flag" ) & (int)ChangeRecordFlags.AcknowledgementRequested ) > 0;
  277. changeRecord.ChangeID.NodeID = reader.GetString( "OperatorKey" );
  278. changeRecord.ChangeID.OriginatingUSN = reader.GetLong( "USN" );
  279. ChangeRecordBase changeRecordBase = ( ChangeRecordBase ) serializer.Deserialize( stringReader );
  280. if( changeRecordBase is ChangeRecordCorrection )
  281. {
  282. //
  283. // The query to find change records will do correction 'fixups'. That is, the changeData of this
  284. // change record will be replaced with the changeData from the correction. The problem with this is
  285. // that the original change data will now look like a correction. To distinguish these types of
  286. // change records, we look to see if the OriginatingUSN's match. If the OriginatingUSN's match,
  287. // we want they payload of the change record in this correction. This payload will contain the
  288. // corrected data that we want.
  289. //
  290. ChangeRecordCorrection changeRecordCorrection = ( ChangeRecordCorrection ) changeRecordBase;
  291. if( changeRecordCorrection.ChangeRecord.ChangeID.OriginatingUSN == changeRecord.ChangeID.OriginatingUSN )
  292. {
  293. changeRecordBase = changeRecordCorrection.ChangeRecord.Payload;
  294. }
  295. }
  296. changeRecord.Payload = changeRecordBase;
  297. }
  298. finally
  299. {
  300. stringReader.Close();
  301. }
  302. return changeRecord;
  303. }
  304. static DiscoveryUrlCollection GetFilterList( BusinessEntity businessEntity )
  305. {
  306. DiscoveryUrlCollection filterList = new DiscoveryUrlCollection();
  307. //
  308. // Get the default URL
  309. //
  310. string defaultDiscoveryUrl= Config.GetString( "DefaultDiscoveryURL" ) + businessEntity.BusinessKey;
  311. foreach( DiscoveryUrl discoveryUrl in businessEntity.DiscoveryUrls )
  312. {
  313. //
  314. // Do a case in-sensitive search
  315. //
  316. if( string.Compare( discoveryUrl.Value, defaultDiscoveryUrl, true ) != 0 )
  317. {
  318. filterList.Add( discoveryUrl );
  319. }
  320. }
  321. return filterList;
  322. }
  323. static ArrayList GetBusinessEntities()
  324. {
  325. ArrayList businessKeyList = new ArrayList();
  326. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
  327. sp.ProcedureName = "net_find_businessKeysWithDiscoveryURLs";
  328. SqlDataReaderAccessor reader = sp.ExecuteReader();
  329. ArrayList businessEntities = new ArrayList();
  330. try
  331. {
  332. while( reader.Read() )
  333. {
  334. BusinessEntity businessEntity = new BusinessEntity( reader.GetGuidString( 0 ) );
  335. businessEntities.Add( businessEntity );
  336. }
  337. }
  338. finally
  339. {
  340. reader.Close();
  341. }
  342. return businessEntities;
  343. }
  344. [STAThread]
  345. static void Main(string[] args)
  346. {
  347. Log( "Microsoft (R) FixDefaultURL Migrate Utility", FixDefaultURL.LogType.ConsoleOnly );
  348. Log( "Copyright (C) Microsoft Corp. 2002. All rights reserved.\n", FixDefaultURL.LogType.ConsoleOnly );
  349. try
  350. {
  351. //
  352. // Process command line arguments
  353. //
  354. ProcessCommandLineArgs( args );
  355. //
  356. // Init
  357. //
  358. Initialize();
  359. //
  360. // Fix our URLs
  361. //
  362. FixDefaultURLs();
  363. }
  364. catch( Exception e )
  365. {
  366. WriteException( "Uncaught exception: " + e.ToString() );
  367. }
  368. finally
  369. {
  370. logFile.Close();
  371. if( null != exceptionsFile )
  372. {
  373. exceptionsFile.Close();
  374. }
  375. }
  376. }
  377. static void ProcessCommandLineArgs( string[] commandLineArgs )
  378. {
  379. //
  380. // No command line args.
  381. //
  382. }
  383. static bool ValidatePublisher()
  384. {
  385. bool validPublisher = Context.User.IsRegistered;
  386. //
  387. // Make sure the user is a UDDI publisher.
  388. //
  389. if( false == validPublisher )
  390. {
  391. DialogResult dialogResult = MessageBox.Show( "You are not registered as a publisher on this UDDI Site? You must register before performing this operation. Would you like to register now?",
  392. "UDDI",
  393. MessageBoxButtons.YesNo );
  394. if( DialogResult.Yes == dialogResult )
  395. {
  396. try
  397. {
  398. Context.User.Register();
  399. validPublisher = Context.User.IsRegistered;
  400. }
  401. catch( Exception registrationException )
  402. {
  403. MessageBox.Show( "An exception occurred when trying to register:\r\n\r\n" + registrationException.ToString() );
  404. }
  405. }
  406. }
  407. return validPublisher;
  408. }
  409. static void Initialize()
  410. {
  411. //
  412. // Open a connection to our UDDI database.
  413. //
  414. ConnectionManager.Open( true, false );
  415. //
  416. // Create our log file.
  417. //
  418. logFile = new StreamWriter( File.Open( LogFileName, FileMode.Append, FileAccess.Write, FileShare.Read ) );
  419. logFile.WriteLine( "--------------------- STARTING NEW LOG (" + DateTime.Now.ToString() + ")--------------------- " );
  420. //
  421. // Get UDDI site configuration settings.
  422. //
  423. Config.Refresh();
  424. //
  425. // Make sure the user is allowed to run this program.
  426. //
  427. WindowsIdentity identity = WindowsIdentity.GetCurrent();
  428. WindowsPrincipal principal = new WindowsPrincipal( identity );
  429. Context.User.SetRole( principal );
  430. if( !Context.User.IsAdministrator )
  431. {
  432. MessageBox.Show( "Access denied.\r\n\r\nThis program must be executed by a member of the '"
  433. + Config.GetString( "GroupName.Administrators" ) + "'\r\ngroup. The current user '"
  434. + identity.Name + "' is not a member of this group." );
  435. return;
  436. }
  437. //
  438. // Make sure the user is a valid publisher.
  439. //
  440. if( false == ValidatePublisher() )
  441. {
  442. Log( "You must be a UDDI publisher in order to run this program", LogType.ConsoleOnly );
  443. System.Environment.Exit( 1 );
  444. }
  445. }
  446. static void WriteException( Exception e )
  447. {
  448. WriteException( e.ToString() );
  449. }
  450. static void WriteException( string msg )
  451. {
  452. if( null == exceptionsFile )
  453. {
  454. //
  455. // Create our exceptions file.
  456. //
  457. exceptionsFile = new StreamWriter( File.Open( ExceptionFileName, FileMode.Append, FileAccess.Write, FileShare.Read ) );
  458. exceptionsFile.WriteLine( "--------------------- STARTING NEW LOG (" + DateTime.Now.ToString() + ")--------------------- " );
  459. }
  460. Log( exceptionsFile, msg, LogType.ConsoleAndLog );
  461. }
  462. static void Log( string message )
  463. {
  464. Log( message, LogType.ConsoleAndLog );
  465. }
  466. static void Log( string message, LogType logType )
  467. {
  468. Log( logFile, message, logType );
  469. }
  470. static void Log( StreamWriter log, string message, LogType logType )
  471. {
  472. switch ( logType )
  473. {
  474. case LogType.ConsoleAndLog:
  475. {
  476. Console.WriteLine( message );
  477. log.WriteLine( "{0}: {1}", DateTime.Now.ToLongTimeString(), message );
  478. break;
  479. }
  480. case LogType.ConsoleOnly:
  481. {
  482. Console.WriteLine( message );
  483. break;
  484. }
  485. default:
  486. {
  487. log.WriteLine( "{0}: {1}", DateTime.Now.ToLongTimeString(), message );
  488. break;
  489. }
  490. }
  491. }
  492. private static string Serialize( object obj )
  493. {
  494. UTF8EncodedStringWriter stringWriter = new UTF8EncodedStringWriter();
  495. try
  496. {
  497. XmlSerializer serializer = new XmlSerializer( obj.GetType() );
  498. XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
  499. namespaces.Add( "", "urn:uddi-org:api_v2" );
  500. serializer.Serialize( stringWriter, obj, namespaces );
  501. }
  502. finally
  503. {
  504. stringWriter.Close();
  505. }
  506. return stringWriter.ToString();
  507. }
  508. static void LogStartBusinessEntity( BusinessEntity businessEntity )
  509. {
  510. Log( "START Examining: " + businessEntity.BusinessKey );
  511. Log( "\tOriginal DiscoveryUrls:" );
  512. foreach( DiscoveryUrl discoveryUrl in businessEntity.DiscoveryUrls )
  513. {
  514. Log( "\t\t" + discoveryUrl.Value );
  515. }
  516. }
  517. static void LogDoneBusinessEntity( BusinessEntity businessEntity )
  518. {
  519. Log( "DONE Examining: " + businessEntity.BusinessKey );
  520. }
  521. static void LogFixStart( DiscoveryUrlCollection filteredList )
  522. {
  523. Log( "\tSTART Fixing duplicates; new DiscoveryUrl list will be:" );
  524. if( filteredList.Count == 0 )
  525. {
  526. Log( "\t\tNo Discovery Urls besides default." );
  527. }
  528. else
  529. {
  530. foreach( DiscoveryUrl discoveryUrl in filteredList )
  531. {
  532. Log( "\t\t" + discoveryUrl.Value );
  533. }
  534. }
  535. }
  536. static void LogFixEnd( BusinessEntity businessEntity )
  537. {
  538. Log( "\tDONE Fixing duplicates" );
  539. }
  540. static void LogChangeRecordCorrection( ChangeRecord changeRecord, ChangeRecord changeRecordCorrection )
  541. {
  542. Log( "\t\t\tCorrecting USN: " + changeRecord.ChangeID.OriginatingUSN );
  543. }
  544. }
  545. }