As initialising the Essbase API is discussed in another post I won't show it here however it is needed.
Here are the steps to login to essbase and get the accessible list of databases of the logged-in user:
Prerequisites
1. Add a few constants
public class NativeConstants
{
public const int
ESS_DBNAMELEN_CHARACTER = 30;
public const int
ESS_BYTES_PER_CHARACTER = 4;
public const int
ESS_BYTES_FOR_TRAILING_NULL = 5;
public const int
ESS_APPNAMELEN = ((30 * NativeConstants.ESS_BYTES_PER_CHARACTER)
+ NativeConstants.ESS_BYTES_FOR_TRAILING_NULL);
public const int
ESS_DBNAMELEN = ((NativeConstants.ESS_DBNAMELEN_CHARACTER
* NativeConstants.ESS_BYTES_PER_CHARACTER)+ NativeConstants.ESS_BYTES_FOR_TRAILING_NULL);
}
2. Create the ESS_APPDB_T structure. This is needed to get the accessible list of database in case of a successful login.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class ESS_APPDB_T
{
/// <summary>
/// Application name
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeConstants.ESS_APPNAMELEN)]
public string AppName;
/// <summary>
/// Database name
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeConstants.ESS_DBNAMELEN)]
public string DbName;
}
3. Add more functions to the EssbaseTypes class
public class EssbaseTypes
{
[DllImport("essapinu.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static internal extern uint EssInit(ref ESS_INIT_T EssInitStruct, ref
uint EssHInst);
[DllImport("essapinu.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static internal extern uint EssTerm(uint
EssHInst);
[DllImport("essapinu.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static internal extern uint EssLogin(uint
EssHInst, string EssSvrName, string EssUserName, string
EssPassword, ref ushort
EssDBCount, ref IntPtr
EssDBList, ref uint
EssHCtx);
[DllImport("essapinu.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static internal extern uint EssLogout(uint
EssHCtx);
[DllImport("essapinu.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static internal extern uint EssFree(uint
EssHInst, IntPtr EssMemBlock);
}
Code
1. Initialise the Essbase API and get the instance handle. How to initialise the Essbase C API
2. Call the login function
Here are a few functions that can be used:
EssLogin - login with db list
EssAutoLogin - login with EssSetActive added to it
EssLoginEx - login with sso_token. Really useful when the token is passed from another Hyperion product as it eliminates the need to ask for credentials.
We'll use EssLogin as it is a bit more interesting.
info needed:
- user and password: "admin"/"password" is my favourite as most production env are using it.
- Essbase server: Can be either server:port or the url of the essbase cluster. If only the server name is used then the default port is used.
info returned:
- essDBCount: the number or accessible database
- essDBList: a pointer to array of ESS_APPDB_T structures
- essHCtx: context handle. Should be kept because it will be needed in almost all api calls.
// Connection details
string essServer = "server";
string username = "admin";
string password = "password";
// Out values of EssLogin method
ushort essDBCount = 0;
IntPtr essDBList = new IntPtr();
uint essHCtx = 0;
// essHCtx is to be user in subsequent essbase api calls
uint errNum2 = EssbaseTypes.EssLogin(essHInst, essServer, username, password, ref essDBCount, ref essDBList, ref essHCtx);
3. Get the list of accessible databases
What we get back from EssLogin is the number of databases and the a pointer to a list of databases
if
(essDBCount > 0)
{
// Get the
database list
ESS_APPDB_T[]
appdbs = new ESS_APPDB_T[essDBCount];
for (int i = 0; i < essDBCount; i++)
{
appdbs[i] = (ESS_APPDB_T)Marshal.PtrToStructure(new
IntPtr((essDBList.ToInt32() + i * Marshal.SizeOf(typeof(ESS_APPDB_T)))), typeof(ESS_APPDB_T));
}
}
4. Free memory
// Free memory allocated to the app/db list
uint errNum3 = EssbaseTypes.EssFree(essHInst, essDBList);
// Log out
uint errNum4 = EssbaseTypes.EssLogout(essHCtx);
6. Terminate the API
// Terminate
uint errNum5 = EssbaseTypes.EssTerm(essHInst);
The C# code above is only an example on how to use the Essbase C API. Building a proper C# wrapper requires a bit more work, especially around UTF8 compatibility.
One very important aspect of using the essbase api is freeing memory. Memory leaks can sneak in and slowly kill you application.
To get the Essbase C API working the API version in the ESS_INIT_T should be set to something like 0x00070000 otherwise it will create problems later on. I do not know exactly why this is happening but some people have been know to spend days figuring this thing out.
No comments:
Post a Comment