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