00001 /*------------------------------------------------------------------------------ 00002 Name: xmlBlaster/demo/c++/TestEmptyContent.cpp 00003 Project: xmlBlaster.org 00004 Comment: C++ client example 00005 Author: Michele Laghi 00006 ------------------------------------------------------------------------------*/ 00007 #include <client/XmlBlasterAccess.h> 00008 #include <util/XmlBlasterException.h> 00009 #include <util/ErrorCode.h> 00010 #include <util/Global.h> 00011 #include <util/I_Log.h> 00012 #include <util/Timestamp.h> 00013 00014 using namespace std; 00015 using namespace org::xmlBlaster::util; 00016 using namespace org::xmlBlaster::util::qos; 00017 using namespace org::xmlBlaster::util::dispatch; 00018 using namespace org::xmlBlaster::client; 00019 using namespace org::xmlBlaster::client::qos; 00020 using namespace org::xmlBlaster::client::key; 00021 00037 class TestEmptyContent : public I_Callback, // for the asynchroneous updates 00038 public I_ConnectionProblems // notification of connection problems when failsafe 00039 { 00040 private: 00041 string ME; // the string identifying this class when logging 00042 Global& global_; 00043 I_Log& log_; // the reference to the log object for this instance 00044 00045 public: 00046 TestEmptyContent(Global& glob) 00047 : ME("TestEmptyContent"), 00048 global_(glob), 00049 log_(glob.getLog("demo")) // all logs written in this class are written to the 00050 { // log channel called 'demo'. To see the traces of this 00051 // channel invoke -trace[demo] true on the command line, 00052 // then it will only switch on the traces for the demo channel 00053 log_.info(ME, "Trying to connect to xmlBlaster with C++ client lib " + Global::getVersion() + 00054 " from " + Global::getBuildTimestamp()); 00055 } 00056 00057 virtual ~TestEmptyContent() // the constructor does nothing for the moment 00058 { 00059 } 00060 00061 00062 bool reachedAlive(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/) 00063 { 00064 log_.info(ME, "reconnected"); 00065 return true; 00066 } 00067 00068 void reachedDead(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/) 00069 { 00070 log_.info(ME, "lost connection"); 00071 } 00072 00073 void reachedPolling(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/) 00074 { 00075 log_.info(ME, "going to poll modus"); 00076 } 00077 00078 void execute() 00079 { 00080 try { 00081 XmlBlasterAccess con(global_); 00082 con.initFailsafe(this); 00083 00084 // Creates a connect qos with the user 'joe' and the password 'secret' 00085 ConnectQos qos(global_, "joe", "secret"); 00086 00087 /* To test SOCKET plugin 00088 ServerRef ref("SOCKET", "socket://localhost:7604"); 00089 qos.addServerRef(ref); 00090 */ 00091 log_.info(ME, string("connecting to xmlBlaster. Connect qos: ") + qos.toXml()); 00092 00093 // connects to xmlBlaster and gives a pointer to this class to tell 00094 // which update method to invoke when callbacks come from the server. 00095 ConnectReturnQos retQos = con.connect(qos, this); // Login and register for updates 00096 log_.info(ME, "successfully connected to xmlBlaster. Return qos: " + retQos.toXml()); 00097 00098 // subscribe key. By invoking setOid you implicitly choose the 'EXACT' mode. 00099 // If you want to subscribe with XPATH use setQueryString instead. 00100 SubscribeKey subKey(global_); 00101 subKey.setOid("TestEmptyContent"); 00102 SubscribeQos subQos(global_); 00103 log_.info(ME, string("subscribing to xmlBlaster with key: ") + subKey.toXml() + 00104 " and qos: " + subQos.toXml()); 00105 00106 SubscribeReturnQos subRetQos = con.subscribe(subKey, subQos); 00107 log_.info(ME, string("successfully subscribed to xmlBlaster. Return qos: ") + 00108 subRetQos.toXml()); 00109 00110 // publish a message with the oid 'TestEmptyContent' 00111 PublishQos publishQos(global_); 00112 PublishKey publishKey(global_); 00113 publishKey.setOid("TestEmptyContent"); 00114 publishKey.setContentMime("text/plain"); 00115 MessageUnit msgUnit(publishKey, string(""), publishQos); 00116 log_.info(ME, string("publishing to xmlBlaster with message: ") + msgUnit.toXml()); 00117 PublishReturnQos pubRetQos = con.publish(msgUnit); 00118 log_.info(ME, "successfully published to xmlBlaster. Return qos: " + pubRetQos.toXml()); 00119 try { 00120 org::xmlBlaster::util::thread::Thread::sleepSecs(1); 00121 } 00122 catch(XmlBlasterException e) { 00123 log_.error(ME, e.toXml()); 00124 } 00125 00126 // now an update should have come. Its time to erase the message, 00127 // otherwise you would get directly an update the next time you connect 00128 // to the same xmlBlaster server. 00129 // Specify which messages you want to erase. Note that you will get an 00130 // update with the status of the UpdateQos set to 'ERASED'. 00131 EraseKey eraseKey(global_); 00132 eraseKey.setOid("TestEmptyContent"); 00133 EraseQos eraseQos(global_); 00134 log_.info(ME, string("erasing the published message. Key: ") + eraseKey.toXml() + 00135 " qos: " + eraseQos.toXml()); 00136 vector<EraseReturnQos> eraseRetQos = con.erase(eraseKey, eraseQos); 00137 for (size_t i=0; i < eraseRetQos.size(); i++ ) { 00138 log_.info(ME, string("successfully erased the message. return qos: ") + 00139 eraseRetQos[i].toXml()); 00140 } 00141 00142 log_.info(ME, "going to sleep for 2 sec and disconnect"); 00143 org::xmlBlaster::util::thread::Thread::sleep(2000); 00144 00145 DisconnectQos disconnectQos(global_); 00146 con.disconnect(disconnectQos); 00147 } 00148 catch (XmlBlasterException e) { 00149 log_.error(ME, e.toXml()); 00150 } 00151 } 00152 00156 string update(const string& /*sessionId*/, UpdateKey& updateKey, const unsigned char* /*content*/, 00157 long /*contentSize*/, UpdateQos& updateQos) 00158 { 00159 log_.info(ME, "update: key: " + updateKey.toXml()); 00160 log_.info(ME, "update: qos: " + updateQos.toXml()); 00161 log_.info(ME, "update: mime: " + updateKey.getContentMime()); 00162 // if (true) throw XmlBlasterException(USER_UPDATE_ERROR, "TestEmptyContent", ""); 00163 return ""; 00164 } 00165 00166 }; 00167 00175 int main(int args, char ** argv) 00176 { 00177 org::xmlBlaster::util::Object_Lifetime_Manager::init(); 00178 Global& glob = Global::getInstance(); 00179 glob.initialize(args, argv); 00180 // XmlBlasterAccess::usage(); 00181 // glob.getLog().info("TestEmptyContent", "Example: TestEmptyContent\n"); 00182 00183 TestEmptyContent hello(glob); 00184 hello.execute(); 00185 org::xmlBlaster::util::Object_Lifetime_Manager::fini(); 00186 return 0; 00187 }