+++ /dev/null
-#include "glite/lb/context.h"
-#include "glite/lb/xml_conversions.h"
-#include "glite/lb/consumer.h"
-
#include <string.h>
#include <expat.h>
-#include "client_headers.h"
-
+#include "glite/lb/context.h"
#include "glite/lb/xml_conversions.h"
+#include "glite/lb/consumer.h"
extern void print_jobs(edg_wll_JobStat *);
int main(int argc,char **argv)
{
-#include "example1_code.c"
-
+ edg_wll_Context ctx;
+ edg_wll_JobStat *statesOut = NULL;
+ edg_wll_QueryRec jc[2];
+
+ edg_wll_InitContext(&ctx);
+
+ jc[0].attr = EDG_WLL_QUERY_ATTR_JOBID;
+ jc[0].op = EDG_WLL_QUERY_OP_EQUAL;
+ if ( edg_wlc_JobIdParse(
+ "https://lhun.ics.muni.cz:9000/OirOgeWh_F9sfMZjnIPYhQ",
+ &jc[0].value.j) )
+ {
+ edg_wll_FreeContext(ctx);
+ exit(1);
+ }
+ jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF;
+ if (edg_wll_QueryJobs(ctx, jc, 0, NULL, &statesOut)) {
+ char *err_text,*err_desc;
+
+ edg_wll_Error(ctx,&err_text,&err_desc);
+ fprintf(stderr,"QueryJobs: %s (%s)\n",err_text,err_desc);
+ free(err_text);
+ free(err_desc);
+ }
+ else {
+ print_jobs(statesOut); /* process the returned data */
+ edg_wll_FreeStatus(statesOut);
+ free(statesOut);
+ }
+ edg_wlc_JobIdFree(jc[0].value.j);
+ edg_wll_FreeContext(ctx);
return 0;
}
+++ /dev/null
-edg_wll_Context ctx;
-edg_wll_JobStat *statesOut = NULL;
-edg_wll_QueryRec jc[2];
-
-edg_wll_InitContext(&ctx);
-
-jc[0].attr = EDG_WLL_QUERY_ATTR_JOBID;
-jc[0].op = EDG_WLL_QUERY_OP_EQUAL;
-if ( edg_wlc_JobIdParse(
- "https://lhun.ics.muni.cz:9000/OirOgeWh_F9sfMZjnIPYhQ",
- &jc[0].value.j) )
-{
- edg_wll_FreeContext(ctx);
- exit(1);
-}
-jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF;
-if (edg_wll_QueryJobs(ctx, jc, 0, NULL, &statesOut)) {
- char *err_text,*err_desc;
-
- edg_wll_Error(ctx,&err_text,&err_desc);
- fprintf(stderr,"QueryJobs: %s (%s)\n",err_text,err_desc);
- free(err_text);
- free(err_desc);
-}
-else {
- print_jobs(statesOut); /* process the returned data */
- edg_wll_FreeStatus(statesOut);
- free(statesOut);
-}
-edg_wlc_JobIdFree(jc[0].value.j);
-edg_wll_FreeContext(ctx);
#include <string.h>
#include <errno.h>
-#include "glite/jobid/cjobid.h"
+/*headers*/
+#include "glite/jobid/cjobid.h"
#include "glite/lb/events.h"
-#include "glite/lb/producer.h"
+#include "glite/lb/producer.h"
+/*end headers*/
+
static struct option opts[] = {
{"help", 0, NULL, 'h'},
if ( (errno = edg_wlc_JobIdParse(jobid_s, &jobid)) ) { perror(jobid_s); return 1; }
+ /*context*/
edg_wll_InitContext(&ctx);
-
+
edg_wll_SetParam(ctx, EDG_WLL_PARAM_SOURCE, EDG_WLL_SOURCE_USER_INTERFACE);
edg_wll_SetParam(ctx, EDG_WLL_PARAM_HOST, server);
edg_wll_SetParam(ctx, EDG_WLL_PARAM_PORT, port);
+ /*end context*/
+ /*sequence*/
if (edg_wll_SetLoggingJob(ctx, jobid, seq_code, EDG_WLL_SEQ_NORMAL)) {
char *et,*ed;
edg_wll_Error(ctx,&et,&ed);
fprintf(stderr,"SetLoggingJob(%s,%s): %s (%s)\n",jobid_s,seq_code,et,ed);
exit(1);
}
+ /*end sequence*/
- err = edg_wll_LogEvent(ctx,
+ /*log*/
+ err = edg_wll_LogEvent(ctx, //* \label{l:logevent}
EDG_WLL_EVENT_USERTAG,
EDG_WLL_FORMAT_USERTAG,
name, value);
-
if (err) {
char *et,*ed;
argv[0],et,ed);
free(et); free(ed);
}
+ /*end log*/
seq_code = edg_wll_GetSequenceCode(ctx);
puts(seq_code);
functions are separated in its own SW module called
\verb'org.glite.lb.common' and are described in section~\ref{s:common}
+\marginpar{Example code}%
+Source code for examples shown in this guide is distributed together
+with the document. The examples contain excerpts from the actual files
+with reference to the file name and line numbers. All the examples can
+be compiled using attached Makefile.
+
\marginpar{Recommended reading}%
Before you start reading this guide, it is recommended to accomodate
yourself with the \LB architecture described in the first part of the
Unless specified otherwise, zero return value means success, non-zero
failure. Standard error codes from \verb'errno.h' are used as
much as possible. In a few cases the error can not be intuitively
-mapped and \LB specific error value greater than
+mapped into standard code and \LB specific error value greater than
\verb'EDG_WLL_ERROR_BASE' is returned.
Few API function return \verb'char *'. In such a~case
\subsection{Context and Parameter Settings}
\label{s:context}
-The \LB library does not maintain internal state (apart of network connections, see \ref{s:pool}), all the API
+The \LB library does not maintain internal state (apart of network
+connections, see \ref{s:pool}), all the API
functions refer to a~\emph{context} argument instead.
Context object preserves state information among the various API
calls, the state including \LB library parameters (\eg security
described in respective API sections, the common parameters are:
\begin{table}[h]
-\begin{tabularx}{\textwidth}{llX}
-{\bf C name} & {\bf Env. variable} & {\bf Description} \\
+\begin{tabularx}{\textwidth}{lX}
+{\bf C name} & {\bf Description} \\
\hline
-\lstinline'EDG_WLL_PARAM_X509_KEY' & \lstinline'X509_USER_KEY' & Key file to use for
-authentication. \\
-\lstinline'EDG_WLL_PARAM_X509_CERT' & \lstinline'X509_USER_CERT' & Certificate file to use
-for authentication. \\
-\lstinline'EDG_WLL_PARAM_CONNPOOL_SIZE' & & Maximum number
-of open connections maintained by the library. \\
+\lstinline'EDG_WLL_PARAM_X509_KEY' &
+Key file to use for authentication.
+\par {\it Type: } \lstinline'char *'
+\par {\it Env. variable: } \lstinline'X509_USER_KEY'
+\\
+\lstinline'EDG_WLL_PARAM_X509_CERT' &
+Certificate file to use for authentication.
+\par {\it Type: } \lstinline'char *'
+\par {\it Env. variable: } \lstinline'X509_USER_CERT'
+\\
+\lstinline'EDG_WLL_PARAM_CONNPOOL_SIZE' &
+Maximum number of open connections maintained by the library.
+\par {\it Type: } \lstinline'int'
+\\
\end{tabularx}
+\caption{Common context parameters}
+\label{t:cparam}
\end{table}
The third argument is parameter value, which can be of type
the JobId is opaque \verb'glite_jobid_t'. The JobId is in fact
just URL with \verb'https' protocol, path component being unique string
with no further structure and host and port designating the \LB server
-holding the job information. The JobId can be
+holding the job information. The JobId can be:
\begin{itemize}
\item created new for given \LB server (the unique part will be
generated by the \LB library):
read from file):
\begin{lstlisting}[firstnumber=3]
if(ret = glite_jobid_parse("https://some.host:9000/OirOgeWh_F9sfMZjnIPYhQ", &jobid)) {
+ fprintf(stderr, "error parsing jobid: %s\n", strerror(ret));
+}
\end{lstlisting}
\item or obtained as part of \LB server query result.
\end{itemize}
\marginpar{\textbf{\LB 1.x}}%
{\it In the older \LB versions (1.x) the
structure was named \verb'edg_wlc_JobId' and the functions had prefix
-\verb'edg_wlc_JobId'. Exact description can be found in the
-header file \verb'glite/wmsutils/cjobid.h'}
+\verb'edg_wlc_JobId', \eg\verb'edg_wlc_JobIdFree()'. Exact description
+can be found in the header file \verb'glite/wmsutils/cjobid.h'}
\subsubsection{Event}
\begin{document}
\reversemarginpar
\lstset{language=C,basicstyle=\footnotesize,numbers=none,breaklines=true}
+\lstset{title=\lstname}
+\lstset{rangeprefix=/*,rangesuffix=*/,includerangemarker=false}
+\lstset{escapeinside={//*}{\^^M}}
% ----- BEGIN COPY -----
% copied from org.glite.lb.client/doc/api/api.tex in hope it could be useful
% -*- mode: latex -*-
\section{\LB\ Querying (Consumer) API}
-\TODO{Complete review; create really functional (buildable) examples and use verbatiminput of relevant part of the code; add list of header files, important functions and data types and their description, etc.}
-
-\def\partitle#1{\par{\textbf{#1}}\par}
\label{ConsOview}
-This section describes the aspects of principal use of the \LB\ consumer API.
-It begins with the simplest examples how to query the bookkeeping
-service, continues with various selection criteria and their combinations, and
-through queries on user tags and timestamps it concludes with the discussion of
-application specific queries.
-
-The document is intended for users interested in the \LB\
-consumer API or those interested in better understanding of the \LB\ service
-capabilities.
-
-In the presented examples only the C \LB\ API (Sect.~\ref{query-C}) is considered.
-The C++ API (Sect.~\ref{query-CPP}) covers the same functionality.
-
-\subsection{Header files}
-Job.h
-JobStatus.h.T
-Notification.h
-ServerConnection.h
-connection.h
-consumer.h
-notification.h
-prod\_proto.h
-producer.h.T
-statistics.h
+\subsection{Query Language}
-\verbatiminput{client_headers.h}
+\subsection{C Language Binding}
-\subsection{Returned results}
-
-\LB\ server returns errors which are classified as hard and soft errors.
-The main difference between these categories is that in the case of soft
-errors results may still be returned.
-The authorization errors belong to
-``soft error'' sort. Hard errors are typically all unrecoverable errors like ENOMEM.
+\subsubsection{Call Semantics}
When the item count returned by \LB\ server exceeds the defined limits, the E2BIG error occur.
There are two limits\,---\,the server and the user limit. The user defined limit may be set in
the context at the client side in the following way:
-\begin{verbatim}
- #include <glite/lb/context.h>
- ...
- edg_wll_Context ctx;
-
- edg_wll_InitContext(&ctx);
- edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_JOBS_LIMIT, 10);
- edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_EVENTS_LIMIT, 20);
- edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_RESULTS, 30);
- ...
- edg_wll_FreeContext(ctx);
-\end{verbatim}
-This code sets the user query limits to the given maximal count of items.
-The E2BIG error may fall into both categories depending on the setting of
-another context parameter, EDG\_WLL\_PARAM\_QUERY\_RESULTS.
-It may take the following values:
+\subsubsection{Header Files}
+\begin{table}[h]
+\begin{tabularx}{\textwidth}{>{\tt}lX}
+glite/lb/consumer.h & Prototypes for all query functions. \\
+\end{tabularx}
+\end{table}
-%The E2BIG error can be classified as hard or soft error too because this error can be affected
-%by one more parameter which can make this error hard or soft. This parameter can be set like this:\\
-%\texttt{edg\_wll\_SetParam(ctx, EDG\_WLL\_PARAM\_QUERY\_RESULTS, EDG\_WLL\_QUERYRES\_ALL);}
-%and possible values follows:
+\subsubsection{Context Parameters}
\begin{itemize}
\item{EDG\_WLL\_QUERYRES\_NONE}\,---\,No results are returned.
In this case an E2BIG error acts like a hard error.
\end{itemize}
Default value is EDG\_WLL\_QUERYRES\_NONE.
-\TODO{zkratit, doplnit zpracovani struktury (print jobs)}
+\subsubsection{Return Values}
+\LB\ server returns errors which are classified as hard and soft errors.
+The main difference between these categories is that in the case of soft
+errors results may still be returned.
+The authorization errors belong to
+``soft error'' sort. Hard errors are typically all unrecoverable errors like ENOMEM.
-\subsection{Job queries}
+The E2BIG error may fall into both categories depending on the setting of
+another context parameter, EDG\_WLL\_PARAM\_QUERY\_RESULTS.
+It may take the following values:
-\partitle{Job status}
-\label{JS}
-\TODO{Add edg\_wll\_JobStat description and error codes handling}
+\subsubsection{Job Queries}
The simplest case corresponds to the situation when an exact job ID
is known and the only information requested is the job status. The job ID
about a job with the ID\\
\texttt{https://lhun.ics.muni.cz:9000/OirOgeWh\_F9sfMZjnIPYhQ}.
-\lstinputlisting{example1_code.c}
-
-%\verbatiminput{example1_code.c}
-
-%\begin{verbatim}
-% #include <glite/lb/consumer.h>
-% ...
-% edg_wll_Context ctx;
-% edg_wll_JobStat *statesOut = NULL;
-% edg_wll_QueryRec jc[2];
-% ...
-% edg_wll_InitContext(&ctx);
-% ...
-% jc[0].attr = EDG_WLL_QUERY_ATTR_JOBID;
-% jc[0].op = EDG_WLL_QUERY_OP_EQUAL;
-% if ( edg_wlc_JobIdParse(
-% "https://lhun.ics.muni.cz:9000/OirOgeWh_F9sfMZjnIPYhQ",
-% &jc[0].value.j) )
-% {
-% edg_wll_FreeContext(ctx);
-% exit(1);
-% }
-% jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF;
-% if (edg_wll_QueryJobs(ctx, jc, 0, NULL, &statesOut)) {
-% char *err_text,*err_desc;
-%
-% edg_wll_Error(ctx,&err_text,&err_desc);
-% fprintf(stderr,"QueryJobs: %s (%s)\n",err_text,err_desc);
-% free(err_text);
-% free(err_desc);
-% }
-% else {
-% ... /* process the returned data */
-% edg_wll_FreeStatus(statesOut);
-% free(statesOut);
-% }
-% edg_wlc_JobIdFree(jc[0].value.j);
-% edg_wll_FreeContext(ctx);
-%\end{verbatim}
-
The first function call in this example initializes the \LB\ context\,---\,variable
\texttt{ctx}\,---\,which is necessary for later use. The most important part
of this code fragment is the \texttt{jc} variable setting.
\emph{For the sake of simplicity such code is not included in the examples
in the rest of this document.}
-\partitle{All user's jobs}
+%\partitle{All user's jobs}
\label{JQ-auj}
\TODO{Update the example so that it is really working}
The following examples demonstrates how \texttt{edg\_wll\_QueryJobs()} combines
the given conditions in a logical conjugation.
-\partitle{Running jobs}
+%\partitle{Running jobs}
\label{JQ-rj}
If all (user's) running jobs are to be retrieved the following code can
\texttt{edg\_wll\_QueryJobs()} connects them in the logical conjunction.
Examples using logical conjunction and logical disjunction are shown in the Sect.~\ref{JQ-AO}.
-\partitle{Jobs running at a given CE}
+%\partitle{Jobs running at a given CE}
The following example gives description of all (user's) jobs running at CE XYZ.
\begin{verbatim}
#include <glite/lb/consumer.h>
saves a CE name the job will be routed to. If location is needed use the \texttt{EDG\_WLL\_QUERY\_ATTR\_LOCATION} attribute.
-\partitle{The WITHIN operator}
+%\partitle{The WITHIN operator}
The \texttt{EDG\_WLL\_QUERY\_OP\_WITHIN} operator can be used in any condition with numeric values.
The following example shows a query on all user's jobs that have returned
an exit code from 2 to 7.
interval\,---\,the lower bound of the interval is stored in the \texttt{value} union and the
upper bound is stored in the \texttt{value2} union.
-\partitle{Using AND, OR in query clauses}
+%\partitle{Using AND, OR in query clauses}
\label{JQ-AO}
In many cases the basic logic using only conjunctions is not sufficient.
For example, if you need all your jobs running at the destination XXX or at
\texttt{(user=NULL) and (state=Running) and (dest='XXX' or dest='YYY')}.
\end{quote}
-\partitle{User tags}
+%\partitle{User tags}
\label{JQ_ut}
\TODO{Is it really working?}
User tags can be used for marking (labelling) jobs. A user tag is
%That means that user tags are composed of two variable components
%and user tag indices depend on tag names.
-\partitle{Time attributes}
+%\partitle{Time attributes}
%A time interval in which a particular state appears is attached to every job
%state.
\TODO{pro prehlednost bych mozna pridal seznam vsech atributu
na ktere se lze ptat}
-\subsection{Event queries and application specific queries}
+\subsubsection{Event queries and application specific queries}
\label{ASQ}
Event queries and job queries are similar.
Obviously, the return type is different\Dash the \LB\ raw events.
are considered in the following paragraph.
-\partitle{All jobs marked as red}
+%\partitle{All jobs marked as red}
\label{ASQ_allred}
This example shows how to select all user's jobs which were (at some time)
marked with the value red of user tag color.
which considers the ``current color'' only). The same applies on all
subsequent examples using the user's marking.
-\partitle{All red jobs at some time marked as green}
+%\partitle{All red jobs at some time marked as green}
The next example shows how to select all jobs which are just now marked with
user tag color red, but at some time in the past they were marked as green.
\begin{verbatim}
\ref{JQ_RedJobs}). Event conditions selects all jobs which were sometimes marked
as green\,---\,this is described in previous example \ref{ASQ_allred}.
-\partitle{All resubmitted jobs}
+%\partitle{All resubmitted jobs}
The next example shows how to get all (your) resubmitted jobs.
\begin{verbatim}
#include <glite/lb/consumer.h>
...
\end{verbatim}
-\partitle{Jobs resubmitted in the last two hours}
+%\partitle{Jobs resubmitted in the last two hours}
The next example shows how to get all user's jobs which were resubmitted in the last
2 hours.
\begin{verbatim}
\end{verbatim}
-\partitle{Complex query}
+%\partitle{Complex query}
The last example illustrates the API usage on
a~meaningful but rather complex query ``which of my red jobs are heading
to a~destination that already encountered problems executing red jobs''.
The synchronous variants of logging functions can in addition return
\verb'EDG_WLL_ERROR_NOJOBID' or \verb'EDG_WLL_ERROR_DB_DUP_KEY'.
-\subsubsection{Logging events}
-\TODO{odkaz na soubor}
-In this section we will give an example how to log an UserTag event to
+\subsubsection{Logging event example}
+In this section we will give commented example how to log an UserTag event to
the \LB.
First we have to include neccessary headers:
-\lstinputlisting[firstline=8,lastline=10]{prod_example1.c}
+\lstinputlisting[numbers=left,linerange=headers-end\ headers]{prod_example1.c}
Initialize context and set parameters:
-\lstinputlisting[firstline=61,lastline=84]{prod_example1.c}
+\lstinputlisting[numbers=left,linerange=context-end\ context]{prod_example1.c}
\TODO{proper setting of sequence codes}
-\lstinputlisting[firstline=86,lastline=91]{prod_example1.c}
+\lstinputlisting[numbers=left,linerange=sequence-end\ sequence]{prod_example1.c}
Log the event:
-\lstinputlisting[firstline=93,lastline=107]{prod_example1.c}
+\lstinputlisting[numbers=left,linerange=log-end\ log]{prod_example1.c}
The \verb'edg_wll_LogEvent()' function is defined as follows:
\begin{lstlisting}[numbers=none]
only two arguments, tag name and value, but other events require more
arguments.
-Instead of using the generic \verb'edg_wll_LogEvent()', we could also
+Instead of using the generic \verb'edg_wll_LogEvent()' at line~\ref{l:logevent}, we could also
write:
-\begin{lstlisting}[firstnumber=92]
+\begin{lstlisting}
err = edg_wll_LogUserTag(ctx, name, value);
\end{lstlisting}