How to synchronize a data change message in a disconnected environment


Summary
This topic shows how to synchronize data changes between replicas in a disconnected environment using ArcObjects. A disconnected environment is one in which the parent and child replica geodatabases are not connected by a local area network (LAN) or a wide area network (WAN).


Exporting a data change message from a replica

Complete the following steps to export a data change message:
  1. Connect to a geodatabase to host the replica from which to export the data changes (see the following note). This requires initializing a GeoDataServer object. GeoDataServer objects allow access to a geodatabase on a LAN or WAN through ArcGIS for Server. For more information on initializing a GeoDataServer, see How to initialize a GeoDataServer object.
  2. Call the following procedure by pasting it into an application and passing in the following parameters:
Parameter
Description
sourceGDS
The GeoDataServer initialized in Step 1. This hosts the replica geodatabase that is the source of the data changes.
replicaName
The replicaName parameter takes the name of the replica.
outputDirectory
The outputDirectory parameter specifies the output location for the data changes file. This location should point to a directory on a local drive. If this folder exists, it will be replaced. If it does not exist, it will be created. The delta Extensible Markup Language (XML) file created by this function is written in a compressed Zip file format. This Zip file will be written to the outputDirectory passed to the function.
To export data changes, a replica must be in a Sending Data State.
See the following code example:
[C#]
public void ExportReplicaDataChanges(IGeoDataServer sourceGDS, String replicaName,
    String outputDirectory)
{
    try
    {
        // Set the export options.
        GDSExportOptions gdsExportOptions = new GDSExportOptions();
        gdsExportOptions.ExportFormat = esriGDSExportFormat.esriGDSExportFormatXml;
        gdsExportOptions.Compressed = true;
        gdsExportOptions.BinaryGeometry = false;

        // Export the data changes. Note: The replica must be in a Sending Data State.
        IGDSData gdsData = sourceGDS.ExportReplicaDataChanges(replicaName,
            gdsExportOptions, esriGDSTransportType.esriGDSTransportTypeUrl,
            esriExportGenerationsOption.esriExportGenerationsAll, false);

        // Force deletion of folder and contents if they exist.
        if (Directory.Exists(outputDirectory))
        {
            Directory.Delete(outputDirectory, true);
        }

        // Create the output folder.
        Directory.CreateDirectory(outputDirectory);

        // Get the compressed data changes document from the uniform resource locator
        // (URL) to the local output directory.
        if (gdsData.TransportType == esriGDSTransportType.esriGDSTransportTypeUrl)
        {
            string fileName = System.IO.Path.GetFileName(gdsData.URL);
            string outputFileName = System.IO.Path.Combine(outputDirectory, fileName)
                ;
            WebClient wc = new WebClient();
            wc.DownloadFile(gdsData.URL, outputFileName);
            wc.Dispose();
        }
        else
        {
            // The file has been embedded because there is no output directory set on ArcGIS Server.
            Console.WriteLine("Server is not configured with a virtual directory.");
        }
    }
    catch (COMException comExc)
    {
        throw new Exception(String.Format(
            "Exporting data changes errored: {0}, Error Code: {1}", comExc.Message,
            comExc.ErrorCode), comExc);
    }
    catch (Exception exc)
    {
        throw new Exception(String.Format("Exporting data changes errored: {0}",
            exc.Message), exc);
    }
}
[VB.NET]
Public Sub ExportReplicaDataChanges(ByVal sourceGDS As IGeoDataServer, ByVal replicaName As String, ByVal outputDirectory As String)
    
    Try
    ' Set the export options.
    Dim gdsExportOptions As GDSExportOptions = New GDSExportOptions()
    gdsExportOptions.ExportFormat = esriGDSExportFormat.esriGDSExportFormatXml
    gdsExportOptions.Compressed = True
    gdsExportOptions.BinaryGeometry = False
    
    ' Export the data changes. Note: The replica must be in a Sending Data State.
    Dim gdsData As IGDSData = sourceGDS.ExportReplicaDataChanges(replicaName, gdsExportOptions, esriGDSTransportType.esriGDSTransportTypeUrl, esriExportGenerationsOption.esriExportGenerationsAll, False)
    
    ' Force deletion of folder and contents if they exist.
    If Directory.Exists(outputDirectory) Then
        Directory.Delete(outputDirectory, True)
    End If
    
    ' Create the output folder.
    Directory.CreateDirectory(outputDirectory)
    
    ' Get the compressed data changes document from the uniform resource locator
    ' (URL) to the local output directory.
    If gdsData.TransportType = esriGDSTransportType.esriGDSTransportTypeUrl Then
        Dim fileName As String = System.IO.Path.GetFileName(gdsData.URL)
        Dim outputFileName As String = System.IO.Path.Combine(outputDirectory, fileName)
        Dim wc As WebClient = New WebClient()
        wc.DownloadFile(gdsData.URL, outputFileName)
        wc.Dispose()
    Else
        ' The file has been embedded because there is no output directory set on ArcGIS Server.
        Console.WriteLine("Server is not configured with a virtual directory.")
    End If
    Catch comExc As COMException
    Throw New Exception(String.Format("Exporting data changes errored: {0}, Error Code: {1}", comExc.Message, comExc.ErrorCode), comExc)
    Catch exc As Exception
    Throw New Exception(String.Format("Exporting data changes errored: {0}", exc.Message), exc)
    End Try
    
End Sub

Importing a data change message into the relative replica

Complete the following steps to import a data change message:
  1. Connect to a geodatabase to host the replica that stores the data changes. This requires initializing a GeoDataServer object. GeoDataServer objects allow access to a geodatabase on a LAN or WAN through ArcGIS for Server. 
  2. Call the following procedure by pasting it into an application and passing in the following parameters:
Parameter
Description
targetGDS
The GeoDataServer initialized in Step 1. This hosts the replica geodatabase that stores the data changes.
inputDirectory
The inputDirectory specifies the location of the data changes file. This location should point to a directory that holds the data changes file. The function expects that the data changes document is written in a compressed Zip file format.
The Zip file must have the same name as the delta file contained within it. The function can easily be modified to import an uncompressed file by setting the gdsData.Compressed property to false. The function also assumes that there is only one file in this directory. If there is more than one file in the inputDirectory, only the first file will be read.
See the following code example:
[C#]
public void ImportReplicaDataChanges(IGeoDataServer targetGDS, string inputDirectory)
{
    try
    {
        // Make sure the input directory exists.
        if (!Directory.Exists(inputDirectory))
        {
            throw new DirectoryNotFoundException(String.Format(
                "Input directory could not be found: {0}", inputDirectory));
        }

        // Get the first file from the input directory.
        DirectoryInfo directoryInfo = new DirectoryInfo(inputDirectory);
        FileInfo[] fileInfoArray = directoryInfo.GetFiles();
        if (fileInfoArray.Length == 0)
        {
            throw new FileNotFoundException("No input files could be found.");
        }
        String inputFile = System.IO.Path.Combine(inputDirectory,
            fileInfoArray[0].Name);

        // Read the .xml file into a byte array to pass to the gdsData object.
        FileInfo fileInfo = new FileInfo(inputFile);
        long fileLength = fileInfo.Length;
        byte[] fileBytes = new Byte[fileLength];

        System.IO.FileStream fileStream = File.Open(inputFile, FileMode.Open,
            FileAccess.Read);
        BinaryReader binaryReader = new BinaryReader(fileStream);
        binaryReader.Read(fileBytes, 0, (int)fileLength);
        binaryReader.Close();
        fileStream.Close();

        // Embed the GDSData object.
        IGDSData gdsData = new GDSDataClass();
        gdsData.TransportType = esriGDSTransportType.esriGDSTransportTypeEmbedded;
        gdsData.Compressed = true;
        gdsData.set_EmbeddedData(ref fileBytes);

        // Import the data changes.
        targetGDS.ImportReplicaDataChanges
            (esriGDSReplicaImportSource.esriGDSReplicaImportSourceDeltaXmlFile,
            esriReplicaReconcilePolicyType.esriReplicaDetectConflicts, true, gdsData)
            ;
    }
    catch (COMException comExc)
    {
        throw new Exception(String.Format(
            "Importing data changes errored: {0}, Error Code: {1}", comExc.Message,
            comExc.ErrorCode), comExc);
    }
    catch (Exception exc)
    {
        throw new Exception(String.Format("Importing data changes errored: {0}",
            exc.Message), exc);
    }
}
[VB.NET]
Public Sub ImportReplicaDataChanges(ByVal targetGDS As IGeoDataServer, ByVal inputDirectory As String)
    
    Try
    ' Make sure the input directory exists.
    If (Not Directory.Exists(inputDirectory)) Then
        Throw New DirectoryNotFoundException(String.Format("Input directory could not be found: {0}", inputDirectory))
    End If
    
    ' Get the first file from the input directory.
    Dim directoryInfo As DirectoryInfo = New DirectoryInfo(inputDirectory)
    Dim fileInfoArray As FileInfo() = directoryInfo.GetFiles()
    If fileInfoArray.Length = 0 Then
        Throw New FileNotFoundException("No input files could be found.")
    End If
    Dim inputFile As String = System.IO.Path.Combine(inputDirectory, fileInfoArray(0).Name)
    
    ' Read the .xml file into a byte array to pass to the gdsData object.
    Dim fileInfo As FileInfo = New FileInfo(inputFile)
    Dim fileLength As Long = fileInfo.Length
    Dim fileBytes As Byte() = New Byte(CInt(fileLength - 1)) {}
    Dim fileStream As System.IO.FileStream = File.Open(inputFile, FileMode.Open, FileAccess.Read)
    Dim binaryReader As BinaryReader = New BinaryReader(fileStream)
    binaryReader.Read(fileBytes, 0, CInt(Fix(fileLength)))
    binaryReader.Close()
    fileStream.Close()
    
    ' Embed the GDSData object.
    Dim gdsData As IGDSData = New GDSDataClass()
    gdsData.TransportType = esriGDSTransportType.esriGDSTransportTypeEmbedded
    gdsData.Compressed = True
    gdsData.EmbeddedData = fileBytes
    
    ' Import the data changes.
    targetGDS.ImportReplicaDataChanges(esriGDSReplicaImportSource.esriGDSReplicaImportSourceDeltaXmlFile, esriReplicaReconcilePolicyType.esriReplicaDetectConflicts, True, gdsData)
    Catch comExc As COMException
    Throw New Exception(String.Format("Importing data changes errored: {0}, Error Code: {1}", comExc.Message, comExc.ErrorCode), comExc)
    Catch exc As Exception
    Throw New Exception(String.Format("Importing data changes errored: {0}", exc.Message), exc)
    End Try
    
End Sub






To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS for Desktop Standard ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced ArcGIS for Desktop Advanced
Engine Developer Kit Engine: Geodatabase Update