RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
testing/json_feeder.cc
00001 /* json_feeder.cc
00002    Wolfgang Sourdeau, February 2013
00003    Copyright (c) 2013 Datacratic.  All rights reserved.
00004 
00005    A utility that feeds a stream of JSON samples to an HTTP server.
00006  */
00007 
00008 
00009 #include <string>
00010 
00011 #include <boost/program_options/cmdline.hpp>
00012 #include <boost/program_options/options_description.hpp>
00013 #include <boost/program_options/positional_options.hpp>
00014 #include <boost/program_options/parsers.hpp>
00015 #include <boost/program_options/variables_map.hpp>
00016 
00017 #include <curlpp/Easy.hpp>
00018 #include <curlpp/Info.hpp>
00019 #include <curlpp/Infos.hpp>
00020 #include <curlpp/Options.hpp>
00021 
00022 #include "jml/utils/filter_streams.h"
00023 
00024 
00025 using namespace std;
00026 using namespace boost::program_options;
00027 using namespace curlpp;
00028 
00029 
00030 struct JsonFeeder {
00031     JsonFeeder(string uri, string filename,
00032                bool printRequests, bool printResponses,
00033                int maxSamples = 1000)
00034         : serverUri(uri), filename(filename), jsonStream(filename),
00035           printRequests(printRequests), printResponses(printResponses),
00036           maxSamples(maxSamples)
00037         {}
00038 
00039     void perform()
00040     {
00041         int sampleNum;
00042 
00043         for (sampleNum = 0; jsonStream && sampleNum < maxSamples;
00044              sampleNum++) {
00045             string current;
00046             getline(jsonStream, current);
00047 
00048             if (current == "") {
00049                 jsonStream = ML::filter_istream(filename);
00050                 getline(jsonStream, current);
00051             }
00052 
00053             Easy client;
00054 
00055             /* perform request */
00056             client.setOpt(options::Url(serverUri));
00057         
00058             client.setOpt(options::Post(true));
00059             client.setOpt(options::PostFields(current));
00060 
00061             list<string> headers;
00062             headers.push_back("Content-Type: application/json");
00063             headers.push_back("Expect:"); /* avoid dual-phase post */
00064             client.setOpt(options::HttpHeader(headers));
00065 
00066             /* separate response headers from body and store response body in "body" */
00067             stringstream body;
00068             client.setOpt(options::TcpNoDelay(true));
00069             client.setOpt(options::Header(false));
00070             client.setOpt(options::WriteStream(&body));
00071             client.perform();
00072 
00073             if (sampleNum > 0 && (printRequests || printResponses)) {
00074                 cerr << "----------------------------" << endl
00075                      << "sample: " << sampleNum << endl;
00076             }
00077 
00078             if (printRequests) {
00079                 cerr << "rq body: " << current << endl;
00080             }
00081 
00082             if (printResponses) {
00083                 int code = infos::ResponseCode::get(client);
00084                 cerr << "resp. code: " << code << endl
00085                      << "resp. body: " << body.str() << endl;
00086             }
00087         }
00088 
00089         cerr << "posted " << sampleNum << " samples" << endl;
00090     }
00091 
00092     string serverUri;
00093     string filename;
00094     ML::filter_istream jsonStream;
00095     bool printRequests;
00096     bool printResponses;
00097     int maxSamples;
00098 };
00099 
00100 
00101 int main(int argc, char *argv[])
00102 {
00103     string serverUri;
00104     string filename;
00105     bool printRequests(false), printResponses(false);
00106 
00107     {
00108         using namespace boost::program_options;
00109 
00110         options_description configuration_options("Configuration options");
00111 
00112         configuration_options.add_options()
00113             ("server-uri,s", value(&serverUri),
00114              "URI of server to feed")
00115             ("filename,f", value(&filename),
00116              "filename")
00117             ("printrequests", value(&printRequests)->zero_tokens(),
00118              "print requests on console")
00119             ("printresponses", value(&printResponses)->zero_tokens(),
00120              "print responses on console");
00121  
00122         options_description all_opt;
00123         all_opt.add(configuration_options);
00124         all_opt.add_options()
00125             ("help,h", "print this message");
00126 
00127         variables_map vm;
00128         store(command_line_parser(argc, argv)
00129               .options(all_opt)
00130               .run(),
00131               vm);
00132         notify(vm);
00133 
00134         if (vm.count("help")) {
00135             cerr << all_opt << endl;
00136             exit(1);
00137         }
00138 
00139         if (serverUri.empty()) {
00140             cerr << "'server-uri' parameter is required" << endl;
00141             exit(1);
00142         }
00143 
00144         if (filename.empty()) {
00145             cerr << "'filename' parameter is required" << endl;
00146             exit(1);
00147         }
00148     }
00149 
00150     JsonFeeder feeder(serverUri, filename, printRequests, printResponses);
00151     feeder.perform();
00152 
00153     return 0;
00154 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator