Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / WebServices / NetBeagleHandler.cs
blobdc007ec977e0ac566e21a355910e5d9717cf551c
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 //FIXME: Generate a random no. b/w 1 .. 99 and multiply by 1000000, and add to hr.id ?
146 hit.Id = 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);
151 else {
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;
170 hit.AddProperty(p);
173 //Add Snippet
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;
185 nwhits.Add(hit);
187 count++;
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);
194 } //end for
196 if (nwhits.Count > 0)
197 result.Add (nwhits);
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);
215 return;
217 } //end if
218 else {
219 if (resp == null)
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)
244 this.wsp = wsp;
245 this.result = result;
246 this.iq = iq;
247 this.reqProcessed = false;
250 public BeagleWebService GetProxy {
251 get { return wsp; }
254 public IQueryResult GetResult {
255 get { return result; }
258 public IQueryable GetQueryable {
259 get { return iq; }
262 public bool RequestProcessed {
263 get { return reqProcessed; }
264 set { reqProcessed = value; }
267 public string SearchToken {
268 get {return token; }
269 set {token = value; }
274 public class NetContext {
276 private string token;
277 private BeagleWebService wsp;
279 public NetContext(BeagleWebService wsp, string token)
281 this.wsp = wsp;
282 this.token = token;
285 public BeagleWebService proxy {
286 get { return wsp; }
289 public string searchToken {
290 get {return token; }