C++ files
authorAleš Křenek <ljocha@ics.muni.cz>
Fri, 2 Jul 2004 14:51:38 +0000 (14:51 +0000)
committerAleš Křenek <ljocha@ics.muni.cz>
Fri, 2 Jul 2004 14:51:38 +0000 (14:51 +0000)
org.glite.lb.client-interface/Makefile
org.glite.lb.client-interface/interface/CountRef.h [new file with mode: 0644]
org.glite.lb.client-interface/interface/Event.h.T [new file with mode: 0644]
org.glite.lb.client-interface/interface/Job.h [new file with mode: 0644]
org.glite.lb.client-interface/interface/JobStatus.h.T [new file with mode: 0644]
org.glite.lb.client-interface/interface/LoggingExceptions.h [new file with mode: 0644]
org.glite.lb.client-interface/interface/Notification.h [new file with mode: 0644]
org.glite.lb.client-interface/interface/ServerConnection.h [new file with mode: 0644]

index f01f8c5..7f09545 100644 (file)
@@ -18,8 +18,10 @@ VPATH=${top_srcdir}/interface
 AT3=perl -I${top_srcdir}/project ${top_srcdir}/project/at3
 
 STAGETO=include/${globalprefix}/${lbprefix}
-STATIC_H=consumer.h context.h dump.h load.h notification.h notifid.h purge.h
-GEN_H=events.h jobstat.h producer.h
+STATIC_H=consumer.h context.h dump.h load.h notification.h notifid.h purge.h \
+       Notification.h CountRef.h Job.h LoggingExceptions.h ServerConnection.h
+GEN_H=events.h jobstat.h producer.h Event.h JobStatus.h
+
 
 generate: ${GEN_H}
 
@@ -33,7 +35,7 @@ check:
        ${AT3} $< >$@ || rm -f $@
        chmod -w $@ >/dev/null
 
-stage:
+stage: generate
        $(MAKE) install PREFIX=${top_srcdir}/${stagedir}
 
 dist: distsrc distbin
@@ -56,4 +58,4 @@ install:
 
 clean:
        rm -f *.h
-       
\ No newline at end of file
+       
diff --git a/org.glite.lb.client-interface/interface/CountRef.h b/org.glite.lb.client-interface/interface/CountRef.h
new file mode 100644 (file)
index 0000000..a8f61cf
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_COUNTREF_HPP__
+#define __EDG_WORKLOAD_LOGGING_CLIENT_COUNTREF_HPP__
+
+#define EWL_BEGIN_NAMESPACE namespace glite { namespace lb {
+#define EWL_END_NAMESPACE } }
+
+EWL_BEGIN_NAMESPACE;
+
+template<typename T>
+class CountRef {
+public:
+       CountRef(void *);
+//     CountRef(void *,void (*)(void *));
+
+       void use(void);
+       void release(void);
+
+       void    *ptr;
+private:
+       int     count;
+//     void    (*destroy)(void *);
+};
+
+template <typename T>
+CountRef<T>::CountRef(void *p)
+{
+       ptr = p;
+       count = 1;
+}
+
+template <typename T>
+void CountRef<T>::release(void)
+{
+       if (--count == 0) {
+               T::destroyFlesh(ptr);
+               delete this;
+       }
+}
+
+template <typename T>
+void CountRef<T>::use(void)
+{
+       count++;
+}
+
+EWL_END_NAMESPACE;
+
+#endif
diff --git a/org.glite.lb.client-interface/interface/Event.h.T b/org.glite.lb.client-interface/interface/Event.h.T
new file mode 100644 (file)
index 0000000..cfeedf0
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_EVENT_HPP__
+#define __EDG_WORKLOAD_LOGGING_CLIENT_EVENT_HPP__
+
+
+#include <utility>
+#include <vector>
+#include <string>
+
+#include "glite/wms/jobid/JobId.h"
+#include "glite/lb/CountRef.h"
+
+#ident "$Header$"
+
+/** @file Event.h
+ *  @version $Revision$
+ */
+
+/*
+@@@AUTO
+*/
+@@@LANG: C++
+
+#include "edg/workload/logging/client/events.h"
+#include "edg/workload/logging/common/notifid.h"
+
+EWL_BEGIN_NAMESPACE;
+
+class Event {
+       friend class Job;
+       friend class ServerConnection;
+       friend class CountRef<Event>;
+public:
+       /** Event type codes.
+        * Identify which of the event fields are valid.
+        */
+
+       enum Type {
+               UNDEF = 0,
+@@@{
+       for my $e ($event->getTypesOrdered) {
+               my $u = uc $e;
+               my $c = getTypeComment $event $e;
+               gen "\t\t$u,\t/**< $c */\n";
+       }
+@@@}
+               TYPE_MAX
+       };
+
+       /** Event attribute symbolic identifier. */
+       enum Attr {
+@@@{
+       for (sort {$a cmp $b} getAllFields $event) {
+               my $u = $_;
+# $u =~ s/([a-z])([A-Z])/$1_$2/g;
+               $u = uc $u;
+
+               my $c = "\t/**\n";
+               for my $t (sort $event->getFieldOccurence($_)) {
+                       selectType $event $t;
+                       my $cc = getFieldComment $event $_;
+                       $t = 'common' if $t eq '_common_';
+                       $c .= "\t * $t: $cc\n";
+               }
+               $c .= "\t */\n";
+
+               gen "$c\t\t$u,\n";
+       }
+@@@}
+               ATTR_MAX
+       };
+
+@@@{
+       for my $f (getAllFields $event) {
+               for my $t (getFieldOccurence $event $f) {
+                       my $ff;
+                       my $ut;
+                       my $utf;
+                       if ($t eq '_common_') {
+                               $ff = $f;
+                               $ut = '';
+                               $utf = '';
+                       }
+                       else {
+                               selectType $event $t;
+                               selectField $event $f;
+                               $ff = getField $event;
+                               $ut = uc $t . '_';
+                               $utf = ucfirst $t;
+                       }
+                       if ($ff->{codes}) {
+                               gen qq{
+!      enum ${utf}Code \{
+};
+                               for (@{$ff->{codes}}) {
+                                       gen qq{
+!              $ut$_->{name},  /**< $_->{comment} */
+};
+                               }
+                               gen qq{
+!      \};
+};
+                       }
+               }
+       }
+@@@}
+
+       enum AttrType { INT_T, STRING_T, TIMEVAL_T, PORT_T, LOGSRC_T, JOBID_T, NOTIFID_T };
+
+       Type    type;
+
+       Event(void);
+        Event(edg_wll_Event *);
+       Event(const Event &);
+       ~Event(void);
+
+
+       /** Assign new Event to an existing instance. */
+       Event & operator= (const Event &);
+
+       /** String representation of the event type */
+       const std::string & name(void) const;
+
+       /** Retrieve integer attribute */
+       int     getValInt(Attr) const;
+
+       /** Retrieve string attribute */
+       std::string getValString(Attr) const;
+
+        /** Retrieve time attribute */
+        struct timeval getValTime(Attr) const;
+               
+        /** Retrieve jobid attribute */
+        const edg::workload::common::jobid::JobId getValJobId(Attr) const;
+
+       /** Attribute name */
+       const std::string & getAttrName(Attr) const;
+
+       /** List of attributes and types valid for this instance */
+       const std::vector<std::pair<Attr,AttrType> >  & getAttrs(void) const;
+
+private:
+       static void     destroyFlesh(void *);
+       CountRef<Event> *flesh;
+};
+
+EWL_END_NAMESPACE;
+
+#endif
diff --git a/org.glite.lb.client-interface/interface/Job.h b/org.glite.lb.client-interface/interface/Job.h
new file mode 100644 (file)
index 0000000..391822d
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_JOB_HPP__
+#define __EDG_WORKLOAD_LOGGING_CLIENT_JOB_HPP__
+
+#ident "$Header$"
+
+#include "glite/wms/jobid/JobId.h"
+
+#include "glite/lb/Event.h"
+#include "glite/lb/JobStatus.h"
+#include "glite/lb/ServerConnection.h"
+
+
+/**
+ * @file Job.h
+ * @version $Revision$
+ */
+
+EWL_BEGIN_NAMESPACE;
+
+/** L&B job.
+ * Implementation of L&B job-specific calls.
+ * Connection to the server is maintained transparently.
+*/
+  
+class Job {
+public:
+  Job(void);
+  Job(const edg::workload::common::jobid::JobId &);
+  ~Job();
+  
+  /** Assign new JobId to an existing instance.
+   * Connection to server is preserved if possible.
+   */
+  
+  Job & operator= (const edg::workload::common::jobid::JobId &);
+
+/**
+ * Status retrieval bitmasks. Used ORed as Job::status() argument,
+ * determine which status fields are actually retrieved.
+ */
+  static const int STAT_CLASSADS;       /**< various job description fields */
+  static const int STAT_CHILDREN;       /**< list of subjob JobId's */
+  static const int STAT_CHILDSTAT;      /**< apply the flags recursively to subjobs */
+
+  /** Return job status */
+  JobStatus status(int) const;
+  
+  /** Return all events corresponding to this job */
+  void log(std::vector<Event> &) const;
+  const std::vector<Event> log(void) const;
+  
+  /** Return last known address of a listener associated to the job.
+   * \param name name of the listener
+   * \return hostname and port number
+   */
+  const std::pair<std::string,uint16_t> queryListener(const std::string & name) const;
+  
+  /** Manipulate LB parameters, the same as for edg_wll_Context in C */
+  void setParam(edg_wll_ContextParam, int); 
+  void setParam(edg_wll_ContextParam, const std::string); 
+  void setParam(edg_wll_ContextParam, const struct timeval &); 
+
+  int getParamInt(edg_wll_ContextParam) const;
+  std::string getParamString(edg_wll_ContextParam) const;
+  struct timeval getParamTime(edg_wll_ContextParam) const;
+  
+private:
+  ServerConnection     server;
+  edg::workload::common::jobid::JobId                  jobId;
+};
+
+EWL_END_NAMESPACE;
+
+#endif
diff --git a/org.glite.lb.client-interface/interface/JobStatus.h.T b/org.glite.lb.client-interface/interface/JobStatus.h.T
new file mode 100644 (file)
index 0000000..76163a7
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_JOBSTATUS_HPP__
+#define __EDG_WORKLOAD_LOGGING_CLIENT_JOBSTATUS_HPP__
+
+/*
+@@@AUTO
+*/
+
+@@@LANG: C++
+
+#include <sys/time.h>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "glite/wms/jobid/JobId.h"
+
+#include "glite/lb/jobstat.h"
+#include "glite/lb/CountRef.h"
+
+EWL_BEGIN_NAMESPACE;
+
+/**
+ * Description of job status.
+ * The status is computed from a sequence of logged events
+ */
+
+
+class JobStatus {
+       friend class Job;
+       friend class CountRef<JobStatus>;
+public:
+       enum Code {
+               UNDEF = 0,      /**< indicates invalid, i.e. uninitialized instance */
+@@@{
+       for my $stat ($status->getTypesOrdered)
+       {
+               my $u = uc($stat);
+               my $c = getTypeComment $status $stat;
+               gen qq{
+!              $u,     /**< $c */
+};
+       }
+@@@}
+               CODE_MAX
+       };
+
+       enum Attr {
+@@@{
+       selectType $status '_common_';
+       for my $u (sort {$a cmp $b} getAllFields $status) {
+               selectField $status $u;
+               my $f = getField $status;
+               $u =~ s/([a-z])([A-Z])/$1_$2/g;
+               $u = uc $u;
+
+               gen "\t/** $f->{comment} */\n\t\t$u,\n";
+       }
+@@@}
+               ATTR_MAX
+       };
+
+@@@{
+       selectType $status '_common_';
+       for my $n (getAllFields $status) {
+               selectField $status $n;
+               my $f = getField $status;
+               if ($f->{codes}) {
+                        my $n = uc getName $f;
+                       gen qq{
+!      enum \{
+};
+                       for (@{$f->{codes}}) {
+                               gen qq{
+!              $n\_$_->{name}, /**< $_->{comment} */
+};
+                       }
+                       gen qq{
+!      \};
+};
+               }
+       }
+@@@}
+       enum AttrType { INT_T, 
+                       STRING_T, 
+                       TIMEVAL_T, 
+                       BOOL_T,
+                       JOBID_T,
+                       INTLIST_T, 
+                       STRLIST_T, 
+                       TAGLIST_T, 
+                       STSLIST_T 
+       };
+  
+       /** Numeric status code */
+       Code    status;
+  
+       /** String representation of the status code */
+       const std::string & name(void) const;
+  
+       /** Retrieve integer attribute */
+       int     getValInt(Attr) const;
+  
+       /** Retrieve string attribute */
+       std::string getValString(Attr) const;
+  
+       /** Retrieve time attribute */
+       struct timeval  getValTime(Attr) const;
+  
+       /** Retrieve jobid attribute */
+       const edg::workload::common::jobid::JobId  getValJobId(Attr) const;
+
+       /** Retrieve bool attribute */
+       bool getValBool(Attr) const;
+
+       /** Retrieve int list attribute */
+       const std::vector<int> getValIntList(Attr) const;
+
+       /** Retrieve string list attribute */
+       const std::vector<std::string> getValStringList(Attr) const;
+
+       /** Retrieve tag list attribute */
+       const std::vector<std::pair<std::string,std::string> > getValTagList(Attr) const;
+
+       /** Retrieve job status list attribute */
+       const std::vector<JobStatus> getValJobStatusList(Attr) const;
+
+       /** Attribute name */
+       const std::string& getAttrName(Attr) const;
+  
+       /** List of attributes and types valid for this instance */
+       const std::vector<std::pair<Attr,AttrType> >& getAttrs(void) const;
+  
+       JobStatus(void);
+       JobStatus(const JobStatus &);
+       JobStatus & operator=(const JobStatus &);
+       JobStatus(const edg_wll_JobStat &);
+       JobStatus & operator=(const edg_wll_JobStat&);
+       virtual ~JobStatus();
+
+protected:
+       edg_wll_JobStat *c_ptr(void);
+
+private:
+       static void     destroyFlesh(void *);
+       CountRef<JobStatus> *flesh;
+};
+
+EWL_END_NAMESPACE;
+
+#endif
+
diff --git a/org.glite.lb.client-interface/interface/LoggingExceptions.h b/org.glite.lb.client-interface/interface/LoggingExceptions.h
new file mode 100644 (file)
index 0000000..f209acd
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_LOGGING_EXCEPTIONS_HPP__
+#define __EDG_WORKLOAD_LOGGING_CLIENT_LOGGING_EXCEPTIONS_HPP__
+
+#include "glite/wms/common/utilities/Exceptions.h"
+
+#include <pthread.h>
+
+#ident "$Header$"
+
+/** @file LoggingExceptions.h
+ *  @version $Revision$
+ */
+
+EWL_BEGIN_NAMESPACE;
+
+class Exception: public edg::workload::common::utilities::Exception {
+public:
+       
+       /* constructor for mandatory fields */
+       Exception(const std::string& source,
+                 int line_number,
+                 const std::string& method,
+                 int   code,
+                 const std::string& exception) 
+               : edg::workload::common::utilities::Exception(source, 
+                                                             line_number, 
+                                                             method, 
+                                                             code, 
+                                                             "edg::workload::logging::Exception")
+               { error_message = exception; };
+       
+       /* constructor for mandatory fields AND exception chain */
+       Exception(const std::string& source,
+                 int line_number,
+                 const std::string& method,
+                 int   code,
+                 const std::string& exception,
+                 const edg::workload::common::utilities::Exception &exc)
+               : edg::workload::common::utilities::Exception(source, 
+                                                             line_number, 
+                                                             method, 
+                                                             code, 
+                                                             "edg::workload::logging::Exception")
+               { error_message = exception + ": " + exc.what(); };
+};
+
+
+class LoggingException: public Exception {
+public:
+       
+       /* constructor for mandatory fields */
+       LoggingException(const std::string& source,
+                        int line_number,
+                        const std::string& method,
+                        int   code,
+                        const std::string& exception) 
+               : Exception(source, line_number, method, code, exception)
+               {};
+       
+       /* constructor for mandatory fields AND exception chain */
+       LoggingException(const std::string& source,
+                        int line_number,
+                        const std::string& method,
+                        int   code,
+                        const std::string& exception, 
+                        const edg::workload::common::utilities::Exception &exc)
+               : Exception(source, line_number, method, code, exception)
+               {};
+};
+
+
+class OSException: public Exception {
+public:
+       
+       /* constructor for mandatory fields */
+       OSException(const std::string& source,
+                   int line_number,
+                   const std::string& method,
+                   int   code,
+                   const std::string& exception)
+               : Exception(source, 
+                           line_number, 
+                           method, 
+                           code, 
+                           exception + ": " + strerror(code))
+               {};
+       
+       /* constructor for mandatory fields AND exception chain */
+       OSException(const std::string& source,
+                   int line_number,
+                   const std::string& method,
+                   int   code,
+                   const std::string& exception,
+                   const edg::workload::common::utilities::Exception &exc)
+               : Exception(source, 
+                           line_number, 
+                           method, 
+                           code, 
+                           exception + ": " + strerror(code))
+               {};
+};
+
+
+#define EXCEPTION_MANDATORY                           \
+       __FILE__,                                     \
+        __LINE__,                                     \
+        std::string(CLASS_PREFIX) + __FUNCTION__         
+
+#define STACK_ADD                                     
+
+/* note: we can use __LINE__ several times in macro, it is expanded into one row */
+#define throw_exception(context, exception)           \
+{ STACK_ADD;                                          \
+  {                                                   \
+     char *text, *desc;                               \
+     int  code;                                       \
+     std::string exc;                                      \
+                                                      \
+     code = edg_wll_Error((context), &text, &desc);   \
+     exc = exception;                                 \
+     if (text) {                                     \
+       exc += ": ";                                  \
+       exc += text;                                  \
+     }                                               \
+     if (desc) {                                     \
+       exc += ": ";                                  \
+       exc += desc;                                  \
+     }                                               \
+     free(text);                                      \
+     free(desc);                                      \
+     throw LoggingException(EXCEPTION_MANDATORY,      \
+                           code,                     \
+                           exc);                     \
+  }                                                  \
+}
+#define check_result(code, context, desc)             \
+  if((code)) throw_exception((context), desc)
+
+
+
+EWL_END_NAMESPACE;
+
+#endif
diff --git a/org.glite.lb.client-interface/interface/Notification.h b/org.glite.lb.client-interface/interface/Notification.h
new file mode 100644 (file)
index 0000000..6c221e3
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_NOTIFICATION_HPP__
+#define __EDG_WORKLOAD_LOGGING_CLIENT_NOTIFICATION_HPP__
+
+
+#include "glite/wms/jobid/JobId.h"
+
+#include "glite/lb/consumer.h"
+#include "glite/lb/notification.h"
+#include "glite/lb/JobStatus.h"
+
+
+EWL_BEGIN_NAMESPACE; 
+
+
+/** Manage LB notifications.
+ * Simplified API, covers only a subset of C API functinality
+ */
+
+class Notification {
+public:
+       Notification();
+
+       /** Create from NotifId */
+       Notification(const std::string);
+
+       /** Create from server,port pair */
+       Notification(const std::string,const u_int16_t);
+
+       ~Notification();
+
+       std::string getNotifId() const; /**< retrieve NotifId */
+       time_t getValid() const;        /**< until when it is valid */
+       int getFd() const;              /**< local listener filedescriptor */
+
+       /** Add this job to the list.
+        * Local operation only, Register() has to be called
+        * to propagate changes to server 
+        */
+       void addJob(const edg::workload::common::jobid::JobId &); 
+
+       /** Remove job from the list, local op again. */
+       void removeJob(const edg::workload::common::jobid::JobId &);
+
+       /** Get jobs on the list */
+       std::string getJobs();
+
+       /** Receive notifications on these states */
+       void setStates(const std::vector<edg::workload::logging::client::JobStatus::Code> &);
+
+       /** Get states */
+       std::string getStates();
+
+       /** Register (or re-register, i.e. change and extend) 
+        * with the server
+        */
+       void Register();
+
+       /** Receive notification.
+        * Blocks at most the specified timeout (maybe 0 for local polling).
+        * \retval 0 OK
+        * \retval 1 timeout 
+        */
+       int receive(edg::workload::logging::client::JobStatus &,timeval &);
+
+private:
+       std::vector<edg::workload::common::jobid::JobId>        jobs;
+       std::vector<edg::workload::logging::client::JobStatus::Code>    states;
+
+       edg_wll_Context ctx;
+       edg_wll_NotifId notifId;
+       time_t          valid;
+};
+
+
+EWL_END_NAMESPACE;
+
+#endif
diff --git a/org.glite.lb.client-interface/interface/ServerConnection.h b/org.glite.lb.client-interface/interface/ServerConnection.h
new file mode 100644 (file)
index 0000000..faa98f5
--- /dev/null
@@ -0,0 +1,306 @@
+#ifndef __EDG_WORKLOAD_LOGGING_CLIENT_SERVERCONNECTION_HPP__
+#define __EDG_WORKLOAD_LOGGING_CLIENT_SERVERCONNECTION_HPP__
+
+#ident "$Header$"
+
+/**
+ * @file ServerConnection.h
+ * @version $Revision$
+ */
+
+#include <string.h>
+#include <list>
+
+#include "glite/wms/jobid/JobId.h"
+
+#include "glite/lb/Event.h"
+#include "glite/lb/JobStatus.h"
+#include "glite/lb/consumer.h"
+
+EWL_BEGIN_NAMESPACE;
+
+/** Auxiliary class to hold an atomic query condition. */
+class QueryRecord {
+public:
+       friend class ServerConnection;
+       friend edg_wll_QueryRec *convertQueryVector(const std::vector<QueryRecord> &in);
+
+       /* IMPORTANT: must match lbapi.h */
+       enum Attr {
+               UNDEF=0,        /**< Not-defined value, used to terminate lists etc. */
+               JOBID,          /**< Job Id \see _edg_wll_QueryRec */
+               OWNER,          /**< Job owner \see _edg_wll_QueryRec */
+               STATUS,         /**< Current job status */
+               LOCATION,       /**< Where is the job processed */
+               DESTINATION,    /**< Destination CE */
+               DONECODE,       /**< Minor done status (OK,fail,cancel) */
+               USERTAG,        /**< User tag (not implemented yet) */
+               TIME,           /**< Timestamp \see _edg_wll_QueryRec */
+               LEVEL,          /**< Logging level (see "dglog.h") * \see _edg_wll_QueryRec */
+               HOST,           /**< Where the event was generated */
+               SOURCE,         /**< Source component */
+               INSTANCE,       /**< Instance of the source component */
+               EVENT_TYPE,     /**< Event type \see _edg_wll_QueryRec */
+               CHKPT_TAG,      /**< Checkpoint tag */
+               RESUBMITTED,    /**< Job was resubmitted */
+               PARENT,         /**< Job was resubmitted */
+               EXITCODE,       /**< Unix exit code */
+       };
+
+       enum Op {
+               EQUAL=EDG_WLL_QUERY_OP_EQUAL,
+               LESS=EDG_WLL_QUERY_OP_LESS,
+               GREATER=EDG_WLL_QUERY_OP_GREATER,
+               WITHIN=EDG_WLL_QUERY_OP_WITHIN,
+               UNEQUAL=EDG_WLL_QUERY_OP_UNEQUAL
+       };
+  
+       QueryRecord();
+
+       /* copy and assignment */
+       QueryRecord(const QueryRecord &);
+       QueryRecord& operator=(const QueryRecord &);
+
+       /* constructors for simple attribute queries */
+       QueryRecord(const Attr, const Op, const std::string &);
+       QueryRecord(const Attr, const Op, const int);
+       QueryRecord(const Attr, const Op, const struct timeval &);
+       QueryRecord(const Attr, const Op, const edg::workload::common::jobid::JobId&);
+       /* this one is for attr==TIME and particular state */
+       QueryRecord(const Attr, const Op, const int, const struct timeval &);
+       
+       /* constructors for WITHIN operator */
+       QueryRecord(const Attr, const Op, const std::string &, const std::string &);
+       QueryRecord(const Attr, const Op, const int, const int);
+       QueryRecord(const Attr, const Op, const struct timeval &, const struct timeval &);
+       QueryRecord(const Attr, const Op, const int, const struct timeval &, const struct timeval &);
+
+       /* convenience for user tags */
+       QueryRecord(const std::string &, const Op, const std::string &);
+       QueryRecord(const std::string &, const Op, const std::string &, const std::string &);
+       
+       ~QueryRecord();
+  
+       static const std::string AttrName(const Attr) ;
+  
+protected:
+
+       /* conversion to C API type */
+       operator edg_wll_QueryRec() const;
+
+private:
+       Attr    attr;
+       Op      oper;
+       std::string tag_name;
+       int state;
+       std::string string_value;
+       edg::workload::common::jobid::JobId jobid_value;
+        int     int_value;
+        struct timeval timeval_value;
+       std::string string_value2;
+        int     int_value2;
+        struct timeval timeval_value2;
+};
+
+
+/** Supported aggregate operations */
+enum AggOp { AGG_MIN=1, AGG_MAX, AGG_COUNT };
+
+
+/**
+ * Connection to the L&B server.
+ * Maintain connection to the server.
+ * Implement non job-specific API calls
+ */
+
+class ServerConnection {
+public:
+       friend class Job;
+
+       ServerConnection(void);
+
+       /* DEPRECATED: do not use
+        * connections are now handled automagically inside the implementation
+        */
+       ServerConnection(const std::string &);
+
+       /** Open connection to a given server */
+       void open(const std::string &);
+
+       /** Close the current connection */
+       void close(void);
+
+       /* END DEPRECATED */
+
+       /* set & get parameter methods */
+
+       /* consumer parameter settings */
+       void setQueryServer(const std::string&, int);
+       void setQueryTimeout(int);
+
+       void setX509Proxy(const std::string&);
+       void setX509Cert(const std::string&, const std::string&);
+
+       std::pair<std::string, int> getQueryServer() const;
+       int getQueryTimeout() const;
+
+       std::string getX509Proxy() const;
+       std::pair<std::string, std::string> getX509Cert() const;
+
+       /* end of set & get */
+
+       virtual ~ServerConnection();
+
+
+       /* consumer API */
+
+       /** Retrieve the set of single indexed attributes.
+        * outer vector elements correspond to indices
+        * inner vector elements correspond to index columns
+        * if .first of the pair is USERTAG, .second is its name
+        * if .first is TIME, .second is state name
+        * otherwise .second is meaningless (empty string anyway)
+        */
+       std::vector<std::vector<std::pair<QueryRecord::Attr,std::string> > >
+               getIndexedAttrs(void);
+
+       /** Retrieve hard and soft result set size limit */
+       std::pair<int,int> getLimits(void) const;
+
+       /** Set the soft result set size limit */
+       void setQueryJobsLimit(int);
+       void setQueryEventsLimit(int);
+  
+       /** Retrieve all events satisfying the query records
+        * @param job_cond, event_cond - vectors of conditions to be satisfied 
+        *  by jobs as a whole or particular events, conditions are ANDed
+        * @param events vector of returned events
+        */
+       void queryEvents(const std::vector<QueryRecord>& job_cond,
+                        const std::vector<QueryRecord>& event_cond,
+                        std::vector<Event>&) const;
+  
+       const std::vector<Event> queryEvents(const std::vector<QueryRecord>& job_cond,
+                                            const std::vector<QueryRecord>& event_cond) const;
+
+       const std::list<Event> queryEventsList(const std::vector<QueryRecord>& job_cond,
+                                              const std::vector<QueryRecord>& event_cond) const;
+
+
+       /** The same as queryEvents but return only an aggregate.
+        * @param job_cond, event_cond - vectors of conditions to be satisfied 
+        *  by jobs as a whole or particular events, conditions are ANDed
+        * @param op aggregate operator to apply
+        * @param attr attribute to apply the operation to
+        */
+       std::string queryEventsAggregate(const std::vector<QueryRecord>& job_cond,
+                                        const std::vector<QueryRecord>& event_cond,
+                                        enum AggOp const op,
+                                        std::string const attr) const;
+  
+
+       /** Retrieve all events satisfying the query records
+        * @param job_cond, event_cond - vectors of vectors of job or event conditions, 
+        * respectively. The inner vectors are logically ANDed, the outer are ORed
+        * (cond1 AND cond2 AND ...) OR (condN AND ...)
+        * @param events vector of returned events
+        */
+       void queryEvents(const std::vector<std::vector<QueryRecord> >& job_cond,
+                        const std::vector<std::vector<QueryRecord> >& event_cond,
+                        std::vector<Event>&) const;
+  
+       const std::vector<Event> 
+       queryEvents(const std::vector<std::vector<QueryRecord> >& job_cond,
+                   const std::vector<std::vector<QueryRecord> >& event_cond) const;
+
+       
+       /** Retrieve jobs satisfying the query records, including their states
+        * @param query vector of Query records that are anded to form the
+        *      query
+        * @param ids vector of returned job id's
+        * @param states vector of returned job states
+        */
+  
+       void queryJobs(const std::vector<QueryRecord>& query,
+                      std::vector<edg::workload::common::jobid::JobId>& ids) const;
+  
+       const std::vector<edg::workload::common::jobid::JobId>
+       queryJobs(const std::vector<QueryRecord>& query) const;
+  
+       
+       /** Retrieve jobs satisfying the query records, including their states
+        * @param query vector of Query record vectors that are ORed and ANDed to form the
+        *      query
+        * @param ids vector of returned job id's
+        * @param states vector of returned job states
+        */
+   
+       void queryJobs(const std::vector<std::vector<QueryRecord> >& query,
+                      std::vector<edg::workload::common::jobid::JobId>& ids) const;
+  
+       const std::vector<edg::workload::common::jobid::JobId>
+       queryJobs(const std::vector<std::vector<QueryRecord> >& query) const;
+
+       /** Retrieve jobs satisfying the query records, including status
+        * information
+        * @param query vector of Query records that are anded to form the
+        *      query
+        * @param ids vector of returned job id's
+        * @param states vector of returned job states
+        */
+       void queryJobStates(const std::vector<QueryRecord>& query, 
+                           int flags,
+                           std::vector<JobStatus> & states) const;
+       const std::vector<JobStatus>  queryJobStates(const std::vector<QueryRecord>& query, 
+                                                    int flags) const;
+
+       const std::list<JobStatus>  queryJobStatesList(const std::vector<QueryRecord>& query,
+                                                    int flags) const;
+  
+       /** Retrieve jobs satisfying the query records, including status
+        * information
+        * @param query vector of Query records that are anded to form the
+        *      query
+        * @param ids vector of returned job id's
+        * @param states vector of returned job states
+        */
+       void queryJobStates(const std::vector<std::vector<QueryRecord> >& query, 
+                           int flags,
+                           std::vector<JobStatus> & states) const;
+       const std::vector<JobStatus>  
+       queryJobStates(const std::vector<std::vector<QueryRecord> >& query, 
+                      int flags) const;
+  
+       /** States of all user's jobs.
+        * Convenience wrapper around queryJobs.
+        */
+       void userJobStates(std::vector<JobStatus>& stateList) const;
+       const std::vector<JobStatus> userJobStates() const;
+  
+  
+       /** JobId's of all user's jobs.
+        * Convenience wrapper around queryJobs.
+        */
+       void userJobs(std::vector<edg::workload::common::jobid::JobId> &) const;
+       const std::vector<edg::workload::common::jobid::JobId> userJobs() const;
+
+       /** Manipulate LB parameters, the same as for edg_wll_Context in C */
+       void setParam(edg_wll_ContextParam, int); 
+       void setParam(edg_wll_ContextParam, const std::string); 
+       void setParam(edg_wll_ContextParam, const struct timeval &); 
+
+       int getParamInt(edg_wll_ContextParam) const;
+       std::string getParamString(edg_wll_ContextParam) const;
+       struct timeval getParamTime(edg_wll_ContextParam) const;
+  
+protected:
+
+       edg_wll_Context getContext(void) const;
+
+private:
+       edg_wll_Context context;
+};
+
+EWL_END_NAMESPACE;
+
+#endif