Initial version of text interface.
authorJiří Filipovič <fila@ics.muni.cz>
Fri, 4 Jul 2008 12:14:52 +0000 (12:14 +0000)
committerJiří Filipovič <fila@ics.muni.cz>
Fri, 4 Jul 2008 12:14:52 +0000 (12:14 +0000)
org.glite.lb.server/src/lb_proto.c
org.glite.lb.server/src/lb_text.c [new file with mode: 0644]
org.glite.lb.server/src/lb_text.h [new file with mode: 0644]

index 00291a0..3893cad 100644 (file)
@@ -190,6 +190,21 @@ static int outputHTML(char **headers)
 }
 
 
+static int drain_text_request(char *request){
+       int i = 0;
+       while (!isspace(request[i])) i++;
+       if (i < 5) 
+               return 0;
+       if (! strncmp(request+i-5, "/text", 5)){
+               if (i == 5)
+                       strcpy(request+i-4, request+i); // keep '/'
+               else
+                       strcpy(request+i-5, request+i);
+               return 1;
+       }
+       else
+               return 0;
+}
 
 
 edg_wll_ErrorCode edg_wll_ProtoV21(edg_wll_Context ctx,
@@ -384,9 +399,10 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
        char *request,char **headers,char *messageBody,
        char **response,char ***headersOut,char **bodyOut)
 {
-       char *requestPTR, *message = NULL;
+       char *requestPTR = NULL, *message = NULL;
        int     ret = HTTP_OK;
        int     html = outputHTML(headers);
+       int     text = 0; //XXX: Plain text communication is special case of html here, hence when text=1, html=1 too
        int     i;
 
        edg_wll_ResetError(ctx);
@@ -425,7 +441,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
 /* GET */
        if (!strncmp(request, METHOD_GET, sizeof(METHOD_GET)-1)) {
                
-               requestPTR = request + sizeof(METHOD_GET)-1;
+               requestPTR = strdup(request + sizeof(METHOD_GET)-1);
+               if (html) text = drain_text_request(requestPTR);
 
 
        /* GET /: Current User Jobs */
@@ -437,7 +454,10 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
 
 // FIXME: edg_wll_UserJobs should take flags as parameter
                        switch (edg_wll_UserJobsServer(ctx,&jobsOut,NULL)) {
-                               case 0: if (html) edg_wll_UserJobsToHTML(ctx, jobsOut, &message);
+                               case 0: if (text)
+                                               edg_wll_UserJobsToText(ctx, jobsOut, &message);
+                                       else if (html)
+                                               edg_wll_UserJobsToHTML(ctx, jobsOut, &message);
                                        else ret = HTTP_OK;
                                        break;
                                case ENOENT: ret = HTTP_NOTFOUND; break;
@@ -481,7 +501,10 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
                                ret = HTTP_BADREQ;
                        }
                        else switch (edg_wll_JobStatusServer(ctx,jobId,0,&stat)) {
-                               case 0: if (html) edg_wll_JobStatusToHTML(ctx,stat,&message); 
+                               case 0: if (text) 
+                                               edg_wll_JobStatusToText(ctx,stat,&message); 
+                                       else if (html)
+                                               edg_wll_JobStatusToHTML(ctx,stat,&message);
                                        else ret = HTTP_OK;
                                        break;
                                case ENOENT: ret = HTTP_NOTFOUND; break;
@@ -499,11 +522,13 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
 
        /* GET [something else]: not understood */
                } else ret = HTTP_BADREQ;
+               free(requestPTR); requestPTR = NULL;
 
 /* POST */
        } else if (!strncmp(request,METHOD_POST,sizeof(METHOD_POST)-1)) {
 
-               requestPTR = request + sizeof(METHOD_POST)-1;
+               requestPTR = strdup(request + sizeof(METHOD_POST)-1);
+               if (html) text = drain_text_request(requestPTR);
        
                if (!strncmp(requestPTR,KEY_QUERY_EVENTS,sizeof(KEY_QUERY_EVENTS)-1)) { 
                        edg_wll_Event *eventsOut = NULL;
@@ -912,15 +937,21 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
         /* POST [something else]: not understood */
                else ret = HTTP_BADREQ;
 
+               free(requestPTR); requestPTR = NULL;
+
 /* other HTTP methods */
        } else ret = HTTP_NOTALLOWED;
 
 err:   asprintf(response,"HTTP/1.1 %d %s",ret,edg_wll_HTTPErrorMessage(ret));
        *headersOut = (char **) (html ? response_headers_html : response_headers_dglb);
-       if ((ret != HTTP_OK) && html)
+       if ((ret != HTTP_OK) && text)
+                *bodyOut = edg_wll_ErrorToText(ctx,ret);
+       else if ((ret != HTTP_OK) && html)
                *bodyOut = edg_wll_ErrorToHTML(ctx,ret);
        else
                *bodyOut = message;
 
+       if (requestPTR) free(requestPTR);
+
        return edg_wll_Error(ctx,NULL,NULL);
 }
diff --git a/org.glite.lb.server/src/lb_text.c b/org.glite.lb.server/src/lb_text.c
new file mode 100644 (file)
index 0000000..48ff9c9
--- /dev/null
@@ -0,0 +1,146 @@
+#ident "$Header$"
+
+#include "lb_text.h"
+#include "lb_proto.h"
+
+#include "glite/lb/context-int.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef __GNUC__
+#define UNUSED_VAR __attribute__((unused))
+#else
+#define UNUSED_VAR
+#endif
+
+int edg_wll_QueryToText(edg_wll_Context ctx UNUSED_VAR, edg_wll_Event *eventsOut UNUSED_VAR, char **message UNUSED_VAR)
+{
+/* not implemented yet */
+       return -1;
+}
+
+/* construct Message-Body of Response-Line for edg_wll_UserJobs */
+int edg_wll_UserJobsToText(edg_wll_Context ctx, edg_wlc_JobId *jobsOut, char **message)
+{
+       char *a, *b;
+       int i = 0;
+       b = strdup("");
+
+       while (jobsOut[i]){
+               char *chid = edg_wlc_JobIdUnparse(jobsOut[i]);
+
+               if (i == 0)
+                       asprintf(&a, "%s%s", b, chid);
+               else
+                       asprintf(&a, "%s,%s", b, chid);
+
+               free(chid);
+               free(b);
+               b = a;
+               i++;
+       }
+
+       asprintf(&a, "User_jobs=%s\n"
+                    "User_subject=%s\n",
+               b, ctx->peerName ? ctx->peerName: "<anonymous>");
+
+        *message = a;
+
+        return 0;
+}
+
+
+/* construct Message-Body of Response-Line for edg_wll_JobStatus */
+int edg_wll_JobStatusToText(edg_wll_Context ctx UNUSED_VAR, edg_wll_JobStat stat, char **message)
+{
+       char *a, *b;
+       char    *chid,*chstat;
+        char    *jdl,*rsl;
+
+       *chid = edg_wlc_JobIdUnparse(stat.jobId);
+
+       #define TR(name,type,field) \
+        if (field) { \
+                asprintf(&a,"%s%s=" type "\n", \
+                        b, name, field); \
+                free(b); \
+                b = a; \
+        }
+
+       jdl = strdup("");
+       rsl = strdup("");
+       
+       b = strdup("");
+
+        chid = edg_wlc_JobIdUnparse(stat.jobId);
+
+       TR("Status","%s",(chstat = edg_wll_StatToString(stat.state)));
+       free(chstat);
+       TR("owner","%s",stat.owner);
+       TR("Condor_Id","%s",stat.condorId);
+       TR("Globus_Id","%s",stat.globusId);
+       TR("Local_Id","%s",stat.localId);
+       TR("Reason","%s",stat.reason);
+       if ( (stat.stateEnterTime.tv_sec) || (stat.stateEnterTime.tv_usec) ) {
+               time_t  time = stat.stateEnterTime.tv_sec;
+               //TR("State_entered","%s",ctime(&time));
+               asprintf(&a, "%sState_entered=%s", b, ctime(&time));
+               free(b); b = a;
+       }
+        if ( (stat.lastUpdateTime.tv_sec) || (stat.lastUpdateTime.tv_usec) ) {
+               time_t  time = stat.lastUpdateTime.tv_sec;
+               //TR("Last_update","%s",ctime(&time));
+               asprintf(&a, "%sLast_update=%s", b, ctime(&time));
+                free(b); b = a;
+       }
+       TR("Expect_update","%s",stat.expectUpdate ? "YES" : "NO");
+       TR("Expect_update_from","%s",stat.expectFrom);
+       TR("Location","%s",stat.location);
+       TR("Destination","%s",stat.destination);
+       TR("Cancelling","%s",stat.cancelling>0 ? "YES" : "NO");
+       if (stat.cancelReason != NULL) {
+               TR("Cancel_reason","%s",stat.cancelReason);
+       }
+       TR("CPU_time","%d",stat.cpuTime);
+
+       
+       TR("Done_code","%d",stat.done_code);
+       TR("Exit_code","%d",stat.exit_code);
+
+        if (stat.jdl) asprintf(&jdl,">Job_description = %s\n", stat.jdl);
+
+       if (stat.rsl) asprintf(&rsl,"RSL = %s\n", stat.rsl);
+
+        asprintf(&a, "Job = %s\n"
+                       "%s"
+                       "%s"
+                       "%s",
+                       chid,b,jdl,rsl);
+        free(b);
+
+        *message = a;
+
+       free(chid);
+       free(jdl);
+       free(rsl);
+        return 0;
+}
+
+char *edg_wll_ErrorToText(edg_wll_Context ctx,int code)
+{
+       char    *out,*et,*ed;
+       char    *msg = edg_wll_HTTPErrorMessage(code);
+       edg_wll_ErrorCode       e;
+
+       e = edg_wll_Error(ctx,&et,&ed);
+       asprintf(&out,"Error=%s\n"
+               "Code=%d\n"
+               "Description=%s (%s)\n"
+               ,msg,e,et,ed);
+
+       free(et); free(ed);
+       return out;
+}
diff --git a/org.glite.lb.server/src/lb_text.h b/org.glite.lb.server/src/lb_text.h
new file mode 100644 (file)
index 0000000..042e1fb
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef GLITE_LB_TEXT_H
+#define GLITE_LB_TEXT_H
+
+#include "glite/lb/context.h"
+#include "glite/lb/events.h"
+#include "glite/lb/jobstat.h"
+
+int edg_wll_QueryToText(edg_wll_Context,edg_wll_Event *,char **);
+int edg_wll_JobStatusToText(edg_wll_Context, edg_wll_JobStat, char **);
+int edg_wll_UserJobsToText(edg_wll_Context, edg_wlc_JobId *, char **);
+char *edg_wll_ErrorToText(edg_wll_Context,int);
+
+#endif /* GLITE_LB_TEXT */