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 //FIXME: Generate a random no. b/w 1 .. 99 and multiply by 1000000, and add to hr.id ?
148 //[Uri Format] netbeagle://164.99.153.134:8888/searchToken?http:///....
149 if (hr
.uri
.StartsWith(NetworkedBeagle
.BeagleNetPrefix
))
150 hit
.Uri
= new Uri(hr
.uri
);
152 string[] fragments
= hr
.uri
.Split ('/');
153 string hostNamePort
= fragments
[2];
154 hit
.Uri
= new Uri(NetworkedBeagle
.BeagleNetPrefix
+ hostNamePort
+ "/" + resp
.searchToken
+ "?" + hr
.uri
);
157 hit
.Type
= hr
.resourceType
;
158 hit
.MimeType
= hr
.mimeType
;
159 hit
.Source
= "Network"; //hit.Source = hr.source;
160 hit
.ScoreRaw
= hr
.scoreRaw
+ 0.01;
161 hit
.ScoreMultiplier
= hr
.scoreMultiplier
;
163 if (hr
.properties
.Length
> 0)
164 foreach (HitProperty hp
in hr
.properties
) {
166 Property p
= Property
.New(hp
.PKey
, hp
.PVal
);
167 p
.IsMutable
= hp
.IsMutable
;
168 p
.IsSearched
= hp
.IsSearched
;
174 ((NetworkHit
)hit
).snippet
= hr
.snippet
;
176 //if (hr.snippet != null)
177 //log.Debug("\nNBH: URI" + i + "=" + hr.uri + "\n Snippet=" + hr.snippet);
179 ((NetworkHit
)hit
).context
= null;
181 //Add NetBeagleQueryable instance
182 hit
.SourceObject
= iq
;
183 hit
.SourceObjectName
= ((NetworkedBeagle
)iq
).Name
;
189 catch (Exception ex2
) {
191 log
.Warn ("Exception in NetBeagleHandler: DoQueryResponseHandler() while processing NetworkHit: {0} from {1}\n Reason: {2} ", hres
[i
].uri
, wsp
.Hostname
+ ":" + wsp
.Port
, ex2
.Message
);
192 //log.Error ("Exception StackTrace: " + ex.StackTrace);
196 if (nwhits
.Count
> 0)
199 if ((! result.Add (nwhits)) && (! hitRejectsLogged))
201 hitRejectsLogged = true;
202 log.Info("NetBeagleHandler: Network Hits rejected by HitRegulator. Too many Hits!");
205 log
.Info("NetBeagleHandler: DoQueryResponseHandler() Got {0} result(s) from Index {1} from Networked Beagle at {2}", count
, resp
.firstResultIndex
, wsp
.Hostname
+ ":" + wsp
.Port
);
207 int index
= resp
.firstResultIndex
+ resp
.numResults
;
208 if (index
< resp
.totalResults
) {
210 log
.Debug("NetBeagleHandler: DoQueryResponseHandler() invoking GetMoreResults with index: " + index
);
212 string searchToken
= resp
.searchToken
;
213 IAsyncResult ar2
= wsp
.BeginGetMoreResults(searchToken
, index
, NetBeagleHandler
.DoQueryResponseHandler
, rc
);
220 log
.Warn("NetBeagleHandler: DoQueryResponseHandler() got Null response from EndBeagleQuery() !");
223 catch (Exception ex
) {
225 log
.Error ("Exception in NetBeagleHandler: DoQueryResponseHandler() - {0} - for {1} ", ex
.Message
, wsp
.Hostname
+ ":" + wsp
.Port
);
228 //Signal completion of request handling
229 rc
.RequestProcessed
= true;
233 public class ReqContext
{
235 private IQueryable iq
;
236 private IQueryResult result
;
237 private BeagleWebService wsp
;
239 private bool reqProcessed
= false;
240 private string token
= null;
242 public ReqContext(BeagleWebService wsp
, IQueryResult result
, IQueryable iq
)
245 this.result
= result
;
247 this.reqProcessed
= false;
250 public BeagleWebService GetProxy
{
254 public IQueryResult GetResult
{
255 get { return result; }
258 public IQueryable GetQueryable
{
262 public bool RequestProcessed
{
263 get { return reqProcessed; }
264 set { reqProcessed = value; }
267 public string SearchToken
{
269 set {token = value; }
274 public class NetContext {
276 private string token;
277 private BeagleWebService wsp;
279 public NetContext(BeagleWebService wsp, string token)
285 public BeagleWebService proxy {
289 public string searchToken {