#include "index.h"
#include "jobstat.h"
#include "lb_authz.h"
+#include "stats.h"
#define DAG_ENABLE 1
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);
#include "lb_proto.h"
#include "lb_html.h"
+#include "stats.h"
#include "get_events.h"
#include "purge.h"
#include "lb_xml_parse.h"
#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"
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 */
#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"
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
+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;
+
+/* 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)
{
}
+
+/* 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;
+}
+
+