4 // Copyright (C) 2005 Novell, Inc.
7 // Vijay K. Nanjundaswamy (knvijay@novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining a
12 // copy of this software and associated documentation files (the "Software"),
13 // to deal in the Software without restriction, including without limitation
14 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 // and/or sell copies of the Software, and to permit persons to whom the
16 // Software is furnished to do so, subject to the following conditions:
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 // DEALINGS IN THE SOFTWARE.
31 using System
.Collections
;
32 using System
.Threading
;
37 namespace Beagle
.Daemon
40 public class NetBeagleHandler
44 IQueryable netBeagleQueryable
;
49 static Logger log
= Logger
.Get ("NetBeagleHandler");
51 public NetBeagleHandler (string hostname
, string port
, IQueryable iq
)
53 this.Hostname
= hostname
;
55 netBeagleQueryable
= iq
;
57 log
.Info ("Instantiating NetBeagleHandler for " + Hostname
+ ":" + Port
);
59 wsp
= new BeagleWebService (Hostname
, Port
);
60 wsp
.Timeout
= 40000; //40 sec time limit per request
63 private string[] ICollection2StringList(ICollection il
)
66 return new string[0] ;
68 string[] sl
= new string[il
.Count
];
74 public IAsyncResult
DoQuery (Query query
, IQueryResult result
,
75 IQueryableChangeData changeData
)
79 SearchRequest sreq
= new SearchRequest();
82 if ((l
!= null) && (l
.Count
> 0))
83 sreq
.text
= ICollection2StringList(query
.Text
);
86 if ((l
!= null) && (l
.Count
> 0))
87 sreq
.mimeType
= ICollection2StringList(query
.MimeTypes
);
90 if ((l
!= null) && (l
.Count
> 0))
91 sreq
.searchSources
= ICollection2StringList(query
.Sources
);
93 sreq
.qdomain
= QueryDomain
.Global
; //Caution: This Enables Cascaded NetBeagle searching !
94 //sreq.qdomain = QueryDomain.System;
96 //Cache the query request, get a unique searchId and include in network searchRequest:
97 sreq
.searchId
= NetworkedBeagle
.AddRequest(query
);
100 int hc
= NetworkedBeagle
.HopCount(query
);
101 sreq
.hopCount
= (hc
> 0) ? hc
:1;
103 log
.Info("NetBeagleHandler: Starting WebService Query for " + Hostname
+ ":" + Port
);
105 ReqContext rc
= new ReqContext(wsp
, result
, netBeagleQueryable
);
107 IAsyncResult ar
= wsp
.BeginBeagleQuery(sreq
, DoQueryResponseHandler
, rc
);
109 // Return w/o waiting for Async query to complete.
110 // Return IAsynResult handle, to allow caller to control it, if required.
115 public static void DoQueryResponseHandler(IAsyncResult ar
)
117 ReqContext rc
= (ReqContext
)ar
.AsyncState
;
119 IQueryable iq
= rc
.GetQueryable
;
120 BeagleWebService wsp
= rc
.GetProxy
;
121 IQueryResult result
= rc
.GetResult
;
124 //bool hitRejectsLogged = false;
128 SearchResult resp
= wsp
.EndBeagleQuery(ar
);
130 if ((resp
!= null) && (resp
.numResults
> 0))
132 if (rc
.SearchToken
== null)
133 rc
.SearchToken
= resp
.searchToken
;
135 //NetContext nc = new NetContext(wsp, resp.searchToken);
136 HitResult
[] hres
= resp
.hitResults
;
137 ArrayList nwhits
= new ArrayList();
139 for (int i
= 0; i
< hres
.Length
; i
++) {
142 HitResult hr
= hres
[i
];
143 Hit hit
= new NetworkHit();
145 //[Uri Format] netbeagle://164.99.153.134:8888/searchToken?http:///....
146 if (hr
.uri
.StartsWith(NetworkedBeagle
.BeagleNetPrefix
))
147 hit
.Uri
= new Uri(hr
.uri
);
149 string[] fragments
= hr
.uri
.Split ('/');
150 string hostNamePort
= fragments
[2];
151 hit
.Uri
= new Uri(NetworkedBeagle
.BeagleNetPrefix
+ hostNamePort
+ "/" + resp
.searchToken
+ "?" + hr
.uri
);
154 hit
.Type
= hr
.resourceType
;
155 hit
.MimeType
= hr
.mimeType
;
156 hit
.Source
= "Network"; //hit.Source = hr.source;
157 hit
.Score
= hr
.score
;
159 if (hr
.properties
.Length
> 0)
160 foreach (HitProperty hp
in hr
.properties
) {
162 Property p
= Property
.New(hp
.PKey
, hp
.PVal
);
163 p
.IsMutable
= hp
.IsMutable
;
164 p
.IsSearched
= hp
.IsSearched
;
170 ((NetworkHit
)hit
).snippet
= hr
.snippet
;
172 //if (hr.snippet != null)
173 //log.Debug("\nNBH: URI" + i + "=" + hr.uri + "\n Snippet=" + hr.snippet);
175 ((NetworkHit
)hit
).context
= null;
177 //Add NetBeagleQueryable instance
178 hit
.SourceObject
= iq
;
179 hit
.SourceObjectName
= ((NetworkedBeagle
)iq
).Name
;
185 catch (Exception ex2
) {
187 log
.Warn ("Exception in NetBeagleHandler: DoQueryResponseHandler() while processing NetworkHit: {0} from {1}\n Reason: {2} ", hres
[i
].uri
, wsp
.Hostname
+ ":" + wsp
.Port
, ex2
.Message
);
188 //log.Error ("Exception StackTrace: " + ex.StackTrace);
192 if (nwhits
.Count
> 0)
195 if ((! result.Add (nwhits)) && (! hitRejectsLogged))
197 hitRejectsLogged = true;
198 log.Info("NetBeagleHandler: Network Hits rejected by HitRegulator. Too many Hits!");
201 log
.Info("NetBeagleHandler: DoQueryResponseHandler() Got {0} result(s) from Index {1} from Networked Beagle at {2}", count
, resp
.firstResultIndex
, wsp
.Hostname
+ ":" + wsp
.Port
);
203 int index
= resp
.firstResultIndex
+ resp
.numResults
;
204 if (index
< resp
.totalResults
) {
206 log
.Debug("NetBeagleHandler: DoQueryResponseHandler() invoking GetMoreResults with index: " + index
);
208 string searchToken
= resp
.searchToken
;
209 IAsyncResult ar2
= wsp
.BeginGetMoreResults(searchToken
, index
, NetBeagleHandler
.DoQueryResponseHandler
, rc
);
216 log
.Warn("NetBeagleHandler: DoQueryResponseHandler() got Null response from EndBeagleQuery() !");
219 catch (Exception ex
) {
221 log
.Error ("Exception in NetBeagleHandler: DoQueryResponseHandler() - {0} - for {1} ", ex
.Message
, wsp
.Hostname
+ ":" + wsp
.Port
);
224 //Signal completion of request handling
225 rc
.RequestProcessed
= true;
229 public class ReqContext
{
231 private IQueryable iq
;
232 private IQueryResult result
;
233 private BeagleWebService wsp
;
235 private bool reqProcessed
= false;
236 private string token
= null;
238 public ReqContext(BeagleWebService wsp
, IQueryResult result
, IQueryable iq
)
241 this.result
= result
;
243 this.reqProcessed
= false;
246 public BeagleWebService GetProxy
{
250 public IQueryResult GetResult
{
251 get { return result; }
254 public IQueryable GetQueryable
{
258 public bool RequestProcessed
{
259 get { return reqProcessed; }
260 set { reqProcessed = value; }
263 public string SearchToken
{
265 set {token = value; }
270 public class NetContext {
272 private string token;
273 private BeagleWebService wsp;
275 public NetContext(BeagleWebService wsp, string token)
281 public BeagleWebService proxy {
285 public string searchToken {