From: Aleš Křenek Date: Mon, 26 Sep 2005 09:43:18 +0000 (+0000) Subject: import of statistics counting X-Git-Tag: gridsite-core_R_1_1_12~89 X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=9107bcd08b86f3b41501ca9dc4f247ac5584ddf5;p=jra1mw.git import of statistics counting --- diff --git a/org.glite.lb.server/src/jobstat.c b/org.glite.lb.server/src/jobstat.c index a1f27ae..8920d42 100644 --- a/org.glite.lb.server/src/jobstat.c +++ b/org.glite.lb.server/src/jobstat.c @@ -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); diff --git a/org.glite.lb.server/src/lb_proto.c b/org.glite.lb.server/src/lb_proto.c index c6fb6d9..7dba657 100644 --- a/org.glite.lb.server/src/lb_proto.c +++ b/org.glite.lb.server/src/lb_proto.c @@ -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 */ diff --git a/org.glite.lb.server/src/lb_xml_parse.c.T b/org.glite.lb.server/src/lb_xml_parse.c.T index 6a13b2b..cea530e 100644 --- a/org.glite.lb.server/src/lb_xml_parse.c.T +++ b/org.glite.lb.server/src/lb_xml_parse.c.T @@ -43,7 +43,10 @@ #define QUERY_SEQUENCE_CODE_RESULT_BEGIN "\r\n" - +#define STATS_RESULT_BEGIN "\r\n" + + // XXX will be redundant soon #define USERJOBS_BEGIN "\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; +} + +