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.

962 lines
25 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Data;
  4. using System.Data.SqlClient;
  5. using System.IO;
  6. using System.Text;
  7. using System.Xml;
  8. using System.Xml.Serialization;
  9. using UDDI;
  10. using UDDI.API;
  11. using UDDI.API.Binding;
  12. using UDDI.API.Business;
  13. using UDDI.API.Service;
  14. using UDDI.API.ServiceType;
  15. using UDDI.Diagnostics;
  16. namespace UDDI.Replication
  17. {
  18. public abstract class ChangeRecordBase
  19. {
  20. public abstract UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType { get; }
  21. public abstract void Process( long LSN );
  22. }
  23. [ XmlRoot( "changeRecord", Namespace="urn:uddi-org:repl" ) ]
  24. public class ChangeRecord
  25. {
  26. //
  27. // Attribute: acknowledgementRequested
  28. //
  29. [ XmlAttribute( "acknowledgementRequested" ) ]
  30. public bool AcknowledgementRequested = false;
  31. //
  32. // Element: changeID
  33. //
  34. private ChangeRecordVector changeID;
  35. [ XmlElement( "changeID" ) ]
  36. public ChangeRecordVector ChangeID
  37. {
  38. get
  39. {
  40. if( null == changeID )
  41. changeID = new ChangeRecordVector();
  42. return changeID;
  43. }
  44. set { changeID = value; }
  45. }
  46. //
  47. // Element: changeRecordAcknowledgement |
  48. // changeRecordCorrection |
  49. // changeRecordCustodyTransfer |
  50. // changeRecordDelete |
  51. // changeRecordDeleteAssertion |
  52. // changeRecordHide |
  53. // changeRecordNewData |
  54. // changeRecordNull |
  55. // changeRecordPublisherAssertion |
  56. // changeRecordSetAssertions
  57. //
  58. private ChangeRecordBase payload;
  59. [ XmlElement( "changeRecordAcknowledgement", typeof( ChangeRecordAcknowledgement ) ) ]
  60. [ XmlElement( "changeRecordCorrection", typeof( ChangeRecordCorrection ) ) ]
  61. [ XmlElement( "changeRecordCustodyTransfer", typeof( ChangeRecordCustodyTransfer ) ) ]
  62. [ XmlElement( "changeRecordDelete", typeof( ChangeRecordDelete ) ) ]
  63. [ XmlElement( "changeRecordDeleteAssertion", typeof( ChangeRecordDeleteAssertion ) ) ]
  64. [ XmlElement( "changeRecordHide", typeof( ChangeRecordHide ) ) ]
  65. [ XmlElement( "changeRecordNewData", typeof( ChangeRecordNewData ) ) ]
  66. [ XmlElement( "changeRecordNull", typeof( ChangeRecordNull ) ) ]
  67. [ XmlElement( "changeRecordPublisherAssertion", typeof( ChangeRecordPublisherAssertion ) ) ]
  68. [ XmlElement( "changeRecordSetAssertions", typeof( ChangeRecordSetAssertions ) ) ]
  69. public ChangeRecordBase Payload
  70. {
  71. get { return payload; }
  72. set { payload = value; }
  73. }
  74. public ChangeRecord()
  75. {
  76. ChangeID.NodeID = null;
  77. ChangeID.OriginatingUSN = 0;
  78. Payload = null;
  79. }
  80. public ChangeRecord( ChangeRecordBase payload )
  81. {
  82. ChangeID.NodeID = null;
  83. ChangeID.OriginatingUSN = 0;
  84. Payload = payload;
  85. }
  86. public ChangeRecord( ChangeRecordVector changeID, ChangeRecordBase payload )
  87. {
  88. ChangeID = changeID;
  89. Payload = payload;
  90. }
  91. /// ****************************************************************
  92. /// public Process
  93. /// ----------------------------------------------------------------
  94. /// <summary>
  95. /// </summary>
  96. /// ****************************************************************
  97. ///
  98. public void Process()
  99. {
  100. //
  101. // Add the change record to our change log as a foreign change.
  102. //
  103. long LSN = Log();
  104. //
  105. // Process the change record payload.
  106. //
  107. Payload.Process( LSN );
  108. //
  109. // If an acknowledgement was requested, generate a
  110. // acknowledgement change record.
  111. //
  112. if( AcknowledgementRequested )
  113. {
  114. //
  115. // Save the log entry as our local system account, not the
  116. // current user.
  117. //
  118. string puid = Context.User.ID;
  119. Context.User.ID = null;
  120. ChangeRecord changeRecord = new ChangeRecord();
  121. changeRecord.Payload = new ChangeRecordAcknowledgement( ChangeID );
  122. changeRecord.Log();
  123. Context.User.ID = puid;
  124. }
  125. }
  126. public long Log()
  127. {
  128. string changeData;
  129. //
  130. // Serialize the change data.
  131. //
  132. Type type = Payload.GetType();
  133. //XmlSerializer serializer = new XmlSerializer( type );
  134. XmlSerializer serializer = XmlSerializerManager.GetSerializer( type );
  135. XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
  136. UTF8EncodedStringWriter stringWriter = new UTF8EncodedStringWriter();
  137. try
  138. {
  139. namespaces.Add( "", "urn:uddi-org:repl" );
  140. serializer.Serialize( stringWriter, Payload, namespaces );
  141. changeData = stringWriter.ToString();
  142. }
  143. finally
  144. {
  145. stringWriter.Close();
  146. }
  147. //
  148. // Store the record in the change log.
  149. //
  150. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor( "net_changeRecord_save" );
  151. sp.Parameters.Add( "@USN", SqlDbType.BigInt );
  152. sp.Parameters.Add( "@PUID", SqlDbType.NVarChar, UDDI.Constants.Lengths.UserID );
  153. sp.Parameters.Add( "@delegatePUID", SqlDbType.NVarChar, UDDI.Constants.Lengths.UserID );
  154. sp.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
  155. sp.Parameters.Add( "@entityKey", SqlDbType.UniqueIdentifier );
  156. sp.Parameters.Add( "@entityTypeID", SqlDbType.TinyInt );
  157. sp.Parameters.Add( "@changeTypeID", SqlDbType.TinyInt );
  158. sp.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
  159. sp.Parameters.Add( "@contextTypeID", SqlDbType.TinyInt );
  160. sp.Parameters.Add( "@lastChange", SqlDbType.BigInt );
  161. sp.Parameters.Add( "@changeData", SqlDbType.NText );
  162. sp.Parameters.Add( "@flag", SqlDbType.Int );
  163. sp.Parameters.Add( "@seqNo", SqlDbType.BigInt, ParameterDirection.Output );
  164. if( Utility.StringEmpty( ChangeID.NodeID ) ||
  165. 0 == String.Compare( Config.GetString( "OperatorKey" ), ChangeID.NodeID, true ) )
  166. {
  167. sp.Parameters.SetNull( "@USN" );
  168. sp.Parameters.SetString( "@PUID", Context.User.ID );
  169. sp.Parameters.SetString( "@delegatePUID", Context.User.ImpersonatorID );
  170. sp.Parameters.SetNull( "@operatorKey" );
  171. }
  172. else
  173. {
  174. sp.Parameters.SetLong( "@USN", changeID.OriginatingUSN );
  175. sp.Parameters.SetNull( "@PUID" );
  176. sp.Parameters.SetNull( "@delegatePUID" );
  177. sp.Parameters.SetGuidFromString( "@operatorKey", changeID.NodeID );
  178. }
  179. sp.Parameters.SetGuid( "@contextID", Context.ContextID );
  180. sp.Parameters.SetInt( "@flag", AcknowledgementRequested ? 0x1 : 0x0 );
  181. sp.Parameters.SetLong( "@lastChange", DateTime.UtcNow.Ticks );
  182. sp.Parameters.SetShort( "@contextTypeID", (short)Context.ContextType );
  183. sp.Parameters.SetShort( "@changeTypeID", (short)Payload.ChangeRecordPayloadType );
  184. if( Payload is ChangeRecordNewData )
  185. {
  186. ChangeRecordNewData payload = (ChangeRecordNewData)Payload;
  187. sp.Parameters.SetShort( "@entityTypeID", (short)payload.EntityType );
  188. if( EntityType.TModel == payload.EntityType )
  189. sp.Parameters.SetGuidFromKey( "@entityKey", payload.Entity.EntityKey );
  190. else
  191. sp.Parameters.SetGuidFromString( "@entityKey", payload.Entity.EntityKey );
  192. }
  193. else if( Payload is ChangeRecordDelete )
  194. {
  195. ChangeRecordDelete payload = (ChangeRecordDelete)Payload;
  196. sp.Parameters.SetShort( "@entityTypeID", (short)payload.EntityType );
  197. if( EntityType.TModel == payload.EntityType )
  198. sp.Parameters.SetGuidFromKey( "@entityKey", payload.EntityKey );
  199. else
  200. sp.Parameters.SetGuidFromString( "@entityKey", payload.EntityKey );
  201. }
  202. else if( Payload is ChangeRecordHide )
  203. {
  204. sp.Parameters.SetShort( "@entityTypeID", (short)EntityType.TModel );
  205. sp.Parameters.SetGuidFromKey( "@entityKey", ((ChangeRecordHide)Payload).TModelKey );
  206. }
  207. else
  208. {
  209. sp.Parameters.SetNull( "@entityTypeID" );
  210. sp.Parameters.SetNull( "@entityKey" );
  211. }
  212. sp.Parameters.SetString( "@changeData", changeData );
  213. sp.ExecuteNonQuery();
  214. return sp.Parameters.GetLong( "@seqNo" );
  215. }
  216. public override string ToString()
  217. {
  218. // XmlSerializer serializer = new XmlSerializer( GetType() );
  219. XmlSerializer serializer = XmlSerializerManager.GetSerializer( GetType() );
  220. UTF8EncodedStringWriter stringWriter = new UTF8EncodedStringWriter ();
  221. try
  222. {
  223. serializer.Serialize( stringWriter, this );
  224. return stringWriter.ToString();
  225. }
  226. finally
  227. {
  228. stringWriter.Close();
  229. }
  230. }
  231. }
  232. [ XmlRoot( "changeRecordAcknowledgement", Namespace="urn:uddi-org:repl" ) ]
  233. public class ChangeRecordAcknowledgement : ChangeRecordBase
  234. {
  235. //
  236. // Element: acknowledgedChange
  237. //
  238. [ XmlElement( "acknowledgedChange" ) ]
  239. public ChangeRecordVector AcknowledgedChange;
  240. public ChangeRecordAcknowledgement()
  241. {
  242. }
  243. public ChangeRecordAcknowledgement( ChangeRecordVector acknowledgedChange )
  244. {
  245. this.AcknowledgedChange = acknowledgedChange;
  246. }
  247. public override void Process( long LSN )
  248. {
  249. }
  250. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  251. {
  252. get { return ChangeRecordPayloadType.ChangeRecordAcknowledgement; }
  253. }
  254. }
  255. [ XmlRoot( "changeRecordCorrection", Namespace="urn:uddi-org:repl" ) ]
  256. public class ChangeRecordCorrection : ChangeRecordBase
  257. {
  258. //
  259. // Element: changeRecord
  260. //
  261. [ XmlElement( "changeRecord" ) ]
  262. public ChangeRecord ChangeRecord;
  263. public override void Process( long LSN )
  264. {
  265. //
  266. // Annotate the change record in our database with this
  267. // correction's LSN. The correction's payload will be
  268. // used as the updated data on future get_changeRecords
  269. // requests.
  270. //
  271. SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
  272. sp.ProcedureName = "net_changeRecord_update";
  273. sp.Parameters.Add( "@seqNo", SqlDbType.BigInt );
  274. sp.Parameters.Add( "@USN", SqlDbType.BigInt );
  275. sp.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
  276. sp.Parameters.Add( "@newSeqNo", SqlDbType.BigInt );
  277. sp.Parameters.Add( "@flag", SqlDbType.Int );
  278. if( true == ChangeRecord.ChangeID.NodeID.ToLower().Equals( Config.GetString( "OperatorKey" ).ToLower() ) )
  279. {
  280. //
  281. // We are correcting a local change
  282. //
  283. sp.Parameters.SetLong( "@seqNo", ChangeRecord.ChangeID.OriginatingUSN );
  284. sp.Parameters.SetNull( "@USN" );
  285. }
  286. else
  287. {
  288. //
  289. // We are correcting a foreign change
  290. //
  291. sp.Parameters.SetLong( "@USN", ChangeRecord.ChangeID.OriginatingUSN );
  292. sp.Parameters.SetNull( "@seqNo" );
  293. }
  294. sp.Parameters.SetGuidFromString( "@operatorKey", ChangeRecord.ChangeID.NodeID );
  295. sp.Parameters.SetLong( "@newSeqNo", LSN );
  296. sp.ExecuteNonQuery();
  297. }
  298. [ XmlIgnore ]
  299. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  300. {
  301. get { return ChangeRecordPayloadType.ChangeRecordCorrection; }
  302. }
  303. }
  304. [ XmlRoot( "changeRecordCustodyTransfer", Namespace="urn:uddi-org:repl" ) ]
  305. public class ChangeRecordCustodyTransfer : ChangeRecordBase
  306. {
  307. public override void Process( long LSN )
  308. {
  309. }
  310. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  311. {
  312. get { return ChangeRecordPayloadType.ChangeRecordCustodyTransfer; }
  313. }
  314. }
  315. [ XmlRoot( "changeRecordDelete", Namespace="urn:uddi-org:repl" ) ]
  316. public class ChangeRecordDelete : ChangeRecordBase
  317. {
  318. private string entityKey;
  319. private EntityBase entity;
  320. //
  321. // Element: businessKey
  322. //
  323. [ XmlElement( "businessKey", Namespace=UDDI.API.Constants.Namespace ) ]
  324. public string BusinessKey
  325. {
  326. get
  327. {
  328. if( entity is BusinessEntity )
  329. return entityKey;
  330. return null;
  331. }
  332. set
  333. {
  334. Debug.Verify( Utility.StringEmpty( entityKey ), "UDDI_ERROR_FATALERROR_DELETE_MULTIPLEKEYS" );
  335. entity = new BusinessEntity( value );
  336. entityKey = value;
  337. }
  338. }
  339. //
  340. // Element: serviceKey
  341. //
  342. [ XmlElement( "serviceKey", Namespace=UDDI.API.Constants.Namespace ) ]
  343. public string ServiceKey
  344. {
  345. get
  346. {
  347. if( entity is BusinessService )
  348. return entityKey;
  349. return null;
  350. }
  351. set
  352. {
  353. Debug.Verify( Utility.StringEmpty( entityKey ), "UDDI_ERROR_FATALERROR_DELETE_MULTIPLEKEYS" );
  354. entity = new BusinessService( value );
  355. entityKey = value;
  356. }
  357. }
  358. //
  359. // Element: bindingKey
  360. //
  361. [ XmlElement( "bindingKey", Namespace=UDDI.API.Constants.Namespace ) ]
  362. public string BindingKey
  363. {
  364. get
  365. {
  366. if( entity is BindingTemplate )
  367. return entityKey;
  368. return null;
  369. }
  370. set
  371. {
  372. Debug.Verify( Utility.StringEmpty( entityKey ), "UDDI_ERROR_FATALERROR_DELETE_MULTIPLEKEYS" );
  373. entity = new BindingTemplate( value );
  374. entityKey = value;
  375. }
  376. }
  377. //
  378. // Element: tModelKey
  379. //
  380. [ XmlElement( "tModelKey", Namespace=UDDI.API.Constants.Namespace ) ]
  381. public string TModelKey
  382. {
  383. get
  384. {
  385. if( entity is TModel )
  386. return entityKey;
  387. return null;
  388. }
  389. set
  390. {
  391. Debug.Verify( Utility.StringEmpty( entityKey ), "UDDI_ERROR_FATALERROR_DELETE_MULTIPLEKEYS" );
  392. // TODO: since tModels should normally not be deleted (they
  393. // should be hidden), put a warning in the event log.
  394. entity = new TModel( value );
  395. entityKey = value;
  396. }
  397. }
  398. [ XmlIgnore ]
  399. public UDDI.EntityType EntityType
  400. {
  401. get { return entity.EntityType; }
  402. }
  403. [ XmlIgnore ]
  404. public string EntityKey
  405. {
  406. get { return entityKey; }
  407. }
  408. [ XmlIgnore ]
  409. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  410. {
  411. get { return ChangeRecordPayloadType.ChangeRecordDelete; }
  412. }
  413. public ChangeRecordDelete()
  414. {
  415. }
  416. public ChangeRecordDelete( EntityType entityType, string entityKey )
  417. {
  418. this.entityKey = entityKey;
  419. switch( entityType )
  420. {
  421. case EntityType.BusinessEntity:
  422. this.entity = new BusinessEntity( entityKey );
  423. break;
  424. case EntityType.BusinessService:
  425. this.entity = new BusinessService( entityKey );
  426. break;
  427. case EntityType.BindingTemplate:
  428. this.entity = new BindingTemplate( entityKey );
  429. break;
  430. case EntityType.TModel:
  431. this.entity = new TModel( entityKey );
  432. break;
  433. }
  434. }
  435. public override void Process( long LSN )
  436. {
  437. //
  438. // Process a change record delete by deleting the entity.
  439. //
  440. entity.Delete();
  441. }
  442. }
  443. [ XmlRoot( "changeRecordDeleteAssertion", Namespace="urn:uddi-org:repl" ) ]
  444. public class ChangeRecordDeleteAssertion : ChangeRecordBase
  445. {
  446. [ XmlElement( "publisherAssertion", Namespace=UDDI.API.Constants.Namespace ) ]
  447. public PublisherAssertion Assertion;
  448. [ XmlElement( "fromBusinessCheck" ) ]
  449. public bool FromBusinessCheck;
  450. [ XmlElement( "toBusinessCheck" ) ]
  451. public bool ToBusinessCheck;
  452. public override void Process( long LSN )
  453. {
  454. //
  455. // Process a change record delete assertion by deleting the assertion.
  456. //
  457. if( !FromBusinessCheck && !ToBusinessCheck )
  458. {
  459. Debug.OperatorMessage( SeverityType.Warning,
  460. CategoryType.Replication,
  461. OperatorMessageType.None,
  462. "FromBusinessCheck and ToBusinessCheck cannot both be false in a ChangeRecordDeleteAssertion message" );
  463. }
  464. else
  465. {
  466. CompletionStatusType status;
  467. status = (CompletionStatusType)
  468. ( ( FromBusinessCheck ? 0x02 : 0x00 ) |
  469. ( ToBusinessCheck ? 0x01 : 0x00 ) );
  470. Assertion.Delete( status );
  471. }
  472. }
  473. [ XmlIgnore ]
  474. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  475. {
  476. get { return ChangeRecordPayloadType.ChangeRecordDeleteAssertion; }
  477. }
  478. public ChangeRecordDeleteAssertion()
  479. {
  480. }
  481. public ChangeRecordDeleteAssertion( PublisherAssertion assertion, CompletionStatusType completion )
  482. {
  483. Assertion = assertion;
  484. FromBusinessCheck = ( 0x02 == ( (int)completion & 0x02 ) );
  485. ToBusinessCheck = ( 0x01 == ( (int)completion & 0x01 ) );
  486. }
  487. }
  488. [ XmlRoot( "changeRecordHide", Namespace="urn:uddi-org:repl" ) ]
  489. public class ChangeRecordHide : ChangeRecordBase
  490. {
  491. [ XmlElement( "tModelKey", Namespace=UDDI.API.Constants.Namespace ) ]
  492. public string TModelKey;
  493. public override void Process( long LSN )
  494. {
  495. //
  496. // Process change record hide by deleting the specified tModel.
  497. //
  498. TModel tModel = new TModel( TModelKey );
  499. tModel.Hide();
  500. }
  501. [ XmlIgnore ]
  502. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  503. {
  504. get { return ChangeRecordPayloadType.ChangeRecordHide; }
  505. }
  506. public ChangeRecordHide()
  507. {
  508. }
  509. public ChangeRecordHide( string tModelKey )
  510. {
  511. TModelKey = tModelKey;
  512. }
  513. }
  514. [ XmlRoot( "changeRecordNewData", Namespace="urn:uddi-org:repl" ) ]
  515. [ XmlInclude( typeof( BusinessEntity ) ) ]
  516. [ XmlInclude( typeof( BusinessService ) ) ]
  517. [ XmlInclude( typeof( BindingTemplate ) ) ]
  518. [ XmlInclude( typeof( TModel ) ) ]
  519. public class ChangeRecordNewData : ChangeRecordBase
  520. {
  521. //
  522. // Element: businessEntity |
  523. // businessService |
  524. // bindingTemplate |
  525. // tModel
  526. //
  527. [ XmlElement( "businessEntity", typeof( BusinessEntity ), Namespace=UDDI.API.Constants.Namespace ) ]
  528. [ XmlElement( "businessService", typeof( BusinessService ), Namespace=UDDI.API.Constants.Namespace ) ]
  529. [ XmlElement( "bindingTemplate", typeof( BindingTemplate ), Namespace=UDDI.API.Constants.Namespace ) ]
  530. [ XmlElement( "tModel", typeof( TModel ), Namespace=UDDI.API.Constants.Namespace ) ]
  531. public EntityBase Entity;
  532. public ChangeRecordNewData()
  533. {
  534. }
  535. public ChangeRecordNewData( EntityBase entity )
  536. {
  537. this.Entity = entity;
  538. }
  539. [ XmlIgnore ]
  540. public UDDI.EntityType EntityType
  541. {
  542. get { return Entity.EntityType; }
  543. }
  544. [ XmlIgnore ]
  545. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  546. {
  547. get { return ChangeRecordPayloadType.ChangeRecordNewData; }
  548. }
  549. /// ****************************************************************
  550. /// public Process
  551. /// ----------------------------------------------------------------
  552. /// <summary>
  553. /// </summary>
  554. /// ****************************************************************
  555. ///
  556. public override void Process( long LSN )
  557. {
  558. //
  559. // We process a new data change record by saving the entity to
  560. // the registry.
  561. //
  562. Entity.Save();
  563. }
  564. }
  565. [ XmlRoot( "changeRecordNull", Namespace="urn:uddi-org:repl" ) ]
  566. public class ChangeRecordNull : ChangeRecordBase
  567. {
  568. public override void Process( long LSN )
  569. {
  570. //
  571. // Nothing to do for a null change record.
  572. //
  573. }
  574. [ XmlIgnore ]
  575. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  576. {
  577. get { return ChangeRecordPayloadType.ChangeRecordNull; }
  578. }
  579. }
  580. [ XmlRoot( "changeRecordPublisherAssertion", Namespace="urn:uddi-org:repl" ) ]
  581. public class ChangeRecordPublisherAssertion : ChangeRecordBase
  582. {
  583. [ XmlElement( "publisherAssertion", Namespace=UDDI.API.Constants.Namespace ) ]
  584. public PublisherAssertion Assertion;
  585. [ XmlElement( "fromBusinessCheck" ) ]
  586. public bool FromBusinessCheck;
  587. [ XmlElement( "toBusinessCheck" ) ]
  588. public bool ToBusinessCheck;
  589. public override void Process( long LSN )
  590. {
  591. //
  592. // Process a change record assertion by saving the assertion.
  593. //
  594. if( !FromBusinessCheck && !ToBusinessCheck )
  595. {
  596. Debug.OperatorMessage( SeverityType.Warning,
  597. CategoryType.Replication,
  598. OperatorMessageType.None,
  599. "FromBusinessCheck and ToBusinessCheck cannot both be false in a ChangeRecordPublisherAssertion message" );
  600. }
  601. else
  602. {
  603. CompletionStatusType status;
  604. status = (CompletionStatusType)
  605. ( ( FromBusinessCheck ? 0x02 : 0x00 ) |
  606. ( ToBusinessCheck ? 0x01 : 0x00 ) );
  607. Assertion.Save( status );
  608. }
  609. }
  610. [ XmlIgnore ]
  611. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  612. {
  613. get { return ChangeRecordPayloadType.ChangeRecordPublisherAssertion; }
  614. }
  615. public ChangeRecordPublisherAssertion()
  616. {
  617. }
  618. public ChangeRecordPublisherAssertion( PublisherAssertion assertion, CompletionStatusType status )
  619. {
  620. Assertion = assertion;
  621. FromBusinessCheck = ( 0x02 == ( (int)status & 0x02 ) );
  622. ToBusinessCheck = ( 0x01 == ( (int)status & 0x01 ) );
  623. }
  624. }
  625. [ XmlRoot( "changeRecordSetAssertions", Namespace="urn:uddi-org:repl" ) ]
  626. public class ChangeRecordSetAssertions : ChangeRecordBase
  627. {
  628. [ XmlElement( "changeRecordPublisherAssertion" ) ]
  629. public ChangeRecordPublisherAssertionCollection Assertions;
  630. public override void Process( long LSN )
  631. {
  632. foreach( ChangeRecordPublisherAssertion assertion in Assertions )
  633. assertion.Process( LSN );
  634. }
  635. [ XmlIgnore ]
  636. public override UDDI.API.ChangeRecordPayloadType ChangeRecordPayloadType
  637. {
  638. get { return ChangeRecordPayloadType.ChangeRecordSetAssertions; }
  639. }
  640. }
  641. public class ChangeRecordCollection : CollectionBase
  642. {
  643. public ChangeRecord this[ int index ]
  644. {
  645. get{ return (ChangeRecord)List[ index ]; }
  646. set{ List[ index ] = value; }
  647. }
  648. public int Add( ChangeRecord changeRecord )
  649. {
  650. return List.Add( changeRecord );
  651. }
  652. public int Add()
  653. {
  654. return List.Add( new ChangeRecord() );
  655. }
  656. public void Insert( int index, ChangeRecord changeRecord )
  657. {
  658. List.Insert( index, changeRecord );
  659. }
  660. public int IndexOf( ChangeRecord changeRecord )
  661. {
  662. return List.IndexOf( changeRecord );
  663. }
  664. public bool Contains( ChangeRecord changeRecord )
  665. {
  666. return List.Contains( changeRecord );
  667. }
  668. public void Remove( ChangeRecord changeRecord )
  669. {
  670. List.Remove( changeRecord );
  671. }
  672. public void CopyTo( ChangeRecord[ ] array, int index )
  673. {
  674. InnerList.CopyTo( array, index );
  675. }
  676. }
  677. //
  678. // TODO: Consider renaming this class, the ChangeRecord... convention has become a bit confusing.
  679. // Are things prefixed with "ChangeRecord" change records or is this just a prefix for
  680. // association of these classes into a collective group.
  681. //
  682. // Consider the use of a <ChangeRecord> namespace, maybe turning the semantic into
  683. // ChangeRecord.Correction
  684. // ChangeRecord.NewData
  685. // and maybe event ChangeRecord.Vector, which is a little better than current.
  686. //
  687. // The spec uses the terms HighWaterMark and HightWaterMarkVector
  688. // I think these might be better choices.
  689. //
  690. public class ChangeRecordVector
  691. {
  692. //
  693. // Element: nodeID
  694. //
  695. [ XmlElement( "nodeID" ) ]
  696. public string NodeID;
  697. //
  698. // Element: originatingUSN
  699. //
  700. [ XmlElement( "originatingUSN" ) ]
  701. public long OriginatingUSN;
  702. public ChangeRecordVector()
  703. {
  704. }
  705. public ChangeRecordVector( string nodeID, long originatingUSN )
  706. {
  707. this.NodeID = nodeID;
  708. this.OriginatingUSN = originatingUSN;
  709. }
  710. }
  711. public class ChangeRecordVectorCollection : CollectionBase
  712. {
  713. public ChangeRecordVector this[ int index ]
  714. {
  715. get{ return (ChangeRecordVector)List[ index ]; }
  716. set{ List[ index ] = value; }
  717. }
  718. public int Add()
  719. {
  720. return List.Add( new ChangeRecordVector() );
  721. }
  722. public int Add( ChangeRecordVector vector )
  723. {
  724. return List.Add( vector );
  725. }
  726. public int Add( string nodeID, long originatingUSN )
  727. {
  728. return List.Add( new ChangeRecordVector( nodeID, originatingUSN ) );
  729. }
  730. public void Insert( int index, ChangeRecordVector vector )
  731. {
  732. List.Insert( index, vector );
  733. }
  734. public int IndexOf( ChangeRecordVector vector )
  735. {
  736. return List.IndexOf( vector );
  737. }
  738. public bool Contains( ChangeRecordVector vector )
  739. {
  740. return List.Contains( vector );
  741. }
  742. public void Remove( ChangeRecordVector vector )
  743. {
  744. List.Remove( vector );
  745. }
  746. public void CopyTo( ChangeRecordVector[ ] array, int index )
  747. {
  748. InnerList.CopyTo( array, index );
  749. }
  750. public bool IsProcessed( ChangeRecordVector changeID )
  751. {
  752. //
  753. // TODO: Consider. If you find Node id and OriginatingUSNs are not equal return false
  754. // avoiding checking the rest of the list
  755. //
  756. foreach( ChangeRecordVector vector in this )
  757. {
  758. if( 0 == String.Compare( changeID.NodeID, vector.NodeID, true ) &&
  759. changeID.OriginatingUSN <= vector.OriginatingUSN )
  760. return true;
  761. }
  762. return false;
  763. }
  764. public void MarkAsProcessed( ChangeRecordVector changeID )
  765. {
  766. foreach( ChangeRecordVector vector in this )
  767. {
  768. if( 0 == String.Compare( changeID.NodeID, vector.NodeID, true ) )
  769. {
  770. vector.OriginatingUSN = changeID.OriginatingUSN;
  771. return;
  772. }
  773. }
  774. this.Add( changeID );
  775. }
  776. }
  777. public class ChangeRecordPublisherAssertionCollection : CollectionBase
  778. {
  779. public ChangeRecordPublisherAssertion this[ int index ]
  780. {
  781. get{ return (ChangeRecordPublisherAssertion)List[ index ]; }
  782. set{ List[ index ] = value; }
  783. }
  784. public int Add()
  785. {
  786. return List.Add( new ChangeRecordPublisherAssertion() );
  787. }
  788. public int Add( ChangeRecordPublisherAssertion changeRecord )
  789. {
  790. return List.Add( changeRecord );
  791. }
  792. public void Insert( int index, ChangeRecordPublisherAssertion changeRecord )
  793. {
  794. List.Insert( index, changeRecord );
  795. }
  796. public int IndexOf( ChangeRecordPublisherAssertion changeRecord )
  797. {
  798. return List.IndexOf( changeRecord );
  799. }
  800. public bool Contains( ChangeRecordPublisherAssertion changeRecord )
  801. {
  802. return List.Contains( changeRecord );
  803. }
  804. public void Remove( ChangeRecordPublisherAssertion changeRecord )
  805. {
  806. List.Remove( changeRecord );
  807. }
  808. public void CopyTo( ChangeRecordPublisherAssertion[ ] array, int index )
  809. {
  810. InnerList.CopyTo( array, index );
  811. }
  812. }
  813. }