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.
 
 
 
 
 
 

442 lines
12 KiB

using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using UDDI;
using UDDI.API;
using UDDI.API.Binding;
using UDDI.API.Business;
using UDDI.API.Service;
using UDDI.API.ServiceType;
using UDDI.Diagnostics;
namespace UDDI.Replication
{
[XmlRoot( "changeRecords", Namespace=UDDI.Replication.Constants.Namespace )]
public class ChangeRecordDetail
{
[XmlElement( "changeRecord" )]
public ChangeRecordCollection ChangeRecords = new ChangeRecordCollection();
public ChangeRecordDetail()
{
}
}
[XmlRoot( "highWaterMarks", Namespace=UDDI.Replication.Constants.Namespace )]
public class HighWaterMarkDetail
{
[XmlElement( "highWaterMark" )]
public ChangeRecordVectorCollection HighWaterMarks = new ChangeRecordVectorCollection();
}
[XmlRoot( "get_changeRecords", Namespace=UDDI.Replication.Constants.Namespace )]
public class GetChangeRecords
{
//
// Element: requestingNode
//
[XmlElement( "requestingNode" )]
public string RequestingNode;
//
// Element: changesAlreadySeen
//
private ChangeRecordVectorCollection changesAlreadySeen;
[XmlArray( "changesAlreadySeen" ), XmlArrayItem( "highWaterMark" )]
public ChangeRecordVectorCollection ChangesAlreadySeen
{
get
{
if( null == changesAlreadySeen )
changesAlreadySeen = new ChangeRecordVectorCollection();
return changesAlreadySeen;
}
set { changesAlreadySeen = value; }
}
//
// Element: responseLimitCount
//
private int responseLimitCount = -1;
[XmlElement( "responseLimitCount" ), DefaultValue( -1 )]
public int ResponseLimitCount
{
get { return responseLimitCount; }
set { responseLimitCount = value; }
}
//
// Element: responseLimitVector
//
private ChangeRecordVectorCollection responseLimitVector;
[XmlArray( "responseLimitVector" ), XmlArrayItem( "highWaterMark" )]
public ChangeRecordVectorCollection ResponseLimitVectorSerialize
{
get
{
if( -1 != ResponseLimitCount || Utility.CollectionEmpty( responseLimitVector ) )
return null;
return responseLimitVector;
}
set { responseLimitVector = value; }
}
[XmlIgnore]
public ChangeRecordVectorCollection ResponseLimitVector
{
get
{
if( null == responseLimitVector )
responseLimitVector = new ChangeRecordVectorCollection();
return responseLimitVector;
}
}
/// ****************************************************************
/// public Get
/// ----------------------------------------------------------------
/// <summary>
/// </summary>
/// ****************************************************************
///
public ChangeRecordDetail Get()
{
Debug.VerifySetting( "OperatorKey" );
ChangeRecordDetail detail = new ChangeRecordDetail();
try
{
//
// Get the list of known operators.
//
StringCollection operators = new StringCollection();
SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
sp.ProcedureName = "net_operators_get";
SqlDataReaderAccessor reader = sp.ExecuteReader();
try
{
while( reader.Read() )
{
operators.Add( reader.GetGuidString( "operatorKey" ) );
}
}
finally
{
reader.Close();
}
//
// Set the search criteria for change records.
//
foreach( string operatorKey in operators )
{
long startUSN;
long stopUSN;
startUSN = 0;
foreach( ChangeRecordVector mark in ChangesAlreadySeen )
{
if( 0 == String.Compare( operatorKey, mark.NodeID, true ) )
{
startUSN = mark.OriginatingUSN + 1;
break;
}
}
stopUSN = System.Int64.MaxValue;
foreach( ChangeRecordVector mark in ResponseLimitVector )
{
if( 0 == String.Compare( operatorKey, mark.NodeID, true ) )
{
stopUSN = mark.OriginatingUSN;
break;
}
}
FindChangeRecords.SetRange( operatorKey, startUSN, stopUSN );
}
//
// Retrieve the change records.
//
int limit = Config.GetInt( "Replication.ResponseLimitCountDefault" );
if( ResponseLimitCount >= 0 && ResponseLimitCount <= limit )
limit = ResponseLimitCount;
reader = FindChangeRecords.RetrieveResults( limit );
try
{
while( reader.Read() )
{
XmlSerializer serializer = null;
switch( (ChangeRecordPayloadType)reader.GetShort( "changeTypeID" ) )
{
case ChangeRecordPayloadType.ChangeRecordNull:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordNull ) );
break;
case ChangeRecordPayloadType.ChangeRecordNewData:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordNewData ) );
break;
case ChangeRecordPayloadType.ChangeRecordDelete:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordDelete ) );
break;
case ChangeRecordPayloadType.ChangeRecordPublisherAssertion:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordPublisherAssertion ) );
break;
case ChangeRecordPayloadType.ChangeRecordHide:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordHide ) );
break;
case ChangeRecordPayloadType.ChangeRecordDeleteAssertion:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordDeleteAssertion ) );
break;
case ChangeRecordPayloadType.ChangeRecordAcknowledgement:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordAcknowledgement ) );
break;
case ChangeRecordPayloadType.ChangeRecordCorrection:
serializer = XmlSerializerManager.GetSerializer( typeof( ChangeRecordCorrection ) );
break;
}
StringReader stringReader = new StringReader( reader.GetString( "changeData" ) );
try
{
ChangeRecord changeRecord = new ChangeRecord();
changeRecord.AcknowledgementRequested = ( reader.GetInt( "flag" ) & (int)ChangeRecordFlags.AcknowledgementRequested ) > 0;
changeRecord.ChangeID.NodeID = reader.GetString( "OperatorKey" );
changeRecord.ChangeID.OriginatingUSN = reader.GetLong( "USN" );
ChangeRecordBase changeRecordBase = ( ChangeRecordBase ) serializer.Deserialize( stringReader );
if( changeRecordBase is ChangeRecordCorrection )
{
//
// The query to find change records will do correction 'fixups'. That is, the changeData of this
// change record will be replaced with the changeData from the correction. The problem with this is
// that the original change data will now look like a correction. To distinguish these types of
// change records, we look to see if the OriginatingUSN's match. If the OriginatingUSN's match,
// we want they payload of the change record in this correction. This payload will contain the
// corrected data that we want.
//
ChangeRecordCorrection changeRecordCorrection = ( ChangeRecordCorrection ) changeRecordBase;
if( changeRecordCorrection.ChangeRecord.ChangeID.OriginatingUSN == changeRecord.ChangeID.OriginatingUSN )
{
changeRecordBase = changeRecordCorrection.ChangeRecord.Payload;
}
}
changeRecord.Payload = changeRecordBase;
detail.ChangeRecords.Add( changeRecord );
}
finally
{
stringReader.Close();
}
}
}
finally
{
reader.Close();
}
}
catch( Exception e )
{
Debug.OperatorMessage(
SeverityType.Error,
CategoryType.Replication,
OperatorMessageType.None,
"Could not retrieve change records:\r\n" + e.ToString() );
FindChangeRecords.CleanUp();
throw;
}
return detail;
}
public override string ToString()
{
XmlSerializer serializer = new XmlSerializer( GetType() );
UTF8EncodedStringWriter stringWriter = new UTF8EncodedStringWriter();
try
{
serializer.Serialize( stringWriter, this );
return stringWriter.ToString();
}
finally
{
stringWriter.Close();
}
}
}
public class FindChangeRecords
{
public static int SetRange( string operatorKey, long startUSN, long stopUSN )
{
SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
sp.ProcedureName = "net_find_changeRecords";
sp.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
sp.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
sp.Parameters.Add( "@startUSN", SqlDbType.BigInt );
sp.Parameters.Add( "@stopUSN", SqlDbType.BigInt );
sp.Parameters.Add( "@rows", SqlDbType.Int, ParameterDirection.Output );
sp.Parameters.SetGuid( "@contextID", Context.ContextID );
sp.Parameters.SetGuidFromString( "@operatorKey", operatorKey );
sp.Parameters.SetLong( "@startUSN", startUSN );
sp.Parameters.SetLong( "@stopUSN", stopUSN );
sp.ExecuteNonQuery();
return sp.Parameters.GetInt( "@rows" );
}
public static SqlDataReaderAccessor RetrieveResults( int maxRows )
{
SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
sp.ProcedureName = "net_find_changeRecords_commit";
sp.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
sp.Parameters.Add( "@responseLimitCount", SqlDbType.Int );
sp.Parameters.SetGuid( "@contextID", Context.ContextID );
sp.Parameters.SetInt( "@responseLimitCount", maxRows );
SqlDataReaderAccessor reader = sp.ExecuteReader();
return reader;
}
public static void CleanUp()
{
SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
sp.ProcedureName = "net_find_changeRecords_cleanup";
sp.Parameters.Add( "@contextID", SqlDbType.UniqueIdentifier );
sp.Parameters.SetGuid( "@contextID", Context.ContextID );
sp.ExecuteNonQuery();
}
}
[XmlRoot( "notify_changeRecordsAvailable", Namespace=UDDI.Replication.Constants.Namespace )]
public class NotifyChangeRecordsAvailable
{
//
// Element: notifyingNode
//
[XmlElement( "notifyingNode" )]
public string NotifyingNode;
//
// Element: changesAvailable
//
private ChangeRecordVectorCollection highWaterMarks;
[XmlArray( "changesAvailable" ), XmlArrayItem( "highWaterMark" )]
public ChangeRecordVectorCollection HighWaterMarks
{
get
{
if( null == highWaterMarks )
highWaterMarks = new ChangeRecordVectorCollection();
return highWaterMarks;
}
set { highWaterMarks = new ChangeRecordVectorCollection(); }
}
public void Notify()
{
ReplicationResult result = new ReplicationResult();
result.OperatorNodeID = NotifyingNode;
result.Description = null;
result.LastNodeID = null;
result.LastUSN = 0;
result.LastChange = DateTime.Now.Ticks;
result.ReplicationStatus = ReplicationStatus.Notify;
result.Save();
}
}
[XmlRoot( "do_ping", Namespace=UDDI.Replication.Constants.Namespace )]
public class DoPing
{
public string Ping()
{
Debug.VerifySetting( "OperatorKey" );
return Config.GetString( "OperatorKey" );
}
}
[XmlRoot( "get_highWaterMarks", Namespace=UDDI.Replication.Constants.Namespace )]
public class GetHighWaterMarks
{
public HighWaterMarkDetail Get()
{
HighWaterMarkDetail detail = new HighWaterMarkDetail();
SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
sp.ProcedureName = "net_highWaterMarks_get";
SqlDataReaderAccessor reader = sp.ExecuteReader();
try
{
while( reader.Read() )
{
detail.HighWaterMarks.Add(
reader.GetString( "operatorKey" ),
reader.GetLong( "USN" ) );
}
}
finally
{
reader.Close();
}
return detail;
}
}
}