blackboard_processor.cpp

00001
00002 /***************************************************************************
00003  *  blackboard_processor.cpp - Web request processor for BlackBoard info
00004  *
00005  *  Created: Thu Oct 23 16:10:21 2008
00006  *  Copyright  2006-2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022
00023 #include "blackboard_processor.h"
00024 #include "page_reply.h"
00025
00026 #include <blackboard/blackboard.h>
00027 #include <interface/interface.h>
00028 #include <interface/field_iterator.h>
00029 #include <interface/interface_info.h>
00030
00031 #include <string>
00032 #include <cstring>
00033 #include <cstdlib>
00034
00035 using namespace fawkes;
00036 
00037 /** @class WebBlackBoardRequestProcessor "blackboard_processor.h"
00038  * BlackBoard web request processor.
00039  * Provides access to BlackBoard introspection features.
00040  * @author Tim Niemueller
00041  */
00042 
00043 /** Constructor.
00044  * @param baseurl Base URL where processor is mounted
00045  * @param blackboard BlackBoard instance
00046  */
00047 WebBlackBoardRequestProcessor::WebBlackBoardRequestProcessor(const char *baseurl,
00048                                                              BlackBoard *blackboard)
00049 {
00050   __baseurl     = strdup(baseurl);
00051   __baseurl_len = strlen(__baseurl);
00052   __blackboard  = blackboard;
00053 }
00054
00055 
00056 /** Destructor. */
00057 WebBlackBoardRequestProcessor::~WebBlackBoardRequestProcessor()
00058 {
00059   free(__baseurl);
00060   for (__ifi = __interfaces.begin(); __ifi != __interfaces.end(); ++__ifi) {
00061     __blackboard->close(__ifi->second);
00062   }
00063   __interfaces.clear();
00064 }
00065
00066
00067 WebReply *
00068 WebBlackBoardRequestProcessor::process_request(const char *url,
00069                                                const char *method,
00070                                                const char *version,
00071                                                const char *upload_data,
00072                                                size_t *upload_data_size,
00073                                                void **session_data)
00074 {
00075   if ( strncmp(__baseurl, url, __baseurl_len) == 0 ) {
00076     // It is in our URL prefix range
00077     std::string subpath = std::string(url).substr(__baseurl_len);
00078
00079     WebPageReply *r = new WebPageReply("BlackBoard");
00080     *r += "<h2>BlackBoard interfaces:</h2>\n";
00081
00082     bool found_some = false;
00083     InterfaceInfoList *iil = __blackboard->list_all();
00084     for (InterfaceInfoList::iterator i = iil->begin(); i != iil->end(); ++i) {
00085       if (! found_some) {
00086         *r += "<table>\n";
00087         *r += "<tr><th>Interface</th><th>Reader(s)</th><th>Writer</th></tr>\n";
00088         found_some = true;
00089       }
00090       r->append_body("<tr><td><a href=\"%s/view/%s::%s\">%s::%s</a></td><td>%u</td><td style=\"color:%s\">%s</td></tr>\n",
00091                      __baseurl, i->type(), i->id(), i->type(), i->id(),
00092                      i->num_readers(), i->has_writer() ? "green" : "red", i->has_writer() ? "yes" : "no");
00093     }
00094     delete iil;
00095
00096     if (found_some) {
00097       *r += "</table>\n";
00098     } else {
00099       *r += "<b>No interfaces found.</b>\n";
00100     }
00101
00102     if (subpath.find("/view/") == 0) {
00103       std::string iuid = subpath.substr(subpath.find_first_not_of("/", std::string("/view/").length()));
00104       std::string iftype = iuid.substr(0, iuid.find("::"));
00105       std::string ifname = iuid.substr(iuid.find("::") + 2);
00106
00107
00108       r->append_body("<a href=\"%s\">Clear detailed</a>\n", __baseurl);
00109
00110       r->append_body("<h2>Interface: %s</h2>\n", iuid.c_str());
00111       if (__interfaces.find(iuid) == __interfaces.end()) {
00112         try {
00113           Interface *iface = __blackboard->open_for_reading(iftype.c_str(), ifname.c_str());
00114           __interfaces[iuid] = iface;
00115         } catch (Exception &e) {
00116           r->append_body("Failed to open interface: %s\n", e.what());
00117         }
00118       }
00119       if (__interfaces.find(iuid) != __interfaces.end()) {
00120         Interface *iface = __interfaces[iuid];
00121         iface->read();
00122
00123         r->append_body("<table>\n"
00124                        " <tr><td><b>Type:</b></td><td>%s</td></tr>\n"
00125                        " <tr><td><b>ID:</b></td><td>%s</td></tr>\n"
00126                        " <tr><td><b>Has writer?:</b></td><td>%s</td></tr>\n"
00127                        " <tr><td><b>Num readers:</b></td><td>%u</td></tr>\n"
00128                        " <tr><td><b>Serial:</b></td><td>%u</td></tr>\n"
00129                        " <tr><td><b>Data size:</b></td><td>%u</td></tr>\n"
00130                        " <tr><td><b>Hash:</b></td><td>%s</td></tr>\n"
00131                        "</table>\n",
00132                        iface->type(), iface->id(), iface->has_writer() ? "yes" : "no",
00133                        iface->num_readers(), iface->serial(),
00134                        iface->datasize(), iface->hash_printable());
00135
00136         r->append_body("<table>\n"
00137                        " <tr>\n"
00138                        "  <th>Name</th><th>Type</th><th>Value</th>\n"
00139                        " </tr>\n");
00140         for (InterfaceFieldIterator fi = iface->fields(); fi != iface->fields_end(); ++fi) {
00141           bool is_string = (fi.get_type() == IFT_STRING);
00142           *r += " <tr>\n";
00143           if ( fi.get_length() > 1 ) {
00144             r->append_body("  <td>%s</td><td>%s [%zu]</td><td>%s%s%s</td>\n",
00145                            fi.get_name(), fi.get_typename(),
00146                            fi.get_length(), is_string ? "<pre>" : "",
00147                            fi.get_value_string(), is_string ? "</pre>" : "");
00148           } else {
00149             r->append_body("  <td>%s</td><td>%s</td><td>%s%s%s</td>\n",
00150                            fi.get_name(), fi.get_typename(), is_string ? "<pre>" : "",
00151                            fi.get_value_string(), is_string ? "</pre>" : "");
00152           }
00153           *r += " </tr>\n";
00154         }
00155         r->append_body("</table>\n");
00156       }
00157     }
00158
00159     return r;
00160   } else {
00161     return NULL;
00162   }
00163 }