First version of RSS feed for finished jobs.
authorJiří Filipovič <fila@ics.muni.cz>
Mon, 27 Apr 2009 13:31:36 +0000 (13:31 +0000)
committerJiří Filipovič <fila@ics.muni.cz>
Mon, 27 Apr 2009 13:31:36 +0000 (13:31 +0000)
TODO:
- configure time of RSS feed (currently feds all jobs)
- only indexed queries
- add more feeds...

org.glite.lb.server/src/lb_proto.c
org.glite.lb.server/src/lb_rss.c [new file with mode: 0644]
org.glite.lb.server/src/lb_rss.h [new file with mode: 0644]

index 7a07549..47632b0 100644 (file)
@@ -286,6 +286,49 @@ static void freeNotifInfo(notifInfo *ni){
        if (ni->conditions_text) free(ni->conditions_text);
 }
 
+static int getJobsRSS(edg_wll_Context ctx, char *feedType, edg_wll_JobStat **statesOut){
+       edg_wlc_JobId *jobsOut;
+        //edg_wll_JobStat *statesOut;
+        edg_wll_QueryRec **conds;
+       int i;
+
+       char *can_peername = edg_wll_gss_normalize_subj(ctx->peerName, 0);
+
+       if (strncmp(feedType, "finished", strlen("finished")) == 0){
+               conds = malloc(3*sizeof(*conds));
+               conds[0] = malloc(2*sizeof(**conds));
+               conds[0][0].attr = EDG_WLL_QUERY_ATTR_OWNER;
+               conds[0][0].op = EDG_WLL_QUERY_OP_EQUAL;
+               conds[0][0].value.c = can_peername;
+               conds[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF;
+               conds[1] = malloc(4*sizeof(**conds));
+               conds[1][0].attr = EDG_WLL_QUERY_ATTR_STATUS;
+               conds[1][0].op = EDG_WLL_QUERY_OP_EQUAL;
+               conds[1][0].value.i = EDG_WLL_JOB_DONE;
+               conds[1][1].attr = EDG_WLL_QUERY_ATTR_STATUS;
+                conds[1][1].op = EDG_WLL_QUERY_OP_EQUAL;
+                conds[1][1].value.i = EDG_WLL_JOB_ABORTED;
+               conds[1][2].attr = EDG_WLL_QUERY_ATTR_STATUS;
+                conds[1][2].op = EDG_WLL_QUERY_OP_EQUAL;
+                conds[1][2].value.i = EDG_WLL_JOB_CANCELLED;
+               conds[1][3].attr = EDG_WLL_QUERY_ATTR_UNDEF;
+               conds[2] = NULL;
+       }
+       else{
+               *statesOut = NULL;
+               return -1;
+       }
+
+       edg_wll_QueryJobsServer(ctx, conds, 0, &jobsOut, statesOut);
+
+       for (i = 0; conds[i]; i++)
+               free(conds[i]);
+       free(conds);
+       free(can_peername);
+
+       return 0;
+}
+
 edg_wll_ErrorCode edg_wll_ProtoV21(edg_wll_Context ctx,
        char *request,char **headers,char *messageBody,
        char **response,char ***headersOut,char **bodyOut)
@@ -555,7 +598,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
                } 
 
        /* GET /[jobId]: Job Status */
-               else if (*requestPTR=='/' 
+               else if (*requestPTR=='/'
+                       && strncmp(requestPTR, "/RSS", strlen("/RSS")) 
                        && strncmp(requestPTR, "/NOTIF", strlen("/NOTIF"))
                        && *(requestPTR+strlen("/NOTIF")-1) != ':'
                        && !isspace(*(requestPTR+strlen("/NOTIF")-1))) {
@@ -635,6 +679,17 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
 
                        freeNotifInfo(&ni);
 
+       /*GET /RSS:[feed type] RSS feed */
+               } else if (strncmp(requestPTR, "/RSS:", strlen("/RSS:")) == 0){
+                       edg_wll_JobStat *states;
+                       char *feedType = requestPTR + strlen("/RSS:");
+                       if (getJobsRSS(ctx, feedType, &states) < 0){
+                               ret = HTTP_INTERNAL;
+                                goto err;
+                       }
+                       edg_wll_RSSFeed(ctx, states, requestPTR, &message);
+                       // freeJobStates
+
        /* GET [something else]: not understood */
                } else ret = HTTP_BADREQ;
                free(requestPTR); requestPTR = NULL;
diff --git a/org.glite.lb.server/src/lb_rss.c b/org.glite.lb.server/src/lb_rss.c
new file mode 100644 (file)
index 0000000..7c36202
--- /dev/null
@@ -0,0 +1,84 @@
+#ident "$Header:"
+
+#include "lb_rss.h"
+#include "lb_proto.h"
+
+#include "glite/lb/context-int.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <assert.h>
+
+#ifdef __GNUC__
+#define UNUSED_VAR __attribute__((unused))
+#else
+#define UNUSED_VAR
+#endif
+
+#define TR(type, field) \
+       if (field){ \
+               int l = asprintf(&pomA, type, (field)); \ 
+               pomB = realloc(pomB, sizeof(*pomB)*(pomL+l+1)); \
+               strcpy(pomB+pomL, pomA); \
+               pomL += l; \
+               free(pomA); pomA = NULL; \
+       }
+
+#define TRC(str) \
+       { \
+               int l = asprintf(&pomA, str); \
+               pomB = realloc(pomB, sizeof(*pomB)*(pomL+l+1)); \
+               strcpy(pomB+pomL, pomA); \
+                pomL += l; \
+                free(pomA); pomA = NULL; \ 
+       }
+
+
+int edg_wll_RSSFeed(edg_wll_Context ctx UNUSED_VAR, edg_wll_JobStat *states, char *request, char **message){
+       char *pomA = NULL, *pomB = NULL;
+       int pomL = 0;
+       int i;
+       char *chid, *chstat, *rss_link, *tmp;
+       time_t time;
+       
+       TRC("<?xml version=\"1.0\"?>\n<rss version=\"2.0\">\n<channel>\n");
+       TRC("<title>LB feed</title>\n");
+       asprintf(&rss_link, "https://%s:%i%s", ctx->srvName, ctx->srvPort, request);
+       for (tmp = rss_link; *tmp && !isspace(*tmp); tmp++);
+       *tmp = 0;
+       TR("<link>%s</link>\n", rss_link);
+       TRC("<description>List of jobs.</description>");
+       if (states) for (i = 0; states[i].state != EDG_WLL_JOB_UNDEF; i++){
+               TRC("<item>\n");
+               TR("<title>%s</title>\n", (chid = edg_wlc_JobIdUnparse(states[i].jobId)));
+               TR("<link>%s</link>\n", chid);
+               TR("<guid>%s</guid>\n", chid);
+               // strip description to allow new lines
+               TR("<description>Status: %s</description>\n", (chstat = edg_wll_StatToString(states[i].state)));
+               TRC("</item>\n<item>\n");
+               time = states[i].stateEnterTime.tv_sec;
+               TR("<description>State entered: %s</description>\n", ctime(&time));
+               TRC("</item>\n<item>\n");
+               TR("<description>Destination: %s</description>\n", states[i].destination);
+               TRC("</item>\n");
+               
+               
+               /*TRC("<description>");
+               TR("Status: %s\n", (chstat = edg_wll_StatToString(states[i].state)));
+               time = states[i].stateEnterTime.tv_sec;
+               TR("State entered %s\n", ctime(&time));
+               TRC("</description>\n");
+               TR("<guid>%s</guid>\n", chid);
+               TRC("</item>\n");*/
+               free(chid);
+               free(chstat);
+       }
+       TRC("</channel>\n</rss>");
+
+       *message = pomB;
+
+       return 0;
+}
+
diff --git a/org.glite.lb.server/src/lb_rss.h b/org.glite.lb.server/src/lb_rss.h
new file mode 100644 (file)
index 0000000..e690ee7
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef GLITE_LB_RSS_H
+#define GLITE_LB_RSS_H
+
+#include "glite/lb/context-int.h"
+#include "glite/lb/jobstat.h"
+
+int edg_wll_RSSFeed(edg_wll_Context ctx, edg_wll_JobStat *states, char *request, char **message);
+
+#endif /* GLITE_LB_RSS_H */