wiki:FDORfc4

Version 2 (modified by gregboone, 17 years ago) ( diff )

--

FDO RFC 4 - Provider Support for ArcSDE 9.2

This page contains a change request (RFC) for the FDO Open Source project. More FDO RFCs can be found on the RFCs page.

Status

RFC Template Version(1.0)
Submission DateApr 19, 2007
Last ModifiedTimestamp
AuthorGreg Boone
RFC StatusDraft
Implementation Statuspending
Proposed Milestone3.2.2.0
Assigned PSC guide(s)Greg Boone
Voting HistoryTBD
+1
+0
-0
-1

Overview

Various FDO OpenSource community users and clients have requested that the FDO ArcSDE Provider support access to both the ArcSDE 9.1 and 9.2 clients. In its current OpenSource build configuration, the ArcSDE provider is not able to accomplish this requirement. At this time only the ArcSDE 9.1 client support is provided. Therefore the question arises: how can we most effectively provide support for both ArcSDE client platforms without placing additional administrative burdens on our users?

Motivation

It is our assertion that it would be impractical to create two separate ArcSDE providers, one for 9.1 and another for 9.2. We ascertain that such a system would be difficult to maintain by the developers and users of the FDO open source community. We also ascertain that having two providers, either named identically or separately, would be difficult for our clients to install, switch between and generally support in conjunction with their users.

It is the position of this RFC that a solution be implemented that would enable support for both ArcSDE clients without requiring a change to the primary entry point of the ArcSDE provider and it’s associated registration content in the FDO providers.xml file. It is position of this RFC that two new pseudo “provider” libraries, ArcSDEProvider91.dll, ArcSDEProvider92.dll, and a loader dll, ArcSDEProvider.dll, be generated that would replace the current provider dll setup. The loader dll will take the same name as the current FDO Provider: ArcSDEProvider.dll. The ArcSDE loader dll will load and use the ArcSDEProvider92.dll pseudo-provider dll if the client installed ArcSDE 9.2, otherwise it will load and use ArcSDEProvider91.dll.

If a client installs both ArcSDE versions, ArcSDEProvider92.dll will be loaded and used. The ArcSDE 9.1 client will not be used.

Implementation Overview

To implement the above recommendations, a design has been proposed that would result in the modification of the FDO ArcSDE build process so that it creates two separate provider libraries. Each library in turn will link against separate client SDK versions of ArcSDE 9.1 and 9.2.

In conjunction with the above changes, the ArcSDE build process will create a loader dll which will export only one function: extern "C" FDOSDE_API FdoIConnection* CreateConnection(). CreateConnection is the public global method that is required to allow a provider to be found and loaded by the FDO ClientServices API.

Finally, the updated design proposes that a helper class be defined in the loader dll which will load one of the providers based on the installed ArcSDE client.

The ArcSDE 9.1 pseudo-provider dll will link against the ArcSDE client libraries in %FDOTHIRDPARTY%\ESRI\ArcSDEClient91\Windows. If the libraries are not found in that location it will try and find the libraries in %SDEHOME%. If not found in either location, the build will fail.

The ArcSDE 9.2 pseudo-provider dll will link against the ArcSDE client libraries in %FDOTHIRDPARTY%\ESRI\ArcSDEClient92\Windows. If the libraries are not found in that location it will try and find the libraries in %SDEHOME%. If not found in either location, the build will fail.

The ArcSDE unit test project will only search for include and lib files in %SDEHOME%.

In case user has only one version of the ArcSDE client installed, the location must be specified using %SDEHOME%

The Provider 'Loader Library'

Here is example code on how the loader dll logic will operate.

Windows:

typedef FdoIConnection* (*CreateConnectionProc)();

#ifdef _WIN32

#ifdef ARCSDEPROVIDER_EXPORTS
#define FDOSDE_API __declspec(dllexport)
#else
#define FDOSDE_API __declspec(dllimport)
#endif

class ArcSDELoaderLibrary
{
private:
    HMODULE m_hArcSDE;

public:
    ArcSDELoaderLibrary()
    {
        m_hArcSDE = NULL;
        try
        {
            HMODULE hmod = ::LoadLibraryW(L"sde.dll");
            if (hmod != NULL)
            {
                ::FreeLibrary(hmod);
                m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider92.dll");
                // in case load ArcSDEProvider92.dll fails try to load 91
                if (m_hArcSDE == NULL)
                    m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider91.dll");
            }
            else
                m_hArcSDE = ::LoadLibraryW(L"ArcSDEProvider91.dll");
        }
        catch(...){}
    }
    HMODULE GetLibraryHandle()
    {
        return m_hArcSDE;
    }
    ~ArcSDELoaderLibrary()
    {
        try
        {
            if (m_hArcSDE != NULL)
                ::FreeLibrary(m_hArcSDE);
        }
        catch(...){}
    }
};

static ArcSDELoaderLibrary arcSDEloader;
// external access to connection for client services
extern "C" FDOSDE_API FdoIConnection* CreateConnection ()
{
    CreateConnectionProc procCreateConn;
    HMODULE hArc = arcSDEloader.GetLibraryHandle();

    if (hArc != NULL)
    {
        procCreateConn = (CreateConnectionProc)::GetProcAddress (hArc, "CreateConnection");
        if (procCreateConn != NULL)
            return procCreateConn();
    }
    return NULL;
}


Linux:

class ArcSDELoaderLibrary
{
private:
    void* m_hArcSDE;

public:
    ArcSDELoaderLibrary()
    {
        m_hArcSDE = NULL;
        try
        {
            void* hmod = dlopen("libsde.so", RTLD_NOW);
            if (hmod != NULL)
            {
                dlclose(hmod);
                m_hArcSDE = dlopen("libArcSDEProvider92.so", RTLD_NOW);
                // in case load libArcSDEProvider92.so fails try to load 91
                if (m_hArcSDE == NULL)
                    m_hArcSDE = dlopen("libArcSDEProvider91.so", RTLD_NOW);
            }
            else
                m_hArcSDE = dlopen("libArcSDEProvider91.so", RTLD_NOW);
        }
        catch(...){}
    }
    void* GetLibraryHandle()
    {
        return m_hArcSDE;
    }
    ~ArcSDELoaderLibrary()
    {
        try
        {
            if (m_hArcSDE != NULL)
                dlclose(m_hArcSDE);
        }
        catch(...){}
    }
};

static ArcSDELoaderLibrary arcSDEloader;

// external access to connection for client services
extern "C" FDOSDE_API FdoIConnection* CreateConnection ()
{
    CreateConnectionProc procCreateConn;
    void* hArc = arcSDEloader.GetLibraryHandle();

    if (hArc != NULL)
    {
        procCreateConn = (CreateConnectionProc)dlsym (hArc, "CreateConnection");
        if (procCreateConn != NULL)
            return procCreateConn();
    }
    return NULL;
}

Build Script Changes

In order to support the above proposal, the ArcSDE build scripts must be modified.

It is known the open source user can have ArcSDE 9.1 client, ArcSDE 9.2 client or both and the build scripts must handle this.

If a user has both clients we must build both versions of provider, but if he has only one version we must detect at run time which one it is and build the right provider.

The unit test can be based on ArcSDE 9.1 client or ArcSDE 9.2 client so here the user must decide which one to use. In order to handle this, a new environment variable was created to specify the version used by the unit test, named SDEVER_ARCUNITTEST.

Windows side:

If a user has only one version of ArcSDE client he must set the environment variable SDEHOME to target the location of ArcSDE client SDK.

If the user has both versions of ArcSDE clients he must copy/install ArcSDE 9.1 client to:

%FDOTHIRDPARTY%\ESRI\ArcSDEClient91\Windows

…and ArcSDE 9.2 client to

%FDOTHIRDPARTY%\ESRI\ArcSDEClient92\Windows

…to be able to build both versions of provider.

Also he must set the environment variable %SDEHOME% to target the location of ArcSDE client version used in the unit test.

The valid values for SDEVER_ARCUNITTEST will be 91 and 92.

The ArcSDE Provider solution file, ArcSDE.sln, will be modified to include multiple configurations to allow user to build the provider depending of the ArcSDE clients installed. The configurations that will be supported are as follows:

Debug Debug91Only Debug92Only Release Release91Only Release92Only

The following lines will be added to the Windows build scripts to detect the correct build configuration:

SET ARCSDEVERSIONACTIVE=9

:start_exbuild

if not ("%SDEVER_ARCUNITTEST%")==("") goto start_setbuild
if exist "%SDEHOME%\bin\sde.dll" SET SDEVER_ARCUNITTEST=92
if exist "%SDEHOME%\bin\sde91.dll" SET SDEVER_ARCUNITTEST=91

:start_setbuild

if exist "%FDOTHIRDPARTY%\ESRI\ArcSDEClient91\Windows\bin\sde91.dll" SET ARCSDEVERSIONACTIVE=%ARCSDEVERSIONACTIVE%1

if exist "%FDOTHIRDPARTY%\ESRI\ArcSDEClient92\Windows\bin\sde.dll" SET ARCSDEVERSIONACTIVE=%ARCSDEVERSIONACTIVE%2

if "%ARCSDEVERSIONACTIVE%"=="912" SET ARCSDEVERSIONACTIVE=%TYPEBUILDARCSDE%
if "%ARCSDEVERSIONACTIVE%"=="91" SET ARCSDEVERSIONACTIVE=%TYPEBUILDARCSDE%91Only
if "%ARCSDEVERSIONACTIVE%"=="92" SET ARCSDEVERSIONACTIVE=%TYPEBUILDARCSDE%92Only

if "%TYPEACTIONARCSDE%"=="clean" SET MSACTIONARCSDE=Clean
if "%TYPEACTIONARCSDE%"=="install" goto install_files_ArcSDE

echo %MSACTIONARCSDE% %TYPEBUILDARCSDE% ArcSDE provider dlls
SET FDOACTIVEBUILD=%cd%\Src\ArcSDE
cscript //Nologo //job:prepare preparebuilds.wsf
pushd Src

msbuild ArcSDE_temp.sln /t:%MSACTIONARCSDE% /p:Configuration=%ARCSDEVERSIONACTIVE% /p:Platform="Win32" /nologo /consoleloggerparameters:NoSummary


Linux side:

The valid values for SDEVER_ARCUNITTEST will be 91 and empty.

Building different versions of the provider will be done using an environment variable and an optional parameter in the configure script.

If the user has only one version of ArcSDE client he must set the environment variable SDEHOME to target the location of ArcSDE client SDK.

If the user has both versions of ArcSDE clients he must copy/install ArcSDE 9.1 client to

$FDOTHIRDPARTY/ESRI/ArcSDEClient91/Linux

… and ArcSDE 9.2 client to

$FDOTHIRDPARTY/ESRI/ArcSDEClient92/Linux

…to be able to build both versions of provider.

Also, he must set the environment variable $SDEHOME to target the location of the ArcSDE client version used in the unit tests.

Issues

We are still working on finalizing the changes required to the Linux build scripts.

Note: See TracWiki for help on using the wiki.