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.

441 lines
12 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Specialized;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Data.SqlClient;
  7. using System.IO;
  8. using System.Text;
  9. using System.Xml;
  10. using System.Xml.Serialization;
  11. using UDDI;
  12. using UDDI.API;
  13. using UDDI.API.Binding;
  14. using UDDI.API.Business;
  15. using UDDI.API.Service;
  16. using UDDI.API.ServiceType;
  17. using UDDI.Diagnostics;
  18. namespace UDDI.Replication
  19. {
  20. [XmlRoot( "changeRecords", Namespace=UDDI.Replication.Constants.Namespace )]
  21. public class ChangeRecordDetail
  22. {
  23. [XmlElement( "changeRecord" )]
  24. public ChangeRecordCollection ChangeRecords = new ChangeRecordCollection();
  25. public ChangeRecordDetail()
  26. {
  27. }
  28. }
  29. [XmlRoot( "highWaterMarks", Namespace=UDDI.Replication.Constants.Namespace )]
  30. public class HighWaterMarkDetail
  31. {
  32. [XmlElement( "highWaterMark" )]
  33. public ChangeRecordVectorCollection HighWaterMarks = new ChangeRecordVectorCollection();
  34. }
  35. [XmlRoot( "get_changeRecords", Namespace=UDDI.Replication.Constants.Namespace )]
  36. public class GetChangeRecords
  37. {
  38. //
  39. // Element: requestingNode
  40. //
  41. [XmlElement( "requestingNode" )]
  42. public string RequestingNode;
  43. //
  44. // Element: changesAlreadySeen
  45. //
  46. private ChangeRecordVectorCollection changesAlreadySeen;
  47. [XmlArray( "changesAlreadySeen" ), XmlArrayItem( "highWaterMark" )]
  48. public ChangeRecordVectorCollection ChangesAlreadySeen
  49. {
  50. get
  51. {
  52. if( null == changesAlreadySeen )
  53. changesAlreadySeen = new ChangeRecordVectorCollection();
  54. return changesAlreadySeen;
  55. }
  56. set { changesAlreadySeen = value; }
  57. }
  58. //
  59. // Element: responseLimitCount
  60. //
  61. private int responseLimitCount = -1;
  62. [XmlElement( "responseLimitCount" ), DefaultValue( -1 )]
  63. public int ResponseLimitCount
  64. {
  65. get { return responseLimitCount; }
  66. set { responseLimitCount = value; }
  67. }
  68. //
  69. // Element: responseLimitVector
  70. //
  71. private ChangeRecordVectorCollection responseLimitVector;
  72. [XmlArray( "responseLimitVector" ), XmlArrayItem( "highWaterMark" )]
  73. public ChangeRecordVectorCollection ResponseLimitVectorSerialize
  74. {
  75. get
  76. {
  77. if( -1 != ResponseLimitCount || Utility.CollectionEmpty( responseLimitVector ) )
  78. return null;
  79. return responseLimitVector;
  80. }
  81. set { responseLimitVector = value; }
  82. }
  83. [XmlIgnore]
  84. public ChangeRecordVectorCollection ResponseLimitVector
  85. {
  86. get
  87. {
  88. if( null == responseLimitVector )
  89. responseLimitVector = new ChangeRecordVectorCollection();
  90. return responseLimitVector;
  91. }
  92. }
  93. /// ****************************************************************
  94. /// public Get
  95. /// ----------------------------------------------------------------
  96. /// <summary>
  97. /// </summary>
  98. /// ****************************************************************
  99. ///
  100. public ChangeRecordDetail Get()
  101. {
  102. Debug.VerifySetting( "OperatorKey" );
  103. ChangeRecordDetail detail = new ChangeRecordDetail();
  104. try
  105. {
  106. //
  107. // Get the list of known operators.
  108. //
  109. StringCollection operators = new StringCollection();
  110. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
  111. sp.ProcedureName = "net_operators_get";
  112. SqlDataReaderAccessor reader = sp.ExecuteReader();
  113. try
  114. {
  115. while( reader.Read() )
  116. {
  117. operators.Add( reader.GetGuidString( "operatorKey" ) );
  118. }
  119. }
  120. finally
  121. {
  122. reader.Close();
  123. }
  124. //
  125. // Set the search criteria for change records.
  126. //
  127. foreach( string operatorKey in operators )
  128. {
  129. long startUSN;
  130. long stopUSN;
  131. startUSN = 0;
  132. foreach( ChangeRecordVector mark in ChangesAlreadySeen )
  133. {
  134. if( 0 == String.Compare( operatorKey, mark.NodeID, true ) )
  135. {
  136. startUSN = mark.OriginatingUSN + 1;
  137. break;
  138. }
  139. }
  140. stopUSN = System.Int64.MaxValue;
  141. foreach( ChangeRecordVector mark in ResponseLimitVector )
  142. {
  143. if( 0 == String.Compare( operatorKey, mark.NodeID, true ) )
  144. {
  145. stopUSN = mark.OriginatingUSN;
  146. break;
  147. }
  148. }
  149. FindChangeRecords.SetRange( operatorKey, startUSN, stopUSN );
  150. }
  151. //
  152. // Retrieve the change records.
  153. //
  154. int limit = Config.GetInt( "Replication.ResponseLimitCountDefault" );
  155. if( ResponseLimitCount >= 0 && ResponseLimitCount <= limit )
  156. limit = ResponseLimitCount;
  157. reader = FindChangeRecords.RetrieveResults( limit );
  158. try
  159. {
  160. while( reader.Read() )
  161. {
  162. XmlSerializer serializer = null;
  163. switch( (ChangeRecordPayloadType)reader.GetShort( "changeTypeID" ) )
  164. {
  165. case ChangeRecordPayloadType.ChangeRecordNull:
  166. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordNull ) );
  167. break;
  168. case ChangeRecordPayloadType.ChangeRecordNewData:
  169. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordNewData ) );
  170. break;
  171. case ChangeRecordPayloadType.ChangeRecordDelete:
  172. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordDelete ) );
  173. break;
  174. case ChangeRecordPayloadType.ChangeRecordPublisherAssertion:
  175. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordPublisherAssertion ) );
  176. break;
  177. case ChangeRecordPayloadType.ChangeRecordHide:
  178. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordHide ) );
  179. break;
  180. case ChangeRecordPayloadType.ChangeRecordDeleteAssertion:
  181. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordDeleteAssertion ) );
  182. break;
  183. case ChangeRecordPayloadType.ChangeRecordAcknowledgement:
  184. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordAcknowledgement ) );
  185. break;
  186. case ChangeRecordPayloadType.ChangeRecordCorrection:
  187. serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordCorrection ) );
  188. break;
  189. }
  190. StringReader stringReader = new StringReader( reader.GetString( "changeData" ) );
  191. try
  192. {
  193. ChangeRecord changeRecord = new ChangeRecord();
  194. changeRecord.AcknowledgementRequested = ( reader.GetInt( "flag" ) & (int)ChangeRecordFlags.AcknowledgementRequested ) > 0;
  195. changeRecord.ChangeID.NodeID = reader.GetString( "OperatorKey" );
  196. changeRecord.ChangeID.OriginatingUSN = reader.GetLong( "USN" );
  197. ChangeRecordBase changeRecordBase = ( ChangeRecordBase ) serializer.Deserialize( stringReader );
  198. if( changeRecordBase is ChangeRecordCorrection )
  199. {
  200. //
  201. // The query to find change records will do correction 'fixups'. That is, the changeData of this
  202. // change record will be replaced with the changeData from the correction. The problem with this is
  203. // that the original change data will now look like a correction. To distinguish these types of
  204. // change records, we look to see if the OriginatingUSN's match. If the OriginatingUSN's match,
  205. // we want they payload of the change record in this correction. This payload will contain the
  206. // corrected data that we want.
  207. //
  208. ChangeRecordCorrection changeRecordCorrection = ( ChangeRecordCorrection ) changeRecordBase;
  209. if( changeRecordCorrection.ChangeRecord.ChangeID.OriginatingUSN == changeRecord.ChangeID.OriginatingUSN )
  210. {
  211. changeRecordBase = changeRecordCorrection.ChangeRecord.Payload;
  212. }
  213. }
  214. changeRecord.Payload = changeRecordBase;
  215. detail.ChangeRecords.Add( changeRecord );
  216. }
  217. finally
  218. {
  219. stringReader.Close();
  220. }
  221. }
  222. }
  223. finally
  224. {
  225. reader.Close();
  226. }
  227. }
  228. catch( Exception e )
  229. {
  230. Debug.OperatorMessage(
  231. SeverityType.Error,
  232. CategoryType.Replication,
  233. OperatorMessageType.None,
  234. "Could not retrieve change records:\r\n" + e.ToString() );
  235. FindChangeRecords.CleanUp();
  236. throw;
  237. }
  238. return detail;
  239. }
  240. public override string ToString()
  241. {
  242. XmlSerializer serializer = new XmlSerializer( GetType() );
  243. UTF8EncodedStringWriter stringWriter = new UTF8EncodedStringWriter();
  244. try
  245. {
  246. serializer.Serialize( stringWriter, this );
  247. return stringWriter.ToString();
  248. }
  249. finally
  250. {
  251. stringWriter.Close();
  252. }
  253. }
  254. }
  255. public class FindChangeRecords
  256. {
  257. public static int SetRange( string operatorKey, long startUSN, long stopUSN )
  258. {
  259. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
  260. sp.ProcedureName = "net_find_changeRecords";
  261. sp.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
  262. sp.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
  263. sp.Parameters.Add( "@startUSN", SqlDbType.BigInt );
  264. sp.Parameters.Add( "@stopUSN", SqlDbType.BigInt );
  265. sp.Parameters.Add( "@rows", SqlDbType.Int, ParameterDirection.Output );
  266. sp.Parameters.SetGuid( "@contextID", Context.ContextID );
  267. sp.Parameters.SetGuidFromString( "@operatorKey", operatorKey );
  268. sp.Parameters.SetLong( "@startUSN", startUSN );
  269. sp.Parameters.SetLong( "@stopUSN", stopUSN );
  270. sp.ExecuteNonQuery();
  271. return sp.Parameters.GetInt( "@rows" );
  272. }
  273. public static SqlDataReaderAccessor RetrieveResults( int maxRows )
  274. {
  275. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
  276. sp.ProcedureName = "net_find_changeRecords_commit";
  277. sp.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
  278. sp.Parameters.Add( "@responseLimitCount", SqlDbType.Int );
  279. sp.Parameters.SetGuid( "@contextID", Context.ContextID );
  280. sp.Parameters.SetInt( "@responseLimitCount", maxRows );
  281. SqlDataReaderAccessor reader = sp.ExecuteReader();
  282. return reader;
  283. }
  284. public static void CleanUp()
  285. {
  286. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
  287. sp.ProcedureName = "net_find_changeRecords_cleanup";
  288. sp.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
  289. sp.Parameters.SetGuid( "@contextID", Context.ContextID );
  290. sp.ExecuteNonQuery();
  291. }
  292. }
  293. [XmlRoot( "notify_changeRecordsAvailable", Namespace=UDDI.Replication.Constants.Namespace )]
  294. public class NotifyChangeRecordsAvailable
  295. {
  296. //
  297. // Element: notifyingNode
  298. //
  299. [XmlElement( "notifyingNode" )]
  300. public string NotifyingNode;
  301. //
  302. // Element: changesAvailable
  303. //
  304. private ChangeRecordVectorCollection highWaterMarks;
  305. [XmlArray( "changesAvailable" ), XmlArrayItem( "highWaterMark" )]
  306. public ChangeRecordVectorCollection HighWaterMarks
  307. {
  308. get
  309. {
  310. if( null == highWaterMarks )
  311. highWaterMarks = new ChangeRecordVectorCollection();
  312. return highWaterMarks;
  313. }
  314. set { highWaterMarks = new ChangeRecordVectorCollection(); }
  315. }
  316. public void Notify()
  317. {
  318. ReplicationResult result = new ReplicationResult();
  319. result.OperatorNodeID = NotifyingNode;
  320. result.Description = null;
  321. result.LastNodeID = null;
  322. result.LastUSN = 0;
  323. result.LastChange = DateTime.Now.Ticks;
  324. result.ReplicationStatus = ReplicationStatus.Notify;
  325. result.Save();
  326. }
  327. }
  328. [XmlRoot( "do_ping", Namespace=UDDI.Replication.Constants.Namespace )]
  329. public class DoPing
  330. {
  331. public string Ping()
  332. {
  333. Debug.VerifySetting( "OperatorKey" );
  334. return Config.GetString( "OperatorKey" );
  335. }
  336. }
  337. [XmlRoot( "get_highWaterMarks", Namespace=UDDI.Replication.Constants.Namespace )]
  338. public class GetHighWaterMarks
  339. {
  340. public HighWaterMarkDetail Get()
  341. {
  342. HighWaterMarkDetail detail = new HighWaterMarkDetail();
  343. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
  344. sp.ProcedureName = "net_highWaterMarks_get";
  345. SqlDataReaderAccessor reader = sp.ExecuteReader();
  346. try
  347. {
  348. while( reader.Read() )
  349. {
  350. detail.HighWaterMarks.Add(
  351. reader.GetString( "operatorKey" ),
  352. reader.GetLong( "USN" ) );
  353. }
  354. }
  355. finally
  356. {
  357. reader.Close();
  358. }
  359. return detail;
  360. }
  361. }
  362. }