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
.UriAsString
= hr
.uri
;
149 string[] fragments
= hr
.uri
.Split ('/');
150 string hostNamePort
= fragments
[2];
151 hit
.UriAsString
= 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
= new NetContext(hr
.hashCode
);
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 GetResults with index: " + index
);
208 string searchToken
= resp
.searchToken
;
210 GetResultsRequest req
= new GetResultsRequest();
211 req
.startIndex
= index
;
212 req
.searchToken
= searchToken
;
215 ar2
= wsp
.BeginGetResults(req
, NetBeagleHandler
.DoQueryResponseHandler
, rc
);
222 log
.Warn("NetBeagleHandler: DoQueryResponseHandler() got Null response from EndBeagleQuery() !");
225 catch (Exception ex
) {
227 log
.Error ("Exception in NetBeagleHandler: DoQueryResponseHandler() - {0} - for {1} ", ex
.Message
, wsp
.Hostname
+ ":" + wsp
.Port
);
230 //Signal completion of request handling
231 rc
.RequestProcessed
= true;
235 public class ReqContext
{
237 private IQueryable iq
;
238 private IQueryResult result
;
239 private BeagleWebService wsp
;
241 private bool reqProcessed
= false;
242 private string token
= null;
244 public ReqContext(BeagleWebService wsp
, IQueryResult result
, IQueryable iq
)
247 this.result
= result
;
249 this.reqProcessed
= false;
252 public BeagleWebService GetProxy
{
256 public IQueryResult GetResult
{
257 get { return result; }
260 public IQueryable GetQueryable
{
264 public bool RequestProcessed
{
265 get { return reqProcessed; }
266 set { reqProcessed = value; }
269 public string SearchToken
{
271 set {token = value; }
276 public class NetContext
{
278 private int _hashCode
;
280 public NetContext(int hashCode
)
282 this._hashCode
= hashCode
;
285 public int hashCode
{
286 get { return _hashCode; }