import of statistics counting
authorAleš Křenek <ljocha@ics.muni.cz>
Mon, 26 Sep 2005 09:43:18 +0000 (09:43 +0000)
committerAleš Křenek <ljocha@ics.muni.cz>
Mon, 26 Sep 2005 09:43:18 +0000 (09:43 +0000)
org.glite.lb.server/src/jobstat.c
org.glite.lb.server/src/lb_proto.c
org.glite.lb.server/src/lb_xml_parse.c.T

index a1f27ae..8920d42 100644 (file)
@@ -20,6 +20,7 @@
 #include "index.h"
 #include "jobstat.h"
 #include "lb_authz.h"
+#include "stats.h"
 
 
 #define DAG_ENABLE     1
@@ -628,24 +629,36 @@ edg_wll_ErrorCode edg_wll_StepIntState(edg_wll_Context ctx,
        int             be_strict = 0;
        char            *errstring = NULL;
        intJobStat      jobstat;
+       edg_wll_JobStat oldstat;
 
+       memset(&oldstat,0,sizeof oldstat);
        if (seq != 0) {
                intErr = edg_wll_LoadIntState(ctx, job, seq - 1, &ijsp);
        }
        if (seq != 0 && !intErr) {
+               edg_wll_CpyStatus(&ijsp->pub,&oldstat);
                res = processEvent(ijsp, e, seq, be_strict, &errstring);
                if (res == RET_FATAL || res == RET_INTERNAL) { /* !strict */
+                       edg_wll_FreeStatus(&oldstat);
                        return edg_wll_SetError(ctx, EINVAL, errstring);
                }
                edg_wll_StoreIntState(ctx, ijsp, seq);
+               edg_wll_UpdateStatistics(ctx,&oldstat,e,&ijsp->pub);
                if (stat_out) {
                        memcpy(stat_out,&ijsp->pub,sizeof *stat_out);
                        destroy_intJobStat_extension(ijsp);
                }
                else destroy_intJobStat(ijsp);
                free(ijsp);
-       } else {
-               edg_wll_intJobStatus(ctx, job, flags,&jobstat, js_enable_store);
+               edg_wll_FreeStatus(&oldstat);
+       }
+       else if (!edg_wll_intJobStatus(ctx, job, flags,&jobstat, js_enable_store)) 
+       {
+               /* FIXME: we miss state change in the case of seq != 0 
+                * Does anybody care? */
+
+               edg_wll_UpdateStatistics(ctx,NULL,e,&jobstat.pub);
+
                if (stat_out) {
                        memcpy(stat_out,&jobstat.pub,sizeof *stat_out);
                        destroy_intJobStat_extension(&jobstat);
index c6fb6d9..7dba657 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "lb_proto.h"
 #include "lb_html.h"
+#include "stats.h"
 #include "get_events.h"
 #include "purge.h"
 #include "lb_xml_parse.h"
@@ -35,6 +36,7 @@
 #define KEY_INDEXED_ATTRS      "/indexedAttrs "
 #define KEY_NOTIF_REQUEST      "/notifRequest "
 #define KEY_QUERY_SEQUENCE_CODE        "/querySequenceCode "
+#define KEY_STATS_REQUEST      "/statsRequest "
 #define KEY_HTTP               "HTTP/1.1"
 
 
@@ -821,6 +823,63 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
                        if ( seqCode ) free(seqCode);
                        edg_wlc_JobIdFree(jobId);
                }
+               else if (!strncmp(requestPTR,KEY_STATS_REQUEST,sizeof(KEY_STATS_REQUEST)-1)) {
+                       char *function;
+                       edg_wll_QueryRec **conditions;
+                       edg_wll_JobStatCode major = EDG_WLL_JOB_UNDEF;
+                       time_t from, to;
+                       int i, j, minor, res_from, res_to;
+                       float rate = 0, duration = 0;
+                       
+                       
+                       
+                       if (parseStatsRequest(ctx, messageBody, &function, &conditions, 
+                                               &major, &minor, &from, &to))
+                               ret = HTTP_BADREQ;
+                       else {
+                               int     fatal = 0, err = 0;
+                               
+                               // XXX presne poradi parametru zatim neni znamo
+                               // navratove chyby nejsou zname, nutno predelat dle aktualni situace
+                               if (!strcmp(function,"Rate")) 
+                                       err = edg_wll_StateRateServer(ctx,
+                                               conditions[0], major, minor, 
+                                               &from, &to, &rate, &res_from, &res_to); 
+                               else if (!strcmp(function,"Duration"))
+                                       err = edg_wll_StateDurationServer(ctx,
+                                               conditions[0], major, minor, 
+                                               &from, &to, &duration, &res_from, &res_to); 
+                               
+                               switch (err) {
+                                       case 0: if (html) ret = HTTP_NOTIMPL;
+                                               else      ret = HTTP_OK; 
+                                               break;
+                                       case ENOSYS: ret = HTTP_NOTIMPL; break;
+                                       case EEXIST: ret = HTTP_OK; break;
+                                       case EINVAL: ret = HTTP_INVALID; break;
+                                       case ENOENT: ret = HTTP_NOTFOUND; break;
+                                       case EPERM : ret = HTTP_UNAUTH; break;
+                                       case EDG_WLL_ERROR_NOINDEX: ret = HTTP_UNAUTH; break;
+                                       case ENOMEM: fatal = 1; ret = HTTP_INTERNAL; break;
+                                       default: ret = HTTP_INTERNAL; break;
+                               }
+                               /* glue errors (if eny) to XML responce */ 
+                               if (!html && !fatal)
+                                       if (edg_wll_StatsResultToXML(ctx, from, to, rate, 
+                                                       duration, res_from, res_to, &message))
+                                               ret = HTTP_INTERNAL;
+                       }
+                       
+                       free(function);
+                       if (conditions) {
+                               for (j = 0; conditions[j]; j++) {
+                                       for (i = 0; (conditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ )
+                                               edg_wll_QueryRecFree(&conditions[j][i]);
+                                       free(conditions[j]);
+                               }
+                               free(conditions);
+                       }
+               }
 
                        
         /* POST [something else]: not understood */
index 6a13b2b..cea530e 100644 (file)
 #define QUERY_SEQUENCE_CODE_RESULT_BEGIN       "<edg_wll_QuerySequenceCodeResult"
 #define QUERY_SEQUENCE_CODE_RESULT_END         "</edg_wll_QuerySequenceCodeResult>\r\n"
 
-
+#define STATS_RESULT_BEGIN     "<edg_wll_StatsResult"
+#define STATS_RESULT_END       "</edg_wll_StatsResult>\r\n"
+  
+  
 // XXX will be redundant soon
 #define USERJOBS_BEGIN         "<edg_wll_UserJobs"
 #define USERJOBS_END           "</edg_wll_UserJobs>\r\n"
@@ -399,6 +402,37 @@ static void startQuerySequenceCodeRequest(void *data, const char *el, const char
        XMLCtx->level++;
 }
 
+
+
+static void startStatsRequest(void *data, const char *el, const char **attr)
+{
+       edg_wll_XML_ctx *XMLCtx = data;
+
+       
+       strcpy(XMLCtx->element, el);
+
+       switch (XMLCtx->level) {
+               case 0: if (!strcasecmp(el,"edg_wll_StatsRequest") && attr[0] && attr[1]) {
+                               if (strcmp(attr[0],"function")) { unexp() break;}
+                               else XMLCtx->statsFunction = strdup(attr[1]);
+                       }
+                       else unexp()
+                       break;
+               case 1: if (!strcasecmp(el,"and")) {
+                               XMLCtx->jobQueryRec_begin = XML_GetCurrentByteIndex(XMLCtx->p);
+                       }
+                       else if ( (strcasecmp(el,"major")) && (strcasecmp(el,"minor")) && 
+                               (strcasecmp(el,"from")) && (strcasecmp(el,"to")) ) unexp()
+                       break;
+               case 2: /* fall through */
+               case 3: /* do not check xml tags, processed in startJobQueryRec */
+               case 4: break;
+               default: unexp() 
+                        break;
+       }
+       XMLCtx->level++;
+}
+
 #undef unexp
 
 
@@ -830,6 +864,40 @@ static void endQuerySequenceCodeRequest(void *data, const char *el UNUSED_VAR)
 
 
 
+static void endStatsRequest(void *data, const char *el UNUSED_VAR)
+{
+        edg_wll_XML_ctx *XMLCtx = data;
+
+        if (XMLCtx->level == 2) {
+                if (!strcmp(XMLCtx->element,"major")) {
+                       XMLCtx->statsMajor = 
+                               edg_wll_from_string_to_edg_wll_JobStatCode(XMLCtx);
+               }
+               else if (!strcmp(XMLCtx->element,"minor")) {
+                       XMLCtx->statsMinor = edg_wll_from_string_to_int(XMLCtx);
+               }
+               else if (!strcmp(XMLCtx->element,"from")) {
+                       XMLCtx->statsFrom = edg_wll_from_string_to_time_t(XMLCtx);;
+               }
+               else if (!strcmp(XMLCtx->element,"to")) {
+                       XMLCtx->statsTo = edg_wll_from_string_to_time_t(XMLCtx);;
+               }
+               else if (!strcmp(el,"and")) {
+                       long len = (XML_GetCurrentByteIndex(XMLCtx->p) + XML_GetCurrentByteCount(XMLCtx->p))
+                                       -  XMLCtx->jobQueryRec_begin;
+       
+                       parseJobQueryRec(XMLCtx->ctx, XMLCtx->message_body + XMLCtx->jobQueryRec_begin, len,
+                               &XMLCtx->statsConditions);
+               }
+       }
+
+       XMLCtx->char_buf = NULL;
+        XMLCtx->char_buf_len = 0;
+       XMLCtx->level--;
+}
+
+
+
 int parseJobQueryRec(edg_wll_Context ctx, const char *messageBody, long len, edg_wll_QueryRec ***conditions)
 {
        int     ret;
@@ -1165,6 +1233,83 @@ int parseLoadRequest(edg_wll_Context ctx, char *messageBody, edg_wll_LoadRequest
 
 
 
+
+/* parse Stats request from client */
+int parseStatsRequest(edg_wll_Context ctx, char *messageBody, char **function, edg_wll_QueryRec ***conditions, edg_wll_JobStatCode *major, int *minor, time_t *from, time_t *to) 
+{
+       int     ret;
+       edg_wll_XML_ctx         XMLCtx;
+       XML_Char *encoding = "ISO-8859-1";
+
+       
+       /* returns emty variables as default; only some variables will be filled in */
+       /* depending on vaule of XMLCtx.notifFunction */
+       *function = NULL;
+       *major = EDG_WLL_JOB_UNDEF;
+       *minor = 0;
+       *from = 0;
+       *to = 0;
+
+       errno = 0;
+       edg_wll_initXMLCtx(&XMLCtx);
+       XMLCtx.ctx = ctx;
+       XMLCtx.message_body = messageBody;
+       edg_wll_ResetError(ctx);
+
+
+        /* initialize parser */
+        XMLCtx.p = XML_ParserCreate(encoding);
+        XML_SetElementHandler(XMLCtx.p, startStatsRequest, endStatsRequest);
+        XML_SetCharacterDataHandler(XMLCtx.p, char_handler);
+        XML_SetUserData(XMLCtx.p, (void *) &XMLCtx);
+
+
+        if (! XML_Parse(XMLCtx.p, messageBody, strlen(messageBody), 1)) {
+                char *errorMessage;
+
+                asprintf(&errorMessage, "Parse error at line %d:\n%s\n",
+                        XML_GetCurrentLineNumber(XMLCtx.p),
+                        XML_ErrorString(XML_GetErrorCode(XMLCtx.p)));
+
+                edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, errorMessage);
+                free(errorMessage);
+        } else if (XMLCtx.errtxt) edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, XMLCtx.errtxt);
+
+
+       if ((ret = edg_wll_Error(ctx,NULL,NULL))) {
+               int i,j;
+
+               if (XMLCtx.statsConditions) {
+                       for (j = 0; XMLCtx.statsConditions[j]; j++) {
+                               for (i = 0; (XMLCtx.statsConditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ )
+                                       edg_wll_QueryRecFree(&XMLCtx.statsConditions[j][i]);
+                               free(XMLCtx.statsConditions[j]);
+                       }
+                       free(XMLCtx.statsConditions);
+               }
+               free(XMLCtx.notifFunction);
+
+               *function = NULL;
+               *conditions = NULL;
+               *major = EDG_WLL_JOB_UNDEF;
+               *minor = 0;
+               *from = 0;
+               *to = 0;
+       } 
+       else {
+               *function = XMLCtx.statsFunction;
+               *conditions = XMLCtx.statsConditions;
+               *major = XMLCtx.statsMajor;
+               *minor = XMLCtx.statsMinor;
+               *from = XMLCtx.statsFrom;
+               *to = XMLCtx.statsTo;
+       }
+
+       
+        XML_ParserFree(XMLCtx.p);
+       edg_wll_freeXMLCtx(&XMLCtx);
+       return ret;
+}
 /* parse Notif request from client */
 int parseNotifRequest(edg_wll_Context ctx, char *messageBody, char **function, edg_wll_NotifId *notifId, char **address, edg_wll_NotifChangeOp *op, edg_wll_QueryRec ***conditions) 
 {
@@ -1854,3 +1999,38 @@ int edg_wll_QuerySequenceCodeResultToXML(
 }
 
 
+
+/* construct Message-Body of Request-Line for edg_wll_Stats* */
+int edg_wll_StatsResultToXML(
+                edg_wll_Context ctx,
+               time_t from,
+               time_t to,
+               float rate,
+               float duration,
+               int res_from,
+               int res_to,
+                char **message)
+{
+        char *pomA, *pomB;
+
+
+       pomA = strdup("");
+       edg_wll_add_time_t_to_XMLBody(&pomA, from, "from", -1);
+       edg_wll_add_time_t_to_XMLBody(&pomA, to, "to", -1);
+       edg_wll_add_float_to_XMLBody(&pomA, rate, "rate", 0);
+       edg_wll_add_float_to_XMLBody(&pomA, duration, "duration", 0);
+       edg_wll_add_int_to_XMLBody(&pomA, res_from, "res_from", -1);
+       edg_wll_add_int_to_XMLBody(&pomA, res_to, "res_to", -1);
+
+       if (ctx->errDesc || ctx->errCode)
+               trio_asprintf(&pomB,"%s code=\"%d\" desc=\"%|Xs\">\r\n%s%s",
+                       STATS_RESULT_BEGIN, ctx->errCode, ctx->errDesc, pomA, STATS_RESULT_END);
+       else
+               trio_asprintf(&pomB,"%s>\r\n%s%s", STATS_RESULT_BEGIN, pomA, STATS_RESULT_END);
+       free(pomA);
+
+        *message = pomB;
+        return 0;
+}
+
+