1 /*------------------------------------------------------------------------------
  2 Name:      XmlBlasterAccess.h
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 ------------------------------------------------------------------------------*/
  6 #ifndef _CLIENT_XMLBLASTERACCESS_H
  7 #define _CLIENT_XMLBLASTERACCESS_H
  8 
  9 #include <util/xmlBlasterDef.h>
 10 #include <util/Global.h>
 11 #include <util/qos/ConnectQos.h>
 12 #include <client/I_ConnectionProblems.h>
 13 #include <client/I_Callback.h>
 14 #include <util/thread/ThreadImpl.h>
 15 #include <util/dispatch/I_PostSendListener.h>
 16 #include <util/ReferenceCounterBase.h>
 17 #include <util/ReferenceHolder.h>
 18 #include <util/XmlBlasterException.h>
 19 #include <util/queue/MsgQueueEntry.h>
 20 #include <util/queue/I_Queue.h>
 21 #include <string>
 22 #include <vector>
 23 #include <map>
 24 
 25 /* The following comment is used by doxygen for the main html page: */
 26 /*! \mainpage Hints about the C++ client library usage.
 27  *
 28  * \section intro_sec The C++ client library
 29  *
 30  * The xmlBlaster C++ client library supports access to xmlBlaster with asynchronous callbacks,
 31  * client side queuing and fail safe reconnect using the CORBA or SOCKET protocol plugin.
 32  * Details about compilation and its usage can be found in the 
 33  * http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.cpp.html requirement.
 34  *
 35  * As a C++ developer your entry point to use is the class org::xmlBlaster::client::XmlBlasterAccess and
 36  * a complete overview demo code is HelloWorld2.cpp
 37  *
 38  * \section c_sec The C client library
 39  * The C client library offers some basic functionality like the SOCKET protocol with
 40  * the struct #XmlBlasterAccessUnparsed or persistent queues with struct #I_Queue.
 41  * These features are heavily used by the C++ library.
 42  * If you need a tiny xmlBlaster access you can choose to use the C client library directly
 43  * without any C++ code.
 44  *
 45  * For details read the
 46  * http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.c.socket.html requirement and the
 47  * http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.c.queue.html requirement.
 48  * and look at the API documentation at http://www.xmlblaster.org/xmlBlaster/doc/doxygen/c/html/index.html
 49  */
 50 
 51 // Note: I_ConnectionProblems.h includes I_ConnectionsHandler.h includes I_XmlBlasterConnection.h
 52 //       which includes all EraseQos, SubscribeKey etc.
 53 //       -> We could try to avoid this by forward declaration, but all cpp files must
 54 //          then include them thereselves.
 55 
 56 // Declare classes without the need to include them in this header file
 57 namespace org { namespace xmlBlaster { namespace util {
 58    class MessageUnit;
 59 }}}
 60 namespace org { namespace xmlBlaster { namespace util { namespace dispatch {
 61    class DispatchManager;
 62    class ConnectionsHandler;
 63 }}}}
 64 namespace org { namespace xmlBlaster { namespace client { namespace protocol {
 65    class I_CallbackServer;
 66 }}}}
 67 
 68 namespace org { namespace xmlBlaster { namespace client {
 69 
 70 /*
 71  * The interface org::xmlBlaster::client::I_CallbackRaw/I_Callback/I_CallbackExtended are enforced by AbstractCallbackExtended
 72  * is for the protocol drivers.
 73  */
 74 typedef std::map<std::string, I_Callback*> CallbackMapType;
 75 typedef std::map<std::string, std::string> StringMap;
 76 
 77 /**
 78  * This is the main entry point for programmers to the C++ client library. 
 79  * 
 80  * Exactly one Global instance and one instance of this are a pair which can't be
 81  * mixed with other instances. 
 82  */
 83 class Dll_Export XmlBlasterAccess : public org::xmlBlaster::client::I_Callback,
 84                                     public org::xmlBlaster::util::ReferenceCounterBase,
 85                                     public org::xmlBlaster::util::dispatch::I_PostSendListener
 86 {
 87 private:
 88    std::string ME;
 89 
 90    org::xmlBlaster::util::Global&   global_;
 91    org::xmlBlaster::util::GlobalRef globalRef_;
 92    org::xmlBlaster::util::I_Log&    log_;
 93    std::string  instanceName_;
 94 
 95    /** The cluster node id (name) to which we want to connect, needed for nicer logging, can be null */
 96    std::string serverNodeId_;
 97    org::xmlBlaster::util::qos::ConnectQosRef connectQos_;
 98    /** The return from connect() */
 99    org::xmlBlaster::util::qos::ConnectReturnQosRef connectReturnQos_;
100    /** The dispatcher framework **/
101    org::xmlBlaster::util::dispatch::DispatchManager* dispatchManager_;
102    /** The callback server */
103    org::xmlBlaster::client::protocol::I_CallbackServer* cbServer_;
104    /** The connection server for this address */
105    org::xmlBlaster::util::dispatch::ConnectionsHandler* connection_;
106 
107    /** Used to callback the clients default update() method (as given on connect()) */
108    org::xmlBlaster::client::I_Callback* updateClient_;
109    
110    /** 
111     * Used to temporary store the fail safe notification address (if any). Once initFailsafe is called, this
112     * pointer is set to NULL again. This way connection_.initFailsafe will be invoked even if the user has
113     * called XmlBlasterAccess::initFailsafe before the connection_ member has been created.
114     */
115    org::xmlBlaster::client::I_ConnectionProblems* connectionProblems_;
116    CallbackMapType subscriptionCallbackMap_;
117    org::xmlBlaster::util::thread::Mutex updateMutex_;
118    /** this makes sure only one invocation is done at a time on this connection. The update method is not blocked by this mutex. The shutdown is blocked */
119    org::xmlBlaster::util::thread::Mutex invocationMutex_;
120    
121    org::xmlBlaster::util::dispatch::I_PostSendListener* postSendListener_; 
122 
123    /**
124     * Private copy constructor, clones are not supported
125     */
126    XmlBlasterAccess(const XmlBlasterAccess &global);
127 
128    /**
129     * Private assignment operator, clones are not supported
130     */
131    XmlBlasterAccess& operator =(const XmlBlasterAccess &);
132 
133    void cleanup(bool doLock);
134    
135 public:
136    /**
137     * Create an xmlBlaster accessor. 
138     * @param glob Your environment handle or null to use the default org::xmlBlaster::util::Global.instance()
139     */
140    XmlBlasterAccess(org::xmlBlaster::util::Global& global);
141 
142    /**
143     * Create an xmlBlaster accessor. 
144     * @param glob Your environment handle or null to use the default org::xmlBlaster::util::Global.instance()
145     */
146    XmlBlasterAccess(org::xmlBlaster::util::GlobalRef global);
147 
148    virtual ~XmlBlasterAccess();
149 
150    /**
151     * Access the global handle of this connection. 
152     * The returned Global lifetime is limited by XmlBlasterAccess lifetime.
153     * @return The global handle containing the connection specific settings. 
154     */
155    org::xmlBlaster::util::Global& getGlobal();
156 
157    /**
158     * Access the client side queue
159     * @return null if not configured
160     */
161    org::xmlBlaster::util::queue::I_Queue* getQueue();
162 
163    /**
164     * Login to xmlBlaster. 
165     * Calling multiple times for changed connections should be possible but is not deeply tested.
166     * @param qos Your configuration desire
167     * @param client If not null callback messages will be routed to client.update()
168     * @return The returned QOS for this connection
169     */
170    org::xmlBlaster::util::qos::ConnectReturnQos connect(const org::xmlBlaster::util::qos::ConnectQos& qos, org::xmlBlaster::client::I_Callback *clientCb);
171 
172    /**
173     * Access the current ConnectQos instance. 
174     * @return A reference on ConnectQos, you don' need to take care on new/delete, just use it.
175     *         Changes made on the instance are seen in the library as well.
176     */
177    org::xmlBlaster::util::qos::ConnectQosRef getConnectQos();
178    org::xmlBlaster::util::qos::ConnectReturnQosRef getConnectReturnQos();
179 
180    /**
181     * Access the previously with connect() registered callback pointer. 
182     * @return Can be NULL
183     */
184    org::xmlBlaster::client::I_Callback* getCallback();
185 
186    /**
187     * Extracts address data from org::xmlBlaster::util::qos::ConnectQos (or adds default if missing)
188     * and instantiate a callback server as specified in org::xmlBlaster::util::qos::ConnectQos
189     */
190    void createDefaultCbServer();
191 
192    /**
193     * Create a new instance of the desired protocol driver like CORBA or RMI driver using the plugin loader. 
194     * @param type  E.g. "IOR" or "SOCKET", if null we use the same protocol as our client access.
195     * @param version The version of the driver, e.g. "1.0"
196     */
197    org::xmlBlaster::client::protocol::I_CallbackServer* initCbServer(const std::string& loginName, const std::string& type, const std::string& version);
198 
199    /**
200     * Register a listener for to receive information about the progress of incoming data. 
201     * Only one listener is supported, the last call overwrites older calls.
202     * @param listener Your listener, pass 0 to unregister.
203     * @return The previously registered listener or 0
204     */
205    org::xmlBlaster::util::dispatch::I_PostSendListener* registerPostSendListener(org::xmlBlaster::util::dispatch::I_PostSendListener *listener);
206 
207    /**
208     * Register a listener for to receive the return Qos of send messages
209     * from the client queue. 
210     * Only one listener is supported, the last call overwrites older calls.
211     * <p/>
212     * Note: The synchronously send returned QoS are not delivered here as they
213     * are returned by the method invocation already:
214     * <pre>
215     * PublishReturnQos pubRetQos = con.publish(msgUnit);
216     * </pre>
217     * @param listener Your listener, pass 0 to unregister.
218     * @return The previously registered listener or 0
219     */
220    org::xmlBlaster::client::protocol::I_ProgressListener* registerProgressListener(org::xmlBlaster::client::protocol::I_ProgressListener *listener);
221 
222    /**
223     * Initializes the little client helper framework for authentication.
224     * <p />
225     * The first goal is a proper loginQoS xml std::string for authentication.
226     * <p />
227     * The second goal is to intercept the messages for encryption (or whatever the
228     * plugin supports).
229     * <p />
230     * See xmlBlaster.properties, for example:
231     * <pre>
232     *   Security.Client.DefaultPlugin=gui,1.0
233     *   Security.Client.Plugin[gui][1.0]=org.xmlBlaster.authentication.plugins.gui.ClientSecurityHelper
234     * </pre>
235     */
236    void initSecuritySettings(const std::string& secMechanism, const std::string& secVersion);
237 
238    /**
239     * Logout from the server. 
240     * <p>
241     * Depending on your arguments, the callback server is removed as well, releasing all CORBA/RMI/XmlRpc threads.
242     * Note that this kills the server ping thread as well (if in failsafe mode)
243     * </p>
244     * @param qos The disconnect quality of service
245     * @param flush Flushed pending publishOneway() messages if any
246     * @param shutdown shutdown lowlevel connection as well (e.g. CORBA connection)
247     * @param shutdownCb shutdown callback server as well (if any was established)
248     * @return <code>true</code> successfully logged out<br />
249     *         <code>false</code> failure on logout
250     * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.disconnect.html">interface.disconnect requirement</a>
251     */
252    bool disconnect(const org::xmlBlaster::util::qos::DisconnectQos& qos, bool flush=true, bool shutdown=true, bool shutdownCb=true);
253 
254    /**
255     * Enforced by I_PostSendListener
256     * @see org::xmlBlaster::util::dispatch::I_PostSendListener
257     */
258    void postSend(const std::vector<org::xmlBlaster::util::queue::EntryType> &entries);
259 
260    /**
261     * Enforced by I_PostSendListener
262     * @see org::xmlBlaster::util::dispatch::I_PostSendListener
263     */
264    bool sendingFailed(const std::vector<org::xmlBlaster::util::queue::EntryType> &entries, const org::xmlBlaster::util::XmlBlasterException &exception);
265 
266    /**
267     * Create a descriptive ME, for logging only
268     * @return e.g. "/node/heron/client/joe/3"
269     */
270    std::string getId();
271 
272    /**
273     * The public session ID of this login session. 
274     */
275    std::string getSessionName();
276 
277    /**
278     * Your changes outside change the internal sessionName. 
279     * @return A reference counted SessionName. 
280     */
281    org::xmlBlaster::util::SessionNameRef getSessionNameRef();
282 
283    /**
284     * Access the login name.
285     * @return your login name or null if you are not logged in
286     */
287    std::string getLoginName();
288 
289    /**
290     * Allows to set the node name for nicer logging.
291     */
292    void setServerNodeId(const std::string& nodeId);
293 
294    /**
295     * The cluster node id (name) to which we want to connect.
296     * <p />
297     * Needed only for nicer logging when running in a cluster.<br />
298     * Is configurable with "-server.node.id golan"
299     * @return e.g. "golan", defaults to "xmlBlaster"
300     */
301    std::string getServerNodeId() const;
302 
303    /**
304     * Put the given message entry into the queue
305     */
306    // org::xmlBlaster::util::queue::MsgQueueEntry queueMessage(const org::xmlBlaster::util::queue::MsgQueueEntry& entry);
307 
308    /**
309     * Put the given message entry into the queue
310     */
311    // std::vector<MsgQueueEntry*> queueMessage(const std::vector<MsgQueueEntry*>& entries);
312 
313    // org::xmlBlaster::client::qos::SubscribeReturnQos
314 //   std::string subscribe(const std::string& xmlKey, const std::string& qos);
315    org::xmlBlaster::client::qos::SubscribeReturnQos subscribe(const org::xmlBlaster::client::key::SubscribeKey& key, const org::xmlBlaster::client::qos::SubscribeQos& qos, I_Callback *callback=0);
316 
317 //   std::vector<org::xmlBlaster::util::MessageUnit> get(const std::string&  xmlKey, const std::string& qos);
318    std::vector<org::xmlBlaster::util::MessageUnit> get(const org::xmlBlaster::client::key::GetKey& key, const org::xmlBlaster::client::qos::GetQos& qos);
319 
320    /**
321     * This method synchronously accesses maxEntries messages from any xmlBlaster server side queue.
322     * <p>
323     * This is a convenience method which uses get() with a specific Qos.
324     * <p>Important note:<br />
325     * Currently you shouldn't use unlimited timeout==-1 as this could
326     * lead to a server side thread leak on client disconnect.
327     * As a workaround please use a loop and a timeout of for example 60000
328     * and just ignore returned arrays of length 0.
329     * </p>
330     * @param oid The identifier like 
331     *            "topic/hello" to access a history queue,
332     *            "client/joe" to access a subject queue or
333     *            "client/joe/session/1"
334     *            to access a callback queue.
335     *            The string must follow the formatting rule of ContextNode.java
336     * @param maxEntries The maximum number of entries to retrieve
337     * @param timeout The time to wait until return. 
338     *                If you choose a negative value it will block until the maxEntries
339     *                has been reached.
340     *                If the value is '0' (i.e. zero) it will not wait and will correspond to a non-blocking get.
341     *                If the value is positive it will block until the specified amount in milliseconds
342     *                has elapsed or when the maxEntries has been reached (whichever comes first). 
343     * @param consumable  Expressed with 'true' or 'false'.
344     *                    If true the entries returned are deleted from the queue
345     * @return An array of messages, is never null but may be an array of length=0 if no message is delivered
346     * @see org.xmlBlaster.util.context.ContextNode
347     * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/engine.qos.queryspec.QueueQuery.html">engine.qos.queryspec.QueueQuery requirement</a>
348     * @see javax.jms.MessageConsumer#receive
349     */
350    std::vector<org::xmlBlaster::util::MessageUnit> receive(std::string oid, int maxEntries, long timeout, bool consumable);
351 
352    std::vector<org::xmlBlaster::util::MessageUnit> request(org::xmlBlaster::util::MessageUnit &msgUnit, long timeout, int maxEntries);
353 
354    /**
355     * @return oid
356     */
357    std::string createTemporaryTopic(long destroyDelay, int historyMaxMsg);
358 
359    // org::xmlBlaster::client::qos::UnSubscribeReturnQos[]
360 //   std::vector<std::string> unSubscribe(const std::string&  xmlKey, const std::string&  qos);
361    std::vector<org::xmlBlaster::client::qos::UnSubscribeReturnQos> unSubscribe(const org::xmlBlaster::client::key::UnSubscribeKey& key, const org::xmlBlaster::client::qos::UnSubscribeQos& qos);
362 
363    // org::xmlBlaster::client::qos::PublishReturnQos
364 //   std::string publish(const org::xmlBlaster::util::MessageUnit& msgUnit);
365    org::xmlBlaster::client::qos::PublishReturnQos publish(const org::xmlBlaster::util::MessageUnit& msgUnit);
366 
367    void publishOneway(const std::vector<org::xmlBlaster::util::MessageUnit>& msgUnitArr);
368 
369 //   std::vector<std::string> publishArr(const std::vector<org::xmlBlaster::util::MessageUnit>& msgUnitArr);
370    std::vector<org::xmlBlaster::client::qos::PublishReturnQos> publishArr(const std::vector<org::xmlBlaster::util::MessageUnit> &msgUnitArr);
371 
372    // org::xmlBlaster::client::qos::EraseReturnQos[]
373 //   std::vector<std::string> erase(const std::string& xmlKey, const std::string& qos);
374    std::vector<org::xmlBlaster::client::qos::EraseReturnQos> erase(const org::xmlBlaster::client::key::EraseKey& key, const org::xmlBlaster::client::qos::EraseQos& qos);
375 
376    /** 
377     * Switch callback dispatcher on/off. 
378     * This is a convenience function (see ConnectQos). It will update the client side
379     * ConnectQos as well so we don't loose the setting on reconnects after server maintenance.
380     * @param isActive true: XmlBlaster server delivers callback messages
381     *        false: XmlBlaster server keeps messages for this client in the callback queue
382     */
383    void setCallbackDispatcherActive(bool isActive);
384 
385    /**
386     * Convenience method to send an administrative command to xmlBlaster. 
387     * If the command contains a '=' it is interpreted as a set() call, else it is used as
388     * a get() call.
389     * @param command for example "client/joe/?dispatcherActive" (a getter) or "client/joe/?dispatcherActive=false" (a setter).
390     *        The "__cmd:" is added by us
391     *        To enforce a getter or setter you can write "get client/joe/?dispatcherActive" or
392     *        "set client/joe/?dispatcherActive=false"
393     * @param  publishQosP optional Qos, e.g. to set persistance for set command 
394     * @return When setting a value you get the returned state, else the retrieved data
395     * @throws XmlBlasterException on problems
396     */
397    std::string sendAdministrativeCommand(const std::string &command, org::xmlBlaster::client::qos::PublishQos *publishQosP = (org::xmlBlaster::client::qos::PublishQos *)0);
398 
399    /**
400     * This is the callback method invoked from xmlBlaster
401     * delivering us a new asynchronous message.
402     * @see org.xmlBlaster.client.I_Callback#update(String, org::xmlBlaster::client::key::UpdateKey, byte[], org::xmlBlaster::client::qos::UpdateQos)
403     */
404    std::string update(const std::string &sessionId, org::xmlBlaster::client::key::UpdateKey &updateKey, const unsigned char *content, long contentSize, org::xmlBlaster::client::qos::UpdateQos &updateQos);
405 
406    /**
407     * Command line usage.
408     */
409    static std::string usage();
410 
411    /**
412     * used to initialize the failsafe behaviour of the client.
413     * If connectionProblems is not NULL, then the passed object will be notified for connection lost
414     * and reconnected events.
415     */
416     void initFailsafe(I_ConnectionProblems* connectionProblems=NULL);
417 
418     std::string ping();
419 
420    /**
421     * Flushes all entries in the queue, i.e. the entries of the queue are sent to xmlBlaster.
422     * If the queue is empty or NULL, then 0 is returned. If the state is in POLLING or DEAD, then -1 is
423     * returned.. This method blocks until all entries in the queue have been sent.
424     */
425    long flushQueue();
426 
427    /**
428     * Same as isAlive() || isPolling()
429     * @return true if connect() call was successful, even if we are polling
430     */
431    bool isConnected() const;
432 
433    /**
434     * Check if we are 'online'. 
435     * @return true if connected with server and ready
436     */
437    bool isAlive() const;
438 
439    /**
440     * Check if we are polling for the server. 
441     * @return true if polling for the server
442     */
443    bool isPolling() const;
444 
445    /**
446     * Check if this handle is still useful
447     * @return true if we have given up
448     */
449    bool isDead() const;
450 
451    /**
452     * Get connection status string for logging. 
453     * @return "ALIVE" | "POLLING" | "DEAD"
454     */
455    std::string getStatusString() const;
456 
457    /**
458     * Disconnect and cleanup client side resources but keep our login session on server side. 
459     * <p>
460     * As the login session on server side stays alive, all subscriptions stay valid
461     * and callback messages are queued by the server.
462     * If you connect at a later time the server sends us all queued messages.
463     * </p>
464     * <p>
465     * Once you have called this method the XmlBlasterAccess instance
466     * becomes invalid and any further invocation results in 
467     * an XmlBlasterException to be thrown.
468     * </p>
469     * @param map The properties to pass while leaving server.
470     *        Currently this argument has no effect.
471     */
472    void leaveServer(const StringMap &map);
473 };
474 
475 typedef org::xmlBlaster::util::ReferenceHolder<org::xmlBlaster::client::XmlBlasterAccess> XmlBlasterAccessRef;
476 
477 }}} // namespaces
478 
479 #endif


syntax highlighted by Code2HTML, v. 0.9.1