Differences

This shows you the differences between two versions of the page.

Link to this comparison view

muster:8.0:c [2018/01/11 08:21] (current)
Line 1: Line 1:
 +======= Muster C++ API Usage =======
 +
 +===== Introduction =====
 +The C<​nowiki>​++</​nowiki>​ Muster API is mostly declared inside the MClientLib namespace. The API declares two global structures (MUSTER and MUSTERCLIENT) that are required to hold any connection versus the Dispatcher (MUSTER) and a Render client (MUSTERCLIENT).
 +
 +The first step required to use the API is including the headers:
 +
 +<code cpp>
 +#include <​muster.h>​
 +#include <​MClientLib/​MClientLib.h>​
 +#include <​MClientLib/​MErrors.h>​
 +</​code>​
 +
 +  * **muster.h** : This header files at the root level of the SDK includes directory declares some common constants required across the entire Muster codebase.
 +  * **MClientLib/​MClientLib.h** : This header declares the classes and functions available within the API
 +  * **MClientLib/​MErrors.h** : This header declares common classes used as return values for the API functions
 +
 +Before using any function of the API, you must initialize it using:
 +
 +<code cpp>
 +MClientLib::​MUSTERERR err = MClientLib::​InitializeLibrary(argv[0]);​
 +</​code>​
 +
 +The InitializeLibrary() function setup some internal stuff as well as getting the path of the module you're going to execute. It's mostly required by the templates and Python function to find the path to the Muster Python distribution. Alternatively , you can invoke it with MClientLib::​InitializeLibrary(0) and it will guess the module path. The path to Muster runtimes can be also specified by declaring the MUSTER environmental variable before launching your executable.
 +The InitializeLibrary function call returns a MClientLib::​MUSTERERR object that's used across the API to return function execution results. You should always check the MUSTERERR object using the getErrorCode() class method against the MERR_ERR_OK constant:
 +
 +<code cpp>
 +if (err.getErrorCode() != MERR_ERR_OK) {
 + fprintf(stderr,"​Failure on  MClientLib::​InitializeLibrary()\n"​);​
 + return -1;
 +}
 +</​code>​
 +
 +Each call to the InitializeLibrary() function must be paired with a MClientLib::​ShutdownLibrary() before shutting down your module. This is required to free internal memory allocations and it's mandatory!
 +
 +After a successful initialisation of the library, you can attempt to establish a connection versus a Dispatcher service or a Render client service. This can be done using the InitializeSession() or InitializeClientSession() functions, that should be followed by a call to the Connect() function:
 +
 +<code cpp>
 +MClientLib::​MUSTER* session = MClientLib::​InitializeSession();​
 +printf("​\nConnecting to %s...",​server);​
 +err = MClientLib::​Connect(session,​server,​nPort);​
 +if (err.getErrorCode() != MERR_ERR_OK) {
 + fprintf(stderr,"​\nUnable to connect to %s:​%d.\n",​server,​nPort);​
 + MClientLib::​ShutdownSession(session);​
 + MClientLib::​ShutdownLibrary();​
 + return -1;
 +}
 +</​code>​
 +
 +As you can see from the code, a session must always be deallocated by ShutdownSession() or ShutdownClientSession()
 +
 +The next step after a successful connection to the Dispatcher service requires the authentication on the Dispatcher:
 +
 +<code cpp>
 +err = MClientLib::​Authenticate(session,​username,​password);​
 +if (err.getErrorCode() != MERR_ERR_OK) {
 + fprintf(stderr,"​Authentication failed...\n"​);​
 + MClientLib::​Disconnect(session);​
 + MClientLib::​ShutdownSession(session);​
 + MClientLib::​ShutdownLibrary();​
 + return -1;
 +}
 +
 +MClientLib::​MUSTERAUTH authenticationStatus = MClientLib::​GetAuthenticationStatus(session);​
 +switch (authenticationStatus.status) {
 + case MClientLib::​kLoginAdmin:​
 + printf("​Login successfully.\n"​);​
 + break;
 + case MClientLib::​kLoginGuest:​
 + printf("​Logged as guest.\n"​);​
 + break;
 + case MClientLib::​kLoginDeniedLDAPDown:​
 + printf("​Login denied. Directory server is down !");
 + MClientLib::​Disconnect(session);​
 + MClientLib::​ShutdownSession(session);​
 + MClientLib::​ShutdownLibrary();​
 + return -1;
 + break;
 + case MClientLib::​kLoginDenied:​
 + printf("​Login denied.\n"​);​
 + MClientLib::​Disconnect(session);​
 + MClientLib::​ShutdownSession(session);​
 + MClientLib::​ShutdownLibrary();​
 + return -1;
 + break;
 + }
 +
 +if (authenticationStatus.ldapByPassed) {
 + printf("​Directory authentication bypassed. Login from regular Muster users database!\n\n"​);​
 +}
 +</​code>​
 +
 +Once authenticated , you can perform any operation on the Dispatcher nodes and jobs queue using the functions provided by the API.
 +
 +The rest of the following code shows how to retrieve the server status and print it:
 +
 +<code cpp>
 + printf("​Requesting status...\n"​);​
 + err = MClientLib::​AcquireServerStatus(session);​
 + if (err.getErrorCode() == MERR_ERR_OK) {
 + MClientLib::​MUSTERSERVER serverStatus = MClientLib::​GetServerStatus(session);​
 + if (serverStatus.networkProtocolVersion != kNetworkProtocolVersion) {
 + fprintf(stderr,"​\n###​ Protocol version Mismatch. Expecting %d, received %d!\n\n",​kNetworkProtocolVersion,​serverStatus.networkProtocolVersion);​
 + }
 + }
 +
 + MClientLib::​Disconnect(session);​
 + MClientLib::​ShutdownSession(session);​
 + MClientLib::​ShutdownLibrary();​
 +}
 +
 +</​code>​
 +
 +If you need to perform an operation on a specific job, you can call one of the jobs functions like:
 +
 +<code cpp>
 +// Pause the job ID 12
 +err =  MClientLib::​JobActionPause (session, 12);
 +if (err.getErrorCode() != MERR_ERR_OK) {
 + fprintf(stderr,"​Failed to pause job: %s",​err.getDescription().c_str());​
 +}
 +</​code>​
 +
 +You can find a complete set of usage examples inside the mrtool source code available inside the SDK.
 +====== Compiling on Windows ======
 +
 +The compilation on Windows is suggested on Microsoft Visual Studio 2010, that's the platform used to build Muster itself. Even it's supported on any compiler, flags and procedures may change according to your build platform.
 +
 +Start Visual Studio creating a new solution or project:
 +
 +{{ :​muster:​8.0:​visual_studio_new_project.jpg?​nolink |}}
 +
 +Be sure to remove the precompiled headers feature not supported by the Muster API headers:
 +
 +{{ :​muster:​8.0:​visual_studio_new_project_features.jpg?​nolink |}}
 +
 +Configure the path to the includes directory to find the API includes:
 +
 +{{ :​muster:​8.0:​visual_studio_includes.jpg?​nolink |}}
 +
 +Configure the path to the Linker libraries to find the API .libs files:
 +
 +{{ :​muster:​8.0:​visual_studio_linker_general.jpg?​nolink |}}
 +
 +Configure the additional required libs for the linker:
 +
 +{{ :​muster:​8.0:​visual_studio_linker_deps.jpg?​nolink |}}
 +
 +Remember to copy the Muster runtimes .DLL into your application folder (MClientLib.dll , MTemplate.dll,​ MBase.dll, MTemplate.dll and MFramework.dll) or alternatively add the Muster installation path to your PATH environmental variable.
 +
 +====== Compiling on Linux ======
 +
 +Compiling a Muster API source code module on Linux requires you to point g++ on the SDK includes as well as the local Muster installation shared libraries.
 +
 +For example, assuming you've wrote a mymustercmd.cpp file and your Muster installation is available on /​usr/​local/​muster8 , and your sdk installation at /​usr/​local/​muster8/​sdk,​ you compile your file with:
 +
 +<​code>​
 +g++ -I/​usr/​local/​muster8/​sdk/​includes -L/​usr/​local/​muster8 -lMClientLib -lMBase -lMTemplate -lMFramework mymustercmd.cpp -o ./​mymustercmd
 +</​code>​
 +
 +The MClientLib, MBase and MTemplate are the minimal shared libraries required to compile a Muster API module.
 +Be sure also that the module is always able to find the Muster shared libraries, alternatively,​ you can set your libraries search path and the MUSTER installation path before invoking it:
 +
 +<​code>​
 +LD_LIBRARY_PATH=/​usr/​local/​muster8:​$LD_LIBRARY_PATH
 +MUSTER=/​usr/​local/​muster8
 +export LD_LIBRARY_PATH
 +export MUSTER
 +./​mymustercmd
 +</​code>​
 +====== Compiling on MAC OS X ======
 +
 +Compiling a Muster API source code module on MAC OS X requires you to point g++ on the SDK includes as well as the local Muster installation shared libraries.
 +
 +For example, assuming you've wrote a mymustercmd.cpp file and your Muster installation is available on /​Applications/​Muster8 , and your sdk installation at /​Applications/​Muster8/​sdk,​ you compile your file with:
 +
 +<​code>​
 +g++ -I/​Applications/​Muster8/​Contents/​sdk/​includes -L/​Applications/​Muster8/​Contents/​muster8 -lMClientLib -lMBase -lMTemplate -lMFramework mymustercmd.cpp -o ./​mymustercmd
 +</​code>​
 +
 +The MClientLib, MBase and MTemplate are the minimal shared libraries required to compile a Muster API module.
 +Be sure also that the module is always able to find the Muster shared libraries, alternatively,​ you can set your libraries search path and the MUSTER installation path before invoking it:
 +
 +<​code>​
 +MUSTER=/​Applications/​Muster8/​Contents
 +DYLD_LIBRARY_PATH=/​Applications/​Muster8/​Contents/​Frameworks:​$DYLD_LIBRARY_PATH
 +export MUSTER
 +export DYLD_LIBRARY_PATH
 +./​mymustercmd
 +</​code>​
 +