1 /*------------------------------------------------------------------------------
  2 Name:      xmlBlaster/demo/c++/TestEmptyContent.cpp
  3 Project:   xmlBlaster.org
  4 Comment:   C++ client example
  5 Author:    Michele Laghi
  6 ------------------------------------------------------------------------------*/
  7 #include <client/XmlBlasterAccess.h>
  8 #include <util/XmlBlasterException.h>
  9 #include <util/ErrorCode.h>
 10 #include <util/Global.h>
 11 #include <util/I_Log.h>
 12 #include <util/Timestamp.h>
 13 
 14 using namespace std;
 15 using namespace org::xmlBlaster::util;
 16 using namespace org::xmlBlaster::util::qos;
 17 using namespace org::xmlBlaster::util::dispatch;
 18 using namespace org::xmlBlaster::client;
 19 using namespace org::xmlBlaster::client::qos;
 20 using namespace org::xmlBlaster::client::key;
 21 
 22 /**
 23  * This client connects to xmlBlaster and subscribes to a message.
 24  * <p>
 25  * We then publish the message and receive it asynchronous in the update() method.
 26  * </p>
 27  * <p>
 28  * Note that the CORBA layer is transparently hidden,
 29  * and all code conforms to STD C++ (with STL).
 30  * </p>
 31  * <pre>
 32  * Invoke: TestEmptyContent
 33  * </pre>
 34  * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.html"
 35  *              target="others">xmlBlaster interface</a>
 36  */
 37 class TestEmptyContent : public I_Callback,     // for the asynchroneous updates
 38                     public I_ConnectionProblems // notification of connection problems when failsafe
 39 {
 40 private:
 41    string  ME;                        // the string identifying this class when logging
 42    Global& global_;
 43    I_Log&  log_;                      // the reference to the log object for this instance
 44 
 45 public:
 46    TestEmptyContent(Global& glob) 
 47    : ME("TestEmptyContent"),
 48      global_(glob), 
 49      log_(glob.getLog("demo"))        // all logs written in this class are written to the
 50    {                                  // log channel called 'demo'. To see the traces of this
 51                                       // channel invoke -trace[demo] true on the command line,
 52                                       // then it will only switch on the traces for the demo channel
 53       log_.info(ME, "Trying to connect to xmlBlaster with C++ client lib " + Global::getVersion() +
 54                     " from " + Global::getBuildTimestamp());
 55    }
 56 
 57    virtual ~TestEmptyContent()             // the constructor does nothing for the moment
 58    {
 59    }
 60 
 61 
 62    bool reachedAlive(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/)
 63    {
 64       log_.info(ME, "reconnected");
 65       return true;
 66    }
 67 
 68    void reachedDead(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/)
 69    {
 70       log_.info(ME, "lost connection");
 71    }
 72 
 73    void reachedPolling(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/)
 74    {
 75       log_.info(ME, "going to poll modus");
 76    }
 77 
 78    void execute()
 79    {
 80       try {
 81          XmlBlasterAccess con(global_);
 82          con.initFailsafe(this);
 83 
 84          // Creates a connect qos with the user 'joe' and the password 'secret'
 85          ConnectQos qos(global_, "joe", "secret");
 86 
 87          /* To test SOCKET plugin
 88          ServerRef ref("SOCKET", "socket://localhost:7604");
 89          qos.addServerRef(ref);
 90          */
 91          log_.info(ME, string("connecting to xmlBlaster. Connect qos: ") + qos.toXml());
 92 
 93          // connects to xmlBlaster and gives a pointer to this class to tell
 94          // which update method to invoke when callbacks come from the server.
 95          ConnectReturnQos retQos = con.connect(qos, this);  // Login and register for updates
 96          log_.info(ME, "successfully connected to xmlBlaster. Return qos: " + retQos.toXml());
 97 
 98          // subscribe key. By invoking setOid you implicitly choose the 'EXACT' mode.
 99          // If you want to subscribe with XPATH use setQueryString instead.
100          SubscribeKey subKey(global_);
101          subKey.setOid("TestEmptyContent");
102          SubscribeQos subQos(global_);
103          log_.info(ME, string("subscribing to xmlBlaster with key: ") + subKey.toXml() +
104                        " and qos: " + subQos.toXml());
105 
106          SubscribeReturnQos subRetQos = con.subscribe(subKey, subQos);
107          log_.info(ME, string("successfully subscribed to xmlBlaster. Return qos: ") +
108                        subRetQos.toXml());
109 
110          // publish a message with the oid 'TestEmptyContent'
111          PublishQos publishQos(global_);
112          PublishKey publishKey(global_);
113          publishKey.setOid("TestEmptyContent");
114          publishKey.setContentMime("text/plain");
115          MessageUnit msgUnit(publishKey, string(""), publishQos);
116          log_.info(ME, string("publishing to xmlBlaster with message: ") + msgUnit.toXml());
117          PublishReturnQos pubRetQos = con.publish(msgUnit);
118          log_.info(ME, "successfully published to xmlBlaster. Return qos: " + pubRetQos.toXml());
119          try {
120             org::xmlBlaster::util::thread::Thread::sleepSecs(1);
121          }
122          catch(XmlBlasterException e) {
123             log_.error(ME, e.toXml());
124          }
125 
126          // now an update should have come. Its time to erase the message,
127          // otherwise you would get directly an update the next time you connect
128          // to the same xmlBlaster server.
129          // Specify which messages you want to erase. Note that you will get an
130          // update with the status of the UpdateQos set to 'ERASED'.
131          EraseKey eraseKey(global_);
132          eraseKey.setOid("TestEmptyContent");
133          EraseQos eraseQos(global_);
134          log_.info(ME, string("erasing the published message. Key: ") + eraseKey.toXml() +
135                        " qos: " + eraseQos.toXml());
136          vector<EraseReturnQos> eraseRetQos = con.erase(eraseKey, eraseQos);
137          for (size_t i=0; i < eraseRetQos.size(); i++ ) {
138             log_.info(ME, string("successfully erased the message. return qos: ") +
139                           eraseRetQos[i].toXml());
140          }
141 
142          log_.info(ME, "going to sleep for 2 sec and disconnect");
143          org::xmlBlaster::util::thread::Thread::sleep(2000);
144 
145          DisconnectQos disconnectQos(global_);
146          con.disconnect(disconnectQos);
147       }
148       catch (XmlBlasterException e) {
149          log_.error(ME, e.toXml());
150       }
151    }
152 
153    /**
154     * Callbacks from xmlBlaster arrive here. 
155     */
156    string update(const string& /*sessionId*/, UpdateKey& updateKey, const unsigned char* /*content*/,
157                  long /*contentSize*/, UpdateQos& updateQos)
158    {
159       log_.info(ME, "update: key: " + updateKey.toXml());
160       log_.info(ME, "update: qos: " + updateQos.toXml());
161       log_.info(ME, "update: mime: " + updateKey.getContentMime());
162       // if (true) throw XmlBlasterException(USER_UPDATE_ERROR, "TestEmptyContent", "");
163       return "";
164    }
165 
166 };
167 
168 /**
169  * Try
170  * <pre>
171  *   TestEmptyContent -help
172  * </pre>
173  * for usage help
174  */
175 int main(int args, char ** argv)
176 {
177    org::xmlBlaster::util::Object_Lifetime_Manager::init();
178    Global& glob = Global::getInstance();
179    glob.initialize(args, argv);
180 // XmlBlasterAccess::usage();
181 // glob.getLog().info("TestEmptyContent", "Example: TestEmptyContent\n");
182 
183    TestEmptyContent hello(glob);
184    hello.execute();
185    org::xmlBlaster::util::Object_Lifetime_Manager::fini();
186    return 0;
187 }


syntax highlighted by Code2HTML, v. 0.9.1