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 Date | Apr 19, 2007 |
Last Modified | Timestamp |
Author | Greg Boone |
RFC Status | Accepted |
Implementation Status | pending |
Proposed Milestone | 3.2.2.0 |
Assigned PSC guide(s) | Greg Boone |
Voting History | TBD |
+1 | Greg Boone, Robert Bray, Frank Warmerdam, Mateusz Loskot, Jason Birch |
+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?
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:
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:
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.
Test Plan
The ArcSDE Provider unit tests will be run against development/runtime configurations where ArcSDE 9.1 or 9.2 or both are installed.
The ArcSDE Provider will be re-tested in AutoCAD Map 2008 and MapGuide OpenSource 1.2.
Impact of Not Implementing this ECO
If this RFC is not implemented, FDO clients will not be able to exercise the ArcSDE provider against the ArcSDE 9.2 client.
Funding/Resources
Autodesk to provide resources / funding to update the ArcSDE provider.