1 using System;
2 using System.Text ;
3 //using System.Diagnostics ;
4 using System.Xml ;
5 using System.Collections ;
6 using System.Collections.Specialized ; // for ListDictionary
7 using System.Net ; // for WebException
8 using System.Runtime.Remoting ;
9 using System.Runtime.Remoting.Channels ;
10 using System.Runtime.Remoting.Channels.Http ;
11
12 using SimpleLogLib ;
13 using CookComputing.XmlRpc ;
14
15 namespace XmlBlasterLib
16 {
17 /// <summary>
18 /// Implémentation du client XmlBlaster
19 /// </summary>
20 public class XmlBlasterClient
21 {
22 IXmlBlasterClient xmlBlasterClientProxy ;
23 XmlRpcClientProtocol xmlBlasterClientProtocol ;
24
25 // TODO: Ajouter un identifiant de thread ou autre
26 SimpleLog logger = SimpleLogLib.SimpleLogManager.GetLog("XmlBlasterClient", LogLevel.Debug );
27
28 /// <summary>
29 /// A utiliser par les qos
30 /// </summary>
31 internal static SimpleLog loggerQos = SimpleLogLib.SimpleLogManager.GetLog("XmlBlasterQos", LogLevel.Debug );
32
33 //string uniqueId ;
34 string sessionId ;
35 public string SessionId
36 {
37 get { return this.sessionId ; }
38 }
39
40
41 Uri callbackServerUri ;
42 public string Url
43 {
44 get { return xmlBlasterClientProtocol.Url ; }
45 set { xmlBlasterClientProtocol.Url = value ; }
46 }
47
48 HttpChannel httpChannel ;
49
50 public XmlBlasterClient()
51 {
52 //
53 // Client
54 //
55
56 xmlBlasterClientProxy = (IXmlBlasterClient) XmlRpcProxyGen.Create(typeof(IXmlBlasterClient)) ;
57 xmlBlasterClientProtocol = (XmlRpcClientProtocol) xmlBlasterClientProxy ;
58
59 //
60 // Callback Server
61 //
62
63 // On peut le faire depuis un fichier
64 //RemotingConfiguration.Configure("xmlrpc.exe.config");
65
66 // Ou bien à la mano
67 try
68 {
69 //int port = FindFreeHttpPort( 9090 ) ;
70 //logger.Debug( "FindFreeHttpPort() found port "+port );
71 // port = 0 pour que le système assigne automatiquement un port non-utilisé.
72 int port = 0 ;
73
74 ListDictionary channelProperties = new ListDictionary();
75 channelProperties.Add( "port", port );
76
77 httpChannel = new HttpChannel(
78 channelProperties,
79 new CookComputing.XmlRpc.XmlRpcClientFormatterSinkProvider(),
80 new CookComputing.XmlRpc.XmlRpcServerFormatterSinkProvider(null,null)
81 //new SoapClientFormatterSinkProvider(),
82 //new SoapServerFormatterSinkProvider()
83 );
84 }
85 catch( Exception ex )
86 {
87 // Listener config failed : Une seule utilisation de chaque adresse de socket (protocole/adresse réseau/port) est habituellement autorisée
88 XmlBlasterException.HandleException( new Exception("XmlBlaster callback server, Listener config failed.", ex ) );
89 }
90
91 try
92 {
93 ChannelServices.RegisterChannel( httpChannel );
94 }
95 catch( System.Runtime.Remoting.RemotingException )
96 {
97 // Pas grave: The channel has already been registered.
98 }
99 catch( Exception ex )
100 {
101 XmlBlasterException.HandleException( new Exception("XmlBlasterCallback server, failed to RegisterChannel.", ex ) );
102 }
103
104 RemotingConfiguration.RegisterWellKnownServiceType(
105 typeof(XmlBlasterCallback),
106 "XmlBlasterCallback",
107 WellKnownObjectMode.Singleton
108 );
109
110
111 // Comme on a pas indiqué de port, celui-ci a été assigné automatiquement.
112 // Il nous faut donc retrouver l'url afin de pouvoir la transmettre dans le Qos de connexion.
113
114 string[] urls = httpChannel.GetUrlsForUri("XmlBlasterCallback");
115 foreach (string url in urls)
116 logger.Debug("XmlBlasterCallback url: {0}", url);
117 //url: http://192.168.0.151:4808/XmlBlasterCallback
118 if( urls.Length != 1 )
119 {
120 XmlBlasterException.HandleException( new Exception("XmlBlasterCallback server, failed to retreive url." ) );
121 }
122 this.callbackServerUri = new Uri( urls[ 0 ] );
123
124 }
125
126
127 public void Connect( string url, string username, string password )
128 {
129 logger.Debug( "XmlBlaster.Connect()" );
130 logger.Debug( "XmlBlaster.Connect() url:["+url+"]" );
131
132 // reset
133 this.sessionId = null ;
134
135 this.Url = url ; // Set xml-rpc server url
136
137 try
138 {
139 // try connect (login)
140 // to construct authentification data
141 QosConnect qos = new QosConnect( username,password,this.callbackServerUri.ToString() );
142
143 XmlBlasterCallback.pingInterval = qos.PingInterval ;
144
145 string result = xmlBlasterClientProxy.Connect( qos.ToString() );
146
147 QosConnectResult qosConnectResult = new QosConnectResult( result );
148
149 this.sessionId = qosConnectResult.SessionId ;
150
151 // TODO: sessionId should be secret !
152 // do something better ;o)
153 //Random rnd = new Random( );
154 //this.uniqueId = rnd.NextDouble().ToString() ;
155 }
156 catch( Exception ex )
157 {
158 // reset
159 this.sessionId = null ;
160
161 XmlBlasterException.HandleException(ex);
162 }
163 }
164
165 public void Disconnect()
166 {
167 string me="Disconnect()";
168 logger.Debug(me);
169
170 // construct authentification data
171 string qos = @"
172 <qos>
173 <deleteSubjectQueue>true</deleteSubjectQueue>
174 <clearSessions>true</clearSessions>
175 </qos>";
176
177 try
178 {
179 xmlBlasterClientProxy.Disconnect( this.sessionId, qos );
180 }
181 catch( Exception ex )
182 {
183 //XmlBlasterException.HandleException(ex);
184 logger.Error( "{0} Failed. Ex: {1}.", me, ex.Message );
185 }
186 }
187
188
189 /// <summary>
190 /// Make a subscribtion to messages that match the query.
191 /// </summary>
192 /// <param name="query">the query to subscribe to</param>
193 /// <param name="xpath">is it an xpath query</param>
194 /// <returns>the Subscribtion ID or null if failed</returns>
195 public string Subscribe( string query, bool xpath )
196 {
197 string me="Subscribe()";
198 logger.Debug(me);
199
200 string key ;
201 if( xpath )
202 {
203 key = "<key oid='' queryType='XPATH'>"+query+"</key>";
204 }
205 else
206 {
207 key = "<key oid=\""+query+"\" />\n" ;
208 }
209
210 StringBuilder qos = new StringBuilder();
211 qos.Append("<qos>");
212 //qos.Append("<initialUpdate>false</initialUpdate>");
213 qos.Append("<local>false</local>");
214 qos.Append("</qos>");
215
216 return this.Subscribe( key, qos.ToString() );
217 }
218
219 public string Subscribe( string key, string qos )
220 {
221 string me="Subscribe()";
222 logger.Debug(me);
223
224 /* key exemples:
225 * exact :
226 * <key oid='MyMessage' />
227 * xpath :
228 * <key oid='' queryType='XPATH'> /xmlBlaster/key[starts-with(@oid,'radar.')] </key>
229 */
230 try
231 {
232 string result = xmlBlasterClientProxy.Subscribe( this.sessionId, key, qos.ToString() );
233
234 XmlBlasterLib.QosSubscribeResult qsr = new QosSubscribeResult( result );
235
236 return qsr.SubscribeId ;
237 }
238 catch( Exception ex )
239 {
240 XmlBlasterException.HandleException(ex);
241 return null ;
242 }
243 }
244
245
246 public bool Unsubscribe( string subscribtionId )
247 {
248 string me="Unsubscribe()";
249 logger.Debug( me );
250
251 try
252 {
253 string key = "<key oid=\""+subscribtionId+"\" />\n" ;
254 QosUnsubscribe qos = new QosUnsubscribe();
255
256 string[] results = xmlBlasterClientProxy.Unsubscribe( this.sessionId, key, qos.ToString() );
257
258 logger.Debug( "{0} results count={1}", me, results.Length );
259 foreach( string s in results )
260 {
261 XmlBlasterLib.QosUnsubscribeResult qur = new QosUnsubscribeResult( s );
262 logger.Debug( qur.ToString() );
263 }
264 }
265 catch( Exception ex )
266 {
267 XmlBlasterException.HandleException(ex);
268 return false ;
269 }
270
271 return true ;
272 }
273
274
275 public bool Publish( string topic, string xmlContent )
276 {
277 string me="Publish()";
278 logger.Debug(me);
279
280 string key = "<key oid=\""+topic+"\" contentMime=\"text/xml\" >\n" ;
281 //key += "<sender>"+uniqueId+"</sender>\n" ;
282 key += "</key>" ;
283
284 string qos = "<qos />" ;
285
286 return this.Publish( key, qos, xmlContent );
287 }
288
289 public bool Publish( string key, string qos, string xmlContent )
290 {
291 string me="Publish";
292 logger.Debug(me);
293 try
294 {
295 string result = xmlBlasterClientProxy.Publish( this.sessionId, key, xmlContent, qos );
296
297 // TODO: Publish Qos Result
298 return true ;
299 }
300 catch( Exception ex )
301 {
302 XmlBlasterException.HandleException(ex);
303 }
304 return false ;
305 }
306
307
308 public MessageUnit[] Get( string query, bool xpath )
309 {
310 string me="Get()";
311 logger.Debug(me);
312
313 string key ;
314 if( xpath )
315 {
316 // exemple: <key oid='' queryType='XPATH'> /xmlBlaster/key[starts-with(@oid,'radar.')] </key>
317 key = "<key oid='' queryType='XPATH'>"+query+"</key>";
318 }
319 else
320 {
321 key = "<key oid=\""+query+"\" />\n" ;
322 }
323 string qos = "<qos><content>true</content></qos>";
324
325 return this.Get( key, qos );
326 }
327
328 public MessageUnit[] Get( string key, string qos )
329 {
330 string me="Get()";
331 logger.Debug(me);
332 MessageUnit[] msgs = null ;
333 try
334 {
335 object[][] results = xmlBlasterClientProxy.Get( this.sessionId, key, qos );
336
337 int nbrMsgs = results.Length ;
338 logger.Debug("{0} nbrMsgs= {1}", me, nbrMsgs);
339 msgs = new MessageUnit[nbrMsgs];
340 for( int i=0; i<nbrMsgs; i++ )
341 {
342 try
343 {
344 msgs[i] = new MessageUnit( (string) results[i][0], (byte[]) results[i][1], (string) results[i][2] );
345 }
346 catch(Exception ex)
347 {
348 XmlBlasterException.HandleException( new Exception( me+" received a malformed message. Ex: "+ex.Message, ex ) );
349 }
350 }
351
352 }
353 catch( Exception ex )
354 {
355 XmlBlasterException.HandleException(ex);
356 }
357 return msgs ;
358 }
359
360
361 public bool Erase( string query, bool xpath )
362 {
363 string me="Erase()";
364 logger.Debug(me);
365
366 string key ;
367 if( xpath )
368 {
369 // exemple: <key oid='' queryType='XPATH'> /xmlBlaster/key[starts-with(@oid,'radar.')] </key>
370 key = "<key oid='' queryType='XPATH'>"+query+"</key>";
371 }
372 else
373 {
374 key = "<key oid=\""+query+"\" />\n" ;
375 }
376
377 string qos = "<qos />" ;
378
379 return this.Erase( key, qos );
380 }
381
382 public bool Erase( string key, string qos )
383 {
384 string me="Erase()";
385 logger.Debug(me);
386 try
387 {
388 string[] results = xmlBlasterClientProxy.Erase( this.sessionId, key, qos );
389
390 if( logger.IsDebug )
391 {
392 logger.Debug( "{0} Results:", me);
393 foreach( string s in results )
394 {
395 logger.Debug( "\tEraseQosResult: {0}", s);
396 }
397 }
398
399 // TODO: Erase Qos Result
400 return true ;
401 }
402 catch( Exception ex )
403 {
404 XmlBlasterException.HandleException(ex);
405 }
406 return false ;
407 }
408
409 /// <summary>
410 /// L'interface IXmlBlasterClient représente les accès au serveur XmlBlaster
411 /// via XmlRpc (CookComputing.XmlRpc).
412 /// @see XmlBlasterClient.xmlBlasterClientProxy
413 /// </summary>
414 internal interface IXmlBlasterClient
415 {
416 [XmlRpcMethod("authenticate.connect")]
417 string Connect( string connectQos );
418
419 [XmlRpcMethod("authenticate.disconnect")]
420 void Disconnect( string sessiondId, string qos );
421
422 [XmlRpcMethod("xmlBlaster.publish")]
423 string Publish( string sessiondId, string key, string xmlMessage, string qos );
424
425 [XmlRpcMethod("xmlBlaster.subscribe")]
426 string Subscribe( string sessiondId, string key, string qos );
427
428 [XmlRpcMethod("xmlBlaster.unSubscribe")]
429 string[] Unsubscribe( string sessiondId, string key, string qos );
430
431 [XmlRpcMethod("xmlBlaster.get")]
432 object[][] Get( string sessiondId, string key, string qos );
433
434 [XmlRpcMethod("xmlBlaster.erase")]
435 string[] Erase( string sessiondId, string key, string qos );
436
437 }
438
439 }
440
441 /// <summary>
442 /// La class XmlBlasterCallback représente les méthodes que nous exposons à l'extérieur via XmlRpc.
443 /// C'est le serveur XmlBlaster qui appellera ces méthodes.
444 /// Nous lui avons fourni notre adresse d'écoute au moment du Connect().
445 /// </summary>
446 public class XmlBlasterCallback : MarshalByRefObject
447 {
448 // TODO: Ajouter un identifiant de thread ou autre
449 static SimpleLog logger = SimpleLogLib.SimpleLogManager.GetLog("XmlBlasterCallback", LogLevel.Debug );
450
451 //public delegate void MessageArrivedDelegate( string key, string xmlMessage, string sender, string subscribtionId );
452 public delegate void MessageArrivedDelegate( XmlBlasterLib.MessageUnit msgUnit );
453 public static /*event*/ MessageArrivedDelegate messageArrived ;
454
455 //public delegate void PingArrivedDelegate();
456 //public static PingArrivedDelegate pingArrived ;
457
458 internal static int pingLastTime = 0 ;
459 internal static int pingInterval = 0 ;
460
461 public enum XmlBlasterServerHealthStatus
462 {
463 VERYGOOD, GOOD, BAD, VERY_BAD, DEAD
464 }
465
466 public static XmlBlasterServerHealthStatus XmlBlasterServerHealth
467 {
468 get
469 {
470 if( pingLastTime == 0 )
471 {
472 return XmlBlasterServerHealthStatus.DEAD ;
473 }
474 int lap = Environment.TickCount - pingLastTime ;
475 if( lap <= pingInterval/2 )
476 {
477 return XmlBlasterServerHealthStatus.VERYGOOD ;
478 }
479 else if( lap <= pingInterval )
480 {
481 return XmlBlasterServerHealthStatus.GOOD ;
482 }
483 else if( lap <= (pingInterval+pingInterval/2) )
484 {
485 return XmlBlasterServerHealthStatus.BAD ;
486 }
487 else if( lap <= (pingInterval*2) )
488 {
489 return XmlBlasterServerHealthStatus.VERY_BAD ;
490 }
491 return XmlBlasterServerHealthStatus.DEAD ;
492 }
493 }
494
495
496 [XmlRpcMethod("ping")]
497 public string Ping( string msg )
498 {
499 // XML-RPC message :
500 // [12-Nov-2005 11:18:15] string(144) "<?xml version="1.0" encoding="ISO-8859-1"?><methodCall><methodName>ping</methodName><params><param><value></value></param></params></methodCall>"
501
502 logger.Debug( "Ping()" );
503
504 //logger.Debug( "\t msg: ", msg );
505
506 // refresh last server heartbeat
507 pingLastTime = Environment.TickCount ;
508
509 //if( XmlBlasterCallback.pingArrived != null )
510 //{
511 // //XmlBlasterCallback.pingArrived();
512 // // Asynchronously invoke the method.
513 // IAsyncResult ar = XmlBlasterCallback.pingArrived.BeginInvoke( null, null );
514 //}
515
516 return "<qos><state>OK</state></qos>" ;
517 }
518
519
520 [XmlRpcMethod("update")]
521 public string Update( string cbSessionId, string key, System.Byte[] content, string qos )
522 {
523 string me="Update()";
524 logger.Debug(me);
525
526 // refresh last server heartbeat
527 pingLastTime = Environment.TickCount ;
528
529 // Note (from requirements/interface.update.html)
530 //
531 // Be prepared to receive all sorts of messages on update,
532 // like normal messages or internal xmlBlaster messages or administrative command messages.
533 //
534
535 /*
536 XmlBlasterCallback.Update() cbSessionId:
537 unknown
538 XmlBlasterCallback.Update() key:
539 <key oid='__sys__UserList'>
540 <__sys__internal/>
541 </key>
542 XmlBlasterCallback.Update() qos:
543 <qos>
544 <sender>/node/xmlBlaster_127_0_0_1_3412/client/__RequestBroker_internal[xmlBlaster_127_0_0_1_3412]/1</sender>
545 <subscribe id='__subId:xmlBlaster_127_0_0_1_3412-XPATH1132587264334000000'/>
546 <expiration lifeTime='-1'/>
547 <rcvTimestamp nanos='1132587264254000001'/>
548 <queue index='0' size='3'/>
549 <forceUpdate/>
550 <isPublish/>
551 </qos>
552 */
553
554 /*
555 logger.Debug( "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" );
556 logger.Debug( "{0} cbSessionId: {1}", me, cbSessionId ); // SecretSessionId, so should be 'Unknow'.
557 logger.Debug( "{0} key:\n{1}", me, key );
558 logger.Debug( "{0} qos:\n{1}", me, qos );
559 logger.Debug( "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" );
560 */
561
562
563 if( XmlBlasterCallback.messageArrived != null )
564 {
565 //string xml = Encoding.Default.GetString( msg );
566 //XmlBlasterCallback.messageArrived( key, xml, qosUpdate.Sender, qosUpdate.SubscribeId );
567 MessageUnit msg ;
568 try
569 {
570 msg = new MessageUnit( key, content, qos );
571
572 try
573 {
574 //XmlBlasterCallback.messageArrived( msg );
575
576 //logger.Debug( "{0} InvocationList: {1}", me, XmlBlasterCallback.messageArrived.GetInvocationList().Length );
577 // Asynchronously invoke the method.
578 IAsyncResult ar = XmlBlasterCallback.messageArrived.BeginInvoke( msg, null, null );
579 //XmlBlasterCallback.messageArrived.EndInvoke(ar);
580 }
581 catch( Exception ex )
582 {
583 logger.Error( "{0} Failed to fire messageArrived. Ex: {1}", me, ex.Message );
584 }
585 }
586 catch( Exception ex )
587 {
588 logger.Error( "{0} Received a malformed message. Ex: {1}", me, ex.Message );
589 }
590 }
591
592 return "<qos><state>OK</state></qos>";
593 }
594 }
595
596
597 /// <summary>
598 /// Transforme toutes les exceptions catchée dans le client XmlBlaster
599 /// en exception du type XmlBlasterException afin de clarifier les erreurs.
600 /// Le code utilisateur de XmlBlasterClient ne verra que des exceptions de ce type.
601 /// </summary>
602 public class XmlBlasterException : Exception
603 {
604 const string exceptionMessage = "XmlBlaster operation has failed.";
605
606 internal XmlBlasterException()
607 : base( exceptionMessage )
608 {
609 }
610
611 internal XmlBlasterException( string auxMessage )
612 : base( String.Format( "{0} - {1}", exceptionMessage, auxMessage ) )
613 {
614 }
615
616 internal XmlBlasterException( string auxMessage, Exception inner )
617 : base( String.Format( "{0} - {1}", exceptionMessage, auxMessage ), inner )
618 {
619 }
620
621 internal XmlBlasterException( Exception inner )
622 : base( String.Format( "{0} - {1}", exceptionMessage, inner.Message ), inner )
623 {
624 }
625
626 protected static SimpleLog logger = SimpleLogLib.SimpleLogManager.GetLog("XmlBlasterException");
627
628 /// <summary>
629 /// Pour transformer toutes les exceptions en XmlBlasterException
630 /// </summary>
631 /// <param name="ex"></param>
632 internal static void HandleException( Exception ex )
633 {
634 logger.Error( "HandleException() {0}", ex.Message );
635 logger.Error( "HandleException() {0}", ex.StackTrace );
636
637 //string msgBoxTitle = "Error" ;
638 try
639 {
640 throw ex;
641 }
642 catch(XmlRpcFaultException fex)
643 {
644 //MessageBox.Show("Fault Response: " + fex.FaultCode + " "
645 // + fex.FaultString, msgBoxTitle,
646 // MessageBoxButtons.OK, MessageBoxIcon.Error);
647 throw new XmlBlasterException( fex.FaultString, fex ) ;
648 }
649 catch(WebException webEx)
650 {
651 //MessageBox.Show("WebException: " + webEx.Message, msgBoxTitle,
652 // MessageBoxButtons.OK, MessageBoxIcon.Error);
653 if (webEx.Response != null)
654 webEx.Response.Close();
655 throw new XmlBlasterException( webEx ) ;
656 }
657 catch(XmlRpcServerException xmlRpcEx)
658 {
659 //MessageBox.Show("XmlRpcServerException: " + xmlRpcEx.Message,
660 // msgBoxTitle,
661 // MessageBoxButtons.OK, MessageBoxIcon.Error);
662 throw new XmlBlasterException( xmlRpcEx ) ;
663 }
664 catch(Exception defEx)
665 {
666 //MessageBox.Show("Exception: " + defEx.Message, msgBoxTitle,
667 // MessageBoxButtons.OK, MessageBoxIcon.Error);
668 throw new XmlBlasterException( defEx ) ;
669 }
670 }
671
672 }
673
674
675 public class MessageUnit
676 {
677 static SimpleLog logger = SimpleLogLib.SimpleLogManager.GetLog("XmlBlaster.MessageUnit", LogLevel.Debug );
678
679 //string xml = Encoding.Default.GetString( msg );
680
681 public MessageUnit( string key, byte[] content, string qos )
682 {
683 string me="MessageUnit()";
684 logger.Debug("{0} message key: {1}", me, key );
685
686 //this.key = new MessageKey( key );
687 this.keyStr = key ;
688 this.contentBytes = content ;
689 this.qos = new QosMessageUnit( qos );
690 }
691
692
693 QosMessageUnit qos ;
694 public QosMessageUnit Qos
695 {
696 get
697 {
698 return this.qos ;
699 }
700 }
701
702
703 byte[] contentBytes ;
704 string contentStr ;
705 public string ContentStr
706 {
707 get
708 {
709 if( this.contentStr == null )
710 {
711 this.contentStr = Encoding.Default.GetString( this.contentBytes );
712 }
713 return this.contentStr ;
714 }
715 }
716 public byte[] ContentBytes
717 {
718 get
719 {
720 return this.contentBytes ;
721 }
722 }
723
724
725 string keyStr ;
726 XmlDocument keyXmlDoc ;
727 public string KeyStr
728 {
729 get
730 {
731 return this.keyStr ;
732 }
733 }
734 public string KeyOid
735 {
736 get
737 {
738 //return this.key.Oid ;
739 if( this.keyStr != null )
740 {
741 try
742 {
743 if( this.keyXmlDoc == null )
744 {
745 this.keyXmlDoc = new XmlDocument();
746 this.keyXmlDoc.LoadXml( this.keyStr );
747 }
748 //XmlNode node = this.keyXmlDoc.DocumentElement.SelectSingleNode("key");
749 //return (string) node.Attributes[ "oid" ].Value ;
750 return this.keyXmlDoc.DocumentElement.Attributes[ "oid" ].Value ;
751 }
752 catch(Exception ex )
753 {
754 logger.Error( "MessageUnit.KeyOid() Failed. Ex: "+ex.Message );
755 }
756 return null ;
757 }
758 return null ;
759 }
760 }
761
762 public string KeyQuery
763 {
764 get
765 {
766 if( this.keyStr != null )
767 {
768 try
769 {
770 if( this.keyXmlDoc == null )
771 {
772 this.keyXmlDoc = new XmlDocument();
773 this.keyXmlDoc.LoadXml( this.keyStr );
774 }
775 return this.keyXmlDoc.DocumentElement.InnerText.ToString();
776 }
777 catch(Exception ex )
778 {
779 logger.Error( "MessageUnit.KeyOid() Failed. Ex: "+ex.Message );
780 }
781 return null ;
782 }
783 return null ;
784 }
785 }
786
787 }
788
789 #region Les Qos (QosConnect, QosUpdate, ...
790
791 public class QosConnect
792 {
793 const int DEFAULT_PINGINTERVAL = 5000 ;
794
795 static SimpleLog logger = XmlBlasterClient.loggerQos ;
796
797
798 public string securityService_type = "htpasswd" ;
799 public string securityService_version = "1.0" ;
800 public string username ;
801 public string password ;
802 public string callbackUri = null ;
803
804 Hashtable options ;
805
806 public int PingInterval
807 {
808 get
809 {
810 try{ return Convert.ToInt32( this.options["pingInterval"] ); }catch{}
811 return 0 ;
812 }
813 }
814
815 internal QosConnect()
816 {
817 // Setting default options
818 options = new Hashtable();
819 options.Add( "pingInterval", DEFAULT_PINGINTERVAL );
820 }
821 public QosConnect( string username, string password )
822 : this()
823 {
824 this.username = username ;
825 this.password = password ;
826 this.callbackUri = null ;
827 }
828 public QosConnect( string username, string password, string callbackUri )
829 : this()
830 {
831 this.username = username ;
832 this.password = password ;
833 this.callbackUri = callbackUri ;
834 }
835
836 public QosConnect( string username, string password, string callbackUri, Hashtable options )
837 : this()
838 {
839 this.username = username ;
840 this.password = password ;
841 this.callbackUri = callbackUri ;
842
843 // Options Merge: user overload or add options
844 try
845 {
846 foreach( object key in options )
847 {
848 if( this.options.ContainsKey( key ) )
849 {
850 this.options[ key ] = options[ key ];
851 }
852 else
853 {
854 this.options.Add( key, options[ key ] );
855 }
856 }
857 }
858 catch( Exception ex )
859 {
860 logger.Warn("Failed to understand options. Ex: "+ex.Message );
861 }
862 }
863
864 public override string ToString()
865 {
866 string me="ToString()";
867
868 StringBuilder sb = new StringBuilder( 255 );
869
870 sb.Append( "<qos>\n" );
871
872 sb.Append( " <securityService type=\""+this.securityService_type + "\" version=\""+this.securityService_version+"\">\n" );
873 sb.Append( " <user>"+ this.username +"</user>\n" );
874 sb.Append( " <passwd>"+ this.password +"</passwd>\n" );
875 sb.Append( " </securityService>\n" );
876
877 if( callbackUri != null )
878 {
879 sb.Append( "<callback type=\"XMLRPC\" retries=\"2\" delay=\"2000\" pingInterval=\""+this.options["pingInterval"].ToString()+"\" >" );
880 //sb.Append( "http://192.168.0.151:9090/RPC2" );
881 //sb.Append( "http://127.0.0.1:9090/RPC2" );
882
883 //sb.Append( "http://127.0.0.1:8090/EssaisDivers/xmlBLaster.essais/demo.php/callback.php" );
884 //sb.Append( "http://127.0.0.1:9090/XmlBlasterCallback" );
885 sb.Append( this.callbackUri );
886
887 sb.Append( "</callback>\n" );
888 }
889
890 // Subscribe Qos ?
891 //sb.Append( "<local>false</local>\n" );
892
893 sb.Append( "</qos>\n" );
894
895 string s = sb.ToString() ;
896 logger.Debug("{0} XML:\n{1}", me, s );
897 return s ;
898 }
899
900 }
901
902 public class QosConnectResult
903 {
904 static SimpleLog logger = XmlBlasterClient.loggerQos ;
905
906 /*
907 <qos>
908 <securityService type="htpasswd" version="1.0">
909 <user>guest</user>
910 <passwd>guest</passwd>
911 </securityService>
912 <instanceId>/xmlBlaster/node/xmlBlaster_192_168_0_151_3412/instanceId/1131719045135</instanceId>
913 <session name='/node/xmlBlaster_192_168_0_151_3412/client/guest/-4'
914 timeout='86400000' maxSessions='10' clearSessions='false' reconnectSameClientOnly='false'
915 sessionId='sessionId:192.168.0.151-null-1131720478106-2108614840-5'
916 />
917 <queue relating='connection' maxEntries='10000000' maxEntriesCache='1000'>
918 <address type='IOR' dispatchPlugin='undef'>
919 </address>
920 </queue>
921 <queue relating='subject'/>
922 <queue relating='callback' maxEntries='1000' maxEntriesCache='1000'/>
923 </qos>
924 */
925 protected XmlDocument xmlDoc ;
926 public QosConnectResult( string xml )
927 {
928 logger.Debug("Create with XML:\n{0}", xml );
929
930 this.xmlDoc = new XmlDocument();
931 xmlDoc.LoadXml( xml );
932 }
933
934 public string SessionId
935 {
936 get
937 {
938 string s = null ;
939 try
940 {
941 XmlNode root = xmlDoc.DocumentElement ;
942 XmlNode node ;
943 //node = root.SelectSingleNode("descendant::book[author/last-name='Austen']");
944 node = root.SelectSingleNode("session");
945 s = node.Attributes[ "sessionId" ].Value ;
946 }
947 catch( Exception ex )
948 {
949 logger.Error("Failed to retreive SessionId. Ex: {0}", ex.Message );
950 }
951 logger.Debug("sessionId : {0}", s );
952 return s ;
953 }
954 }
955 }
956
957 public class QosSubscribeResult : XmlDocument
958 {
959 static SimpleLog logger = XmlBlasterClient.loggerQos ;
960
961 /*
962 <qos>
963 <subscribe id='__subId:xmlBlaster_127_0_0_1_3412-XPATH1132586655128000000'/>
964 <isSubscribe/>
965 </qos>
966 */
967 protected string subscribeId ;
968 public QosSubscribeResult( string xml )
969 {
970 logger.Debug("Create with XML:\n{0}", xml );
971
972 this.LoadXml( xml );
973 }
974 public string SubscribeId
975 {
976 get
977 {
978 if( subscribeId == null )
979 {
980 XmlNode root = this.DocumentElement ;
981 XmlNode node = root.SelectSingleNode("subscribe");
982 this.subscribeId = node.Attributes[ "id" ].Value ;
983 }
984 logger.Debug("QosSubscribeResult.SubscribeId : "+this.subscribeId);
985 return this.subscribeId ;
986 }
987 }
988 }
989
990 public class QosUnsubscribe : XmlDocument
991 {
992 static SimpleLog logger = XmlBlasterClient.loggerQos ;
993
994 public QosUnsubscribe()
995 {
996 string xml = "<qos/>";
997 logger.Debug("Create with XML:\n{0}", xml );
998 this.LoadXml( xml );
999 }
1000 public override string ToString()
1001 {
1002 return base.OuterXml ;
1003 }
1004 }
1005
1006 public class QosUnsubscribeResult : XmlDocument
1007 {
1008 static SimpleLog logger = XmlBlasterClient.loggerQos ;
1009
1010 public QosUnsubscribeResult( string xml )
1011 {
1012 logger.Debug("Create with XML:\n{0}", xml );
1013 this.LoadXml( xml );
1014 }
1015 public override string ToString()
1016 {
1017 return base.OuterXml ;
1018 }
1019 }
1020
1021 public class QosUpdate : XmlDocument
1022 {
1023 static SimpleLog logger = XmlBlasterClient.loggerQos ;
1024 /*
1025 XmlBlasterCallback.Update() cbSessionId:
1026 unknown
1027 XmlBlasterCallback.Update() key:
1028 <key oid='__sys__UserList'>
1029 <__sys__internal/>
1030 </key>
1031 XmlBlasterCallback.Update() qos:
1032 <qos>
1033 <sender>/node/xmlBlaster_127_0_0_1_3412/client/__RequestBroker_internal[xmlBlaster_127_0_0_1_3412]/1</sender>
1034 <subscribe id='__subId:xmlBlaster_127_0_0_1_3412-XPATH1132587264334000000'/>
1035 <expiration lifeTime='-1'/>
1036 <rcvTimestamp nanos='1132587264254000001'/>
1037 <queue index='0' size='3'/>
1038 <forceUpdate/>
1039 <isPublish/>
1040 </qos>
1041 */
1042 protected string sender ;
1043 protected string subscribeId ;
1044
1045 public QosUpdate( string xml )
1046 {
1047 logger.Debug("Create with XML:\n{0}", xml );
1048 this.LoadXml( xml );
1049 }
1050
1051 public string SubscribeId
1052 {
1053 get
1054 {
1055 if( subscribeId == null )
1056 {
1057 XmlNode node = this.DocumentElement.SelectSingleNode("subscribe");
1058 this.subscribeId = node.Attributes[ "id" ].Value ;
1059 }
1060 logger.Debug("QosUpdate.SubscribeId: {0}", this.subscribeId );
1061 return this.subscribeId ;
1062 }
1063 }
1064 public string Sender
1065 {
1066 get
1067 {
1068 if( sender == null )
1069 {
1070 XmlNode node = this.DocumentElement.SelectSingleNode("sender");
1071 this.sender = node.InnerText ;
1072 }
1073 logger.Debug("QosUpdate.Sender: {0} ", this.sender );
1074 return sender ;
1075 }
1076 }
1077 }
1078 public class QosErase
1079 {
1080 static SimpleLog logger = XmlBlasterClient.loggerQos ;
1081
1082 bool forceDestroy = false ;
1083 public bool ForceDestroy
1084 {
1085 get
1086 {
1087 return this.forceDestroy ;
1088 }
1089 set
1090 {
1091 this.forceDestroy = value ;
1092 }
1093 }
1094 int numEntries = -1 ;
1095 public int NumEntries
1096 {
1097 get
1098 {
1099 return this.numEntries ;
1100 }
1101 set
1102 {
1103 this.numEntries = value ;
1104 }
1105 }
1106 public QosErase()
1107 {
1108 }
1109 public override string ToString()
1110 {
1111 StringBuilder sb = new StringBuilder( 256 );
1112 sb.Append( "<qos>\n" );
1113 sb.Append( "<erase forceDestroy=\""+(forceDestroy?"true":"false")+"\" >" );
1114 sb.Append( "<history numEntries=\""+numEntries.ToString()+"\" />" );
1115 sb.Append( "</erase>" );
1116 sb.Append( "</qos>" );
1117
1118 if( logger.IsDebug )
1119 {
1120 logger.Debug("QosErase.ToString() XML:\n{0}", sb.ToString() );
1121 }
1122 return sb.ToString() ;
1123 }
1124 }
1125
1126 public class QosMessageUnit : XmlDocument
1127 {
1128 static SimpleLog logger = XmlBlasterClient.loggerQos ;
1129
1130 /*
1131 XmlBlasterCallback.Update() cbSessionId:
1132 unknown
1133 XmlBlasterCallback.Update() key:
1134 <key oid='__sys__UserList'>
1135 <__sys__internal/>
1136 </key>
1137 XmlBlasterCallback.Update() qos:
1138 <qos>
1139 <sender>/node/xmlBlaster_127_0_0_1_3412/client/__RequestBroker_internal[xmlBlaster_127_0_0_1_3412]/1</sender>
1140 <subscribe id='__subId:xmlBlaster_127_0_0_1_3412-XPATH1132587264334000000'/>
1141 <expiration lifeTime='-1'/>
1142 <rcvTimestamp nanos='1132587264254000001'/>
1143 <queue index='0' size='3'/>
1144 <forceUpdate/>
1145 <isPublish/>
1146 </qos>
1147 */
1148
1149 protected string sender ;
1150 protected string subscribeId ;
1151 public QosMessageUnit( string xml )
1152 {
1153 string me="QosMessageUnit.QosMessageUnit()";
1154 logger.Debug("{0} XML:\n{1}", me, xml );
1155
1156 this.LoadXml( xml );
1157 }
1158
1159 public string SubscribeId
1160 {
1161 get
1162 {
1163 if( subscribeId == null )
1164 {
1165 XmlNode node = this.DocumentElement.SelectSingleNode("subscribe");
1166 this.subscribeId = node.Attributes[ "id" ].Value ;
1167 }
1168 logger.Debug("QosMessageUnit.SubscribeId: {0}", this.subscribeId );
1169 return this.subscribeId ;
1170 }
1171 }
1172 public string Sender
1173 {
1174 get
1175 {
1176 if( sender == null )
1177 {
1178 XmlNode node = this.DocumentElement.SelectSingleNode("sender");
1179 this.sender = node.InnerText ;
1180 }
1181 logger.Debug("QosMessageUnit.Sender: {0} ", this.sender );
1182 return sender ;
1183 }
1184 }
1185 }
1186
1187
1188 #endregion
1189
1190 }
syntax highlighted by Code2HTML, v. 0.9.1