Compute lucene-style scores for our hits.
[beagle.git] / beagled / WebServices / NetBeagleHandler.cs
blobc6c6883f644bebfd97e9fbd31834812aeda62b00
1 //
2 // NetBeagleHandler.cs
3 //
4 // Copyright (C) 2005 Novell, Inc.
5 //
6 // Authors:
7 // Vijay K. Nanjundaswamy (knvijay@novell.com)
8 //
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.
30 using System;
31 using System.Collections;
32 using System.Threading;
34 using Beagle;
35 using Beagle.Util;
37 namespace Beagle.Daemon
40 public class NetBeagleHandler
42 string Hostname;
43 string Port;
44 IQueryable netBeagleQueryable;
46 BeagleWebService wsp;
47 IQueryResult result;
49 static Logger log = Logger.Get ("NetBeagleHandler");
51 public NetBeagleHandler (string hostname, string port, IQueryable iq)
53 this.Hostname = hostname;
54 this.Port = port;
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)
65 if (il == null)
66 return new string[0] ;
68 string[] sl = new string[il.Count];
69 il.CopyTo(sl, 0);
71 return sl;
74 public IAsyncResult DoQuery (Query query, IQueryResult result,
75 IQueryableChangeData changeData)
77 ICollection l;
79 SearchRequest sreq = new SearchRequest();
81 l = query.Text;
82 if ((l != null) && (l.Count > 0))
83 sreq.text = ICollection2StringList(query.Text);
85 l = query.MimeTypes;
86 if ((l != null) && (l.Count > 0))
87 sreq.mimeType = ICollection2StringList(query.MimeTypes);
89 l = query.Sources;
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.
112 return ar;
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;
123 int count = 0;
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++) {
141 try {
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);
148 else {
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;
166 hit.AddProperty(p);
169 //Add Snippet
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;
181 nwhits.Add(hit);
183 count++;
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);
190 } //end for
192 if (nwhits.Count > 0)
193 result.Add (nwhits);
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);
211 return;
213 } //end if
214 else {
215 if (resp == null)
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)
240 this.wsp = wsp;
241 this.result = result;
242 this.iq = iq;
243 this.reqProcessed = false;
246 public BeagleWebService GetProxy {
247 get { return wsp; }
250 public IQueryResult GetResult {
251 get { return result; }
254 public IQueryable GetQueryable {
255 get { return iq; }
258 public bool RequestProcessed {
259 get { return reqProcessed; }
260 set { reqProcessed = value; }
263 public string SearchToken {
264 get {return token; }
265 set {token = value; }
270 public class NetContext {
272 private string token;
273 private BeagleWebService wsp;
275 public NetContext(BeagleWebService wsp, string token)
277 this.wsp = wsp;
278 this.token = token;
281 public BeagleWebService proxy {
282 get { return wsp; }
285 public string searchToken {
286 get {return token; }