18
18
*/
19
19
package com .redhat .lightblue .savedsearch ;
20
20
21
- import java .util .Map ;
22
21
import java .util .Iterator ;
23
22
import java .util .Objects ;
24
23
import java .util .List ;
60
59
import com .redhat .lightblue .util .Path ;
61
60
import com .redhat .lightblue .util .JsonUtils ;
62
61
62
+ /**
63
+ * This class is the main access point to saved searches. It loads
64
+ * saved searches from the db, and keeps them in a weak cache.
65
+ */
63
66
public class SavedSearchCache {
64
67
private static final Logger LOGGER = LoggerFactory .getLogger (SavedSearchCache .class );
65
68
66
69
public static final String ERR_SAVED_SEARCH ="crud:saved-search" ;
67
70
68
- private Cache <Key ,ObjectNode > cache ;
71
+ Cache <Key ,ObjectNode > cache ;
69
72
70
73
private static final Path P_NAME =new Path ("name" );
71
74
private static final Path P_ENTITY =new Path ("entity" );
@@ -108,6 +111,11 @@ public boolean equals(Object o) {
108
111
public int hashCode () {
109
112
return (version ==null ?1 :version .hashCode ())*searchName .hashCode ()*entity .hashCode ();
110
113
}
114
+
115
+ @ Override
116
+ public String toString () {
117
+ return searchName +":" +entity +":" +version ;
118
+ }
111
119
112
120
public Key (String searchName ,String entity ,String version ) {
113
121
this .searchName =searchName ;
@@ -142,10 +150,21 @@ private void initializeCache(String spec) {
142
150
143
151
144
152
/**
145
- * Retrieves a saved search from the database. The returned JsonNode can be an ObjectNode, or an ArrayNode containing
146
- * zero or more documents. If there are more than one documents, only one of them is for the requested version, and the
147
- * other is for the null version that applies to all versions. It returns null or empty array if nothing is found.
148
- * In case of retrieval error, a RetrievalError is thrown containing the errors.
153
+ * Retrieves a saved search from the database.
154
+ *
155
+ * @param m Mediator instance
156
+ * @param clid The client id
157
+ * @param searchName name of the saved search
158
+ * @param entit Name of the entity
159
+ * @param version Entity version the search should run on
160
+ *
161
+ * The returned JsonNode can be an ObjectNode, or an ArrayNode
162
+ * containing zero or more documents. If there are more than one
163
+ * documents, only one of them is for the requested version, and
164
+ * the other is for the null version that applies to all
165
+ * versions. It returns null or empty array if nothing is found.
166
+ * In case of retrieval error, a RetrievalError is thrown
167
+ * containing the errors.
149
168
*/
150
169
public JsonNode retrieveFromDB (Mediator m ,
151
170
ClientIdentification clid ,
@@ -181,21 +200,29 @@ public JsonNode retrieveFromDB(Mediator m,
181
200
findRequest .setQuery (q );
182
201
findRequest .setProjection (FieldProjection .ALL );
183
202
Response response =m .find (findRequest );
184
- if (response .getErrors ()!=null &&response .getErrors ().isEmpty ())
203
+ if (response .getErrors ()!=null &&! response .getErrors ().isEmpty ())
185
204
throw new RetrievalError (response .getErrors ());
205
+ LOGGER .debug ("Found {}" ,response .getEntityData ());
186
206
return response .getEntityData ();
187
207
}
188
208
189
209
/**
190
210
* Either loads the saved search from the db, or from the
191
211
* cache.
212
+ *
213
+ * @param m Mediator instance
214
+ * @param clid The client id
215
+ * @param searchName name of the saved search
216
+ * @param entit Name of the entity
217
+ * @param version Entity version the search should run on
218
+ *
219
+ * @return The saved search document, or null if not found
192
220
*/
193
221
public JsonNode getSavedSearch (Mediator m ,
194
222
ClientIdentification clid ,
195
223
String searchName ,
196
224
String entity ,
197
- String version ,
198
- Map <String ,String > parameterValues ) {
225
+ String version ) {
199
226
LOGGER .debug ("Loading {}:{}:{}" ,searchName ,entity ,version );
200
227
ObjectNode doc =null ;
201
228
String loadVersion ;
@@ -221,9 +248,11 @@ public JsonNode getSavedSearch(Mediator m,
221
248
LOGGER .debug ("Loading {} from DB" ,searchName );
222
249
JsonNode node =retrieveFromDB (m ,clid ,searchName ,entity ,loadVersion );
223
250
if (node instanceof ObjectNode ) {
251
+ LOGGER .debug ("Loaded a single search" );
224
252
doc =(ObjectNode )node ;
225
253
store (doc );
226
254
} else if (node instanceof ArrayNode ) {
255
+ LOGGER .debug ("Loaded an array of searches" );
227
256
store ((ArrayNode )node );
228
257
doc =findDocForVersion ((ArrayNode )node ,loadVersion );
229
258
}
@@ -235,13 +264,16 @@ public JsonNode getSavedSearch(Mediator m,
235
264
}
236
265
237
266
private ObjectNode findDocForVersion (ArrayNode node ,String version ) {
267
+ LOGGER .debug ("Searching {} in the array" ,version );
238
268
ObjectNode ret =null ;
239
269
String matchedVersion =null ;
240
270
for (Iterator <JsonNode > itr =node .elements ();itr .hasNext ();) {
241
271
JsonNode searchNode =itr .next ();
242
272
if (searchNode instanceof ObjectNode ) {
243
273
JsonNode versionsNode =searchNode .get ("versions" );
244
- if (versionsNode instanceof ArrayNode ) {
274
+ LOGGER .debug ("Versions in search:{}" ,versionsNode );
275
+ if (versionsNode instanceof ArrayNode && versionsNode .size ()>0 ) {
276
+ LOGGER .debug ("Looking up in versions array" );
245
277
for (Iterator <JsonNode > vitr =versionsNode .elements ();vitr .hasNext ();) {
246
278
JsonNode versionNode =vitr .next ();
247
279
if (versionNode instanceof NullNode ) {
@@ -257,11 +289,16 @@ private ObjectNode findDocForVersion(ArrayNode node,String version) {
257
289
}
258
290
}
259
291
}
260
- } else if (version ==null ) {
261
- ret =(ObjectNode )searchNode ;
292
+ } else {
293
+ if (ret ==null ) {
294
+ ret =(ObjectNode )searchNode ;
295
+ matchedVersion =null ;
296
+ }
262
297
}
298
+ LOGGER .debug ("Current best match after {}:{}" ,searchNode ,ret );
263
299
}
264
300
}
301
+ LOGGER .debug ("Best match for version {}:{}" ,version ,ret );
265
302
return ret ;
266
303
}
267
304
@@ -283,6 +320,8 @@ private boolean betterMatch(String searchedVersion,String newVersion,String matc
283
320
// if newVersion is a longer prefix of searchVersion than matchedVersion is, then it is a better match
284
321
int newMatchingPrefix =getMatchingPrefix (searchedVersion ,newVersion );
285
322
int oldMatchingPrefix =getMatchingPrefix (searchedVersion ,matchedVersion );
323
+ LOGGER .debug ("Comparing to {}: {}: prefix={} {}: prefix={}" ,searchedVersion ,newVersion ,newMatchingPrefix ,
324
+ matchedVersion ,oldMatchingPrefix );
286
325
return newMatchingPrefix >oldMatchingPrefix ;
287
326
}
288
327
}
@@ -321,18 +360,22 @@ private synchronized void store(ObjectNode doc) {
321
360
String name =doc .get ("name" ).asText ();
322
361
String entity =doc .get ("entity" ).asText ();
323
362
ArrayNode arr =(ArrayNode )doc .get ("versions" );
363
+ Key key =null ;
324
364
if (arr !=null ) {
325
365
for (Iterator <JsonNode > itr =arr .elements ();itr .hasNext ();) {
326
366
JsonNode version =itr .next ();
327
367
if (version instanceof NullNode ) {
328
- cache . put ( new Key (name ,entity ,null ), doc );
368
+ key = new Key (name ,entity ,null );
329
369
} else {
330
- cache . put ( new Key (name ,entity ,version .asText ()), doc );
370
+ key = new Key (name ,entity ,version .asText ());
331
371
}
332
372
}
333
- } else {
334
- cache .put (new Key (name ,entity ,null ),doc );
335
373
}
374
+ if (key ==null ) {
375
+ key =new Key (name ,entity ,null );
376
+ }
377
+ LOGGER .debug ("Adding {} to cache" ,key );
378
+ cache .put (key ,doc );
336
379
}
337
380
338
381
private synchronized void store (ArrayNode arr ) {
0 commit comments