1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.index;
20
21 import java.io.File;
22 import java.nio.file.Files;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Date;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.lucene.index.Term;
32 import org.apache.lucene.queryparser.classic.ParseException;
33 import org.apache.lucene.search.BooleanQuery;
34 import org.apache.lucene.search.IndexSearcher;
35 import org.apache.lucene.search.PrefixQuery;
36 import org.apache.lucene.search.Query;
37 import org.apache.lucene.search.TermQuery;
38 import org.apache.lucene.store.Directory;
39 import org.apache.lucene.store.FSDirectory;
40 import org.apache.maven.index.context.IndexingContext;
41 import org.apache.maven.index.packer.IndexPacker;
42 import org.apache.maven.index.packer.IndexPackingRequest;
43 import org.apache.maven.index.search.grouping.GAGrouping;
44 import org.apache.maven.index.search.grouping.GGrouping;
45 import org.apache.maven.index.updater.DefaultIndexUpdater;
46 import org.apache.maven.index.updater.IndexUpdateRequest;
47 import org.apache.maven.index.updater.IndexUpdater;
48 import org.junit.Assert;
49 import org.junit.Test;
50
51 import static org.apache.lucene.search.BooleanClause.*;
52 import static org.hamcrest.CoreMatchers.is;
53 import static org.hamcrest.MatcherAssert.assertThat;
54 import static org.junit.Assert.assertEquals;
55 import static org.junit.Assert.assertFalse;
56 import static org.junit.Assert.assertNotNull;
57 import static org.junit.Assert.assertNull;
58 import static org.junit.Assert.assertTrue;
59
60 public class FullIndexNexusIndexerTest extends DefaultIndexNexusIndexerTest {
61 @Override
62 protected void prepareNexusIndexer(NexusIndexer nexusIndexer) throws Exception {
63 context = nexusIndexer.addIndexingContext("test-default", "test", repo, indexDir, null, null, FULL_CREATORS);
64
65 assertNull(context.getTimestamp());
66
67 nexusIndexer.scan(context);
68
69 assertNotNull(context.getTimestamp());
70 }
71
72 @Test
73 public void testSearchGroupedClasses() throws Exception {
74 {
75 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "com/thoughtworks/qdox", SearchType.SCORED);
76 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
77 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
78 Map<String, ArtifactInfoGroup> r = response.getResults();
79
80 assertEquals(r.toString(), 2, r.size());
81
82 assertTrue(r.containsKey("qdox : qdox"));
83 assertTrue(r.containsKey("org.testng : testng"));
84 assertEquals("qdox : qdox", r.get("qdox : qdox").getGroupKey());
85 assertEquals("org.testng : testng", r.get("org.testng : testng").getGroupKey());
86 }
87
88 {
89 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "com.thoughtworks.qdox", SearchType.SCORED);
90 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
91 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
92 Map<String, ArtifactInfoGroup> r = response.getResults();
93 assertEquals(r.toString(), 2, r.size());
94
95 assertTrue(r.containsKey("qdox : qdox"));
96 assertTrue(r.containsKey("org.testng : testng"));
97 assertEquals("qdox : qdox", r.get("qdox : qdox").getGroupKey());
98 assertEquals("org.testng : testng", r.get("org.testng : testng").getGroupKey());
99 }
100
101 {
102 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "thoughtworks", SearchType.SCORED);
103 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
104 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
105 Map<String, ArtifactInfoGroup> r = response.getResults();
106 assertEquals(r.toString(), 2, r.size());
107 assertTrue(r.containsKey("qdox : qdox"));
108 assertTrue(r.containsKey("org.testng : testng"));
109 assertEquals("qdox : qdox", r.get("qdox : qdox").getGroupKey());
110 assertEquals("org.testng : testng", r.get("org.testng : testng").getGroupKey());
111 }
112
113 {
114
115 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "Logger", SearchType.SCORED);
116 GroupedSearchRequest request = new GroupedSearchRequest(q, new GGrouping());
117 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
118
119 Map<String, ArtifactInfoGroup> r = response.getResults();
120 Assert.assertThat(r.toString(), r.size(), is(2));
121
122 Iterator<ArtifactInfoGroup> it = r.values().iterator();
123
124 ArtifactInfoGroup ig1 = it.next();
125 assertEquals(r.toString(), "org.slf4j", ig1.getGroupKey());
126
127 ArtifactInfoGroup ig2 = it.next();
128 assertEquals(r.toString(), "org.testng", ig2.getGroupKey());
129 }
130
131 {
132
133 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "logger", SearchType.SCORED);
134 GroupedSearchRequest request = new GroupedSearchRequest(q, new GGrouping());
135 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
136 Map<String, ArtifactInfoGroup> r = response.getResults();
137 assertEquals(r.toString(), 2, r.size());
138
139 Iterator<ArtifactInfoGroup> it = r.values().iterator();
140
141 ArtifactInfoGroup ig1 = it.next();
142 assertEquals(r.toString(), "org.slf4j", ig1.getGroupKey());
143
144 ArtifactInfoGroup ig2 = it.next();
145 assertEquals(r.toString(), "org.testng", ig2.getGroupKey());
146 }
147
148 {
149
150
151
152 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, ".Logger", SearchType.SCORED);
153 GroupedSearchRequest request = new GroupedSearchRequest(q, new GGrouping());
154 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
155 Map<String, ArtifactInfoGroup> r = response.getResults();
156 assertEquals(r.toString(), 2, r.size());
157 Iterator<ArtifactInfoGroup> it = r.values().iterator();
158 ArtifactInfoGroup ig1 = it.next();
159 assertEquals(r.toString(), "org.slf4j", ig1.getGroupKey());
160 ArtifactInfoGroup ig2 = it.next();
161 assertEquals(r.toString(), "org.testng", ig2.getGroupKey());
162 }
163
164 {
165
166
167
168 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, ".Logger ", SearchType.SCORED);
169 GroupedSearchRequest request = new GroupedSearchRequest(q, new GGrouping());
170 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
171 Map<String, ArtifactInfoGroup> r = response.getResults();
172 assertEquals(r.toString(), 2, r.size());
173 Iterator<ArtifactInfoGroup> it = r.values().iterator();
174 ArtifactInfoGroup ig1 = it.next();
175 assertEquals(r.toString(), "org.slf4j", ig1.getGroupKey());
176 ArtifactInfoGroup ig2 = it.next();
177 assertEquals(r.toString(), "org.testng", ig2.getGroupKey());
178 }
179
180 {
181
182
183
184 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "Logger", SearchType.SCORED);
185 GroupedSearchRequest request = new GroupedSearchRequest(q, new GGrouping());
186 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
187 Map<String, ArtifactInfoGroup> r = response.getResults();
188
189
190 assertEquals(r.toString(), 2, r.size());
191
192 Iterator<ArtifactInfoGroup> it = r.values().iterator();
193
194
195
196
197
198 ArtifactInfoGroup ig2 = it.next();
199 assertEquals(r.toString(), "org.slf4j", ig2.getGroupKey());
200
201 ArtifactInfoGroup ig3 = it.next();
202 assertEquals(r.toString(), "org.testng", ig3.getGroupKey());
203 }
204
205 {
206
207 Query q = nexusIndexer.constructQuery(
208 MAVEN.CLASSNAMES, "org/apache/commons/logging/LogConfigurationException", SearchType.SCORED);
209 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
210 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
211
212 Map<String, ArtifactInfoGroup> r = response.getResults();
213 assertEquals(r.toString(), 2, r.size());
214 }
215
216 {
217
218 Query q = nexusIndexer.constructQuery(
219 MAVEN.CLASSNAMES, "org.apache.commons.logging.LogConfigurationException", SearchType.SCORED);
220 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
221 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
222
223 Map<String, ArtifactInfoGroup> r = response.getResults();
224 assertEquals(r.toString(), 2, r.size());
225 }
226
227 {
228
229 Query q = nexusIndexer.constructQuery(
230 MAVEN.CLASSNAMES, "org.apache.commons.logging.LogConfigurationException", SearchType.EXACT);
231 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
232 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
233
234 Map<String, ArtifactInfoGroup> r = response.getResults();
235 assertEquals(r.toString(), 2, r.size());
236 }
237
238 {
239
240 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "org.apache.commons.logging", SearchType.SCORED);
241 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
242 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
243
244 Map<String, ArtifactInfoGroup> r = response.getResults();
245 assertEquals(r.toString(), 2, r.size());
246 }
247
248 {
249
250
251 Query q = nexusIndexer.constructQuery(MAVEN.CLASSNAMES, "slf4j.Logg*", SearchType.SCORED);
252 GroupedSearchRequest request = new GroupedSearchRequest(q, new GAGrouping());
253 GroupedSearchResponse response = nexusIndexer.searchGrouped(request);
254
255 Map<String, ArtifactInfoGroup> r = response.getResults();
256
257 assertEquals(r.toString(), 1, r.size());
258
259 {
260 ArtifactInfoGroup ig = r.values().iterator().next();
261 ArrayList<ArtifactInfo> list1 = new ArrayList<>(ig.getArtifactInfos());
262 assertEquals(r.toString(), 2, list1.size());
263
264 ArtifactInfo ai1 = list1.get(0);
265 assertEquals("org.slf4j", ai1.getGroupId());
266 assertEquals("slf4j-api", ai1.getArtifactId());
267 assertEquals("1.4.2", ai1.getVersion());
268 ArtifactInfo ai2 = list1.get(1);
269 assertEquals("org.slf4j", ai2.getGroupId());
270 assertEquals("slf4j-api", ai2.getArtifactId());
271 assertEquals("1.4.1", ai2.getVersion());
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286 }
287 }
288
289 @Test
290 public void testSearchArchetypes() throws Exception {
291 Query q = new TermQuery(new Term(ArtifactInfo.PACKAGING, "maven-archetype"));
292 FlatSearchResponse response = nexusIndexer.searchFlat(new FlatSearchRequest(q));
293 Collection<ArtifactInfo> r = response.getResults();
294
295 assertEquals(4, r.size());
296
297 Iterator<ArtifactInfo> it = r.iterator();
298 {
299 ArtifactInfo ai = it.next();
300 assertEquals("org.apache.directory.server", ai.getGroupId());
301 assertEquals("apacheds-schema-archetype", ai.getArtifactId());
302 assertEquals("1.0.2", ai.getVersion());
303 }
304 {
305 ArtifactInfo ai = it.next();
306 assertEquals("org.apache.servicemix.tooling", ai.getGroupId());
307 assertEquals("servicemix-service-engine", ai.getArtifactId());
308 assertEquals("3.1", ai.getVersion());
309 }
310 {
311 ArtifactInfo ai = it.next();
312 assertEquals("org.terracotta.maven.archetypes", ai.getGroupId());
313 assertEquals("pojo-archetype", ai.getArtifactId());
314 assertEquals("1.0.3", ai.getVersion());
315 }
316 {
317 ArtifactInfo ai = it.next();
318 assertEquals("proptest", ai.getGroupId());
319 assertEquals("proptest-archetype", ai.getArtifactId());
320 assertEquals("1.0", ai.getVersion());
321 }
322 }
323
324 @Test
325 public void testIndexTimestamp() throws Exception {
326 final File targetDir = Files.createTempDirectory("testIndexTimestamp").toFile();
327 targetDir.deleteOnExit();
328
329 final IndexPacker indexPacker = lookup(IndexPacker.class);
330 final IndexSearcher indexSearcher = context.acquireIndexSearcher();
331 try {
332 final IndexPackingRequest request =
333 new IndexPackingRequest(context, indexSearcher.getIndexReader(), targetDir);
334 indexPacker.packIndex(request);
335 } finally {
336 context.releaseIndexSearcher(indexSearcher);
337 }
338
339 Thread.sleep(1000L);
340
341 File newIndex = new File(getBasedir(), "target/test-new");
342
343 Directory newIndexDir = FSDirectory.open(newIndex.toPath());
344
345 IndexingContext newContext =
346 nexusIndexer.addIndexingContext("test-new", "test", null, newIndexDir, null, null, DEFAULT_CREATORS);
347
348 final IndexUpdater indexUpdater = lookup(IndexUpdater.class);
349 indexUpdater.fetchAndUpdateIndex(
350 new IndexUpdateRequest(newContext, new DefaultIndexUpdater.FileFetcher(targetDir)));
351
352 assertEquals(context.getTimestamp().getTime(), newContext.getTimestamp().getTime());
353
354 assertEquals(context.getTimestamp(), newContext.getTimestamp());
355
356
357
358 Query query = nexusIndexer.constructQuery(MAVEN.GROUP_ID, "qdox", SearchType.SCORED);
359
360 FlatSearchRequest request = new FlatSearchRequest(query, newContext);
361 FlatSearchResponse response = nexusIndexer.searchFlat(request);
362 Collection<ArtifactInfo> r = response.getResults();
363
364 assertEquals(2, r.size());
365
366 List<ArtifactInfo> list = new ArrayList<>(r);
367
368 assertEquals(2, list.size());
369
370 ArtifactInfo ai = list.get(0);
371
372 assertEquals("1.6.1", ai.getVersion());
373
374 ai = list.get(1);
375
376 assertEquals("1.5", ai.getVersion());
377
378 assertEquals("test", ai.getRepository());
379
380 Date timestamp = newContext.getTimestamp();
381
382 newContext.close(false);
383
384 newIndexDir = FSDirectory.open(newIndex.toPath());
385
386 newContext =
387 nexusIndexer.addIndexingContext("test-new", "test", null, newIndexDir, null, null, DEFAULT_CREATORS);
388
389 indexUpdater.fetchAndUpdateIndex(
390 new IndexUpdateRequest(newContext, new DefaultIndexUpdater.FileFetcher(targetDir)));
391
392 assertEquals(timestamp, newContext.getTimestamp());
393
394 newContext.close(true);
395
396 assertFalse(new File(newIndex, "timestamp").exists());
397 }
398
399 @Test
400 public void testArchetype() throws Exception {
401 String term = "proptest";
402
403 Query bq = new PrefixQuery(new Term(ArtifactInfo.GROUP_ID, term));
404 TermQuery tq = new TermQuery(new Term(ArtifactInfo.PACKAGING, "maven-archetype"));
405
406 FlatSearchResponse response = nexusIndexer.searchFlat(new FlatSearchRequest(new BooleanQuery.Builder()
407 .add(tq, Occur.MUST)
408 .add(bq, Occur.FILTER)
409 .build()));
410
411 Collection<ArtifactInfo> r = response.getResults();
412
413 assertEquals(r.toString(), 1, r.size());
414 }
415
416 @Test
417 public void testArchetypePackaging() throws Exception {
418 Query query = new TermQuery(new Term(ArtifactInfo.PACKAGING, "maven-archetype"));
419 FlatSearchResponse response = nexusIndexer.searchFlat(new FlatSearchRequest(query));
420 assertEquals(response.getResults().toString(), 4, response.getTotalHits());
421 }
422
423 @Test
424 public void testBrokenJar() throws Exception {
425 Query q = nexusIndexer.constructQuery(MAVEN.ARTIFACT_ID, "brokenjar", SearchType.SCORED);
426
427 FlatSearchRequest searchRequest = new FlatSearchRequest(q);
428
429 FlatSearchResponse response = nexusIndexer.searchFlat(searchRequest);
430
431 Set<ArtifactInfo> r = response.getResults();
432
433 assertEquals(r.toString(), 1, r.size());
434
435 ArtifactInfo ai = r.iterator().next();
436
437 assertEquals("brokenjar", ai.getGroupId());
438 assertEquals("brokenjar", ai.getArtifactId());
439 assertEquals("1.0", ai.getVersion());
440 assertEquals(null, ai.getClassNames());
441 }
442
443 @Test
444 public void testMissingPom() throws Exception {
445 Query q = nexusIndexer.constructQuery(MAVEN.ARTIFACT_ID, "missingpom", SearchType.SCORED);
446
447 FlatSearchRequest searchRequest = new FlatSearchRequest(q);
448
449 FlatSearchResponse response = nexusIndexer.searchFlat(searchRequest);
450
451 Set<ArtifactInfo> r = response.getResults();
452
453 assertEquals(r.toString(), 1, r.size());
454
455 ArtifactInfo ai = r.iterator().next();
456
457 assertEquals("missingpom", ai.getGroupId());
458 assertEquals("missingpom", ai.getArtifactId());
459 assertEquals("1.0", ai.getVersion());
460
461 assertNull(ai.getClassNames());
462 }
463
464
465
466 protected IteratorSearchRequest createHighlightedRequest(Field field, String text, SearchType type)
467 throws ParseException {
468 Query q = nexusIndexer.constructQuery(field, text, type);
469
470 IteratorSearchRequest request = new IteratorSearchRequest(q);
471
472 request.getMatchHighlightRequests().add(new MatchHighlightRequest(field, q, MatchHighlightMode.HTML));
473
474 return request;
475 }
476
477 @Test
478 public void testClassnameSearchNgWithHighlighting() throws Exception {
479 IteratorSearchRequest request = createHighlightedRequest(MAVEN.CLASSNAMES, "Logger", SearchType.SCORED);
480
481 IteratorSearchResponse response = nexusIndexer.searchIterator(request);
482
483 for (ArtifactInfo ai : response) {
484 for (MatchHighlight mh : ai.getMatchHighlights()) {
485 for (String highlighted : mh.getHighlightedMatch()) {
486
487 assertTrue("Class name should be highlighted", highlighted.contains("<B>Logger"));
488 assertFalse(
489 "Class name should not contain \"/\" alone (but okay within HTML, see above!)",
490 highlighted.matches("\\p{Lower}/\\p{Upper}"));
491 assertFalse(
492 "Class name should not begin with \".\" or \"/\"",
493 highlighted.startsWith(".") || highlighted.startsWith("/"));
494 }
495 }
496 }
497
498 assertThat(response.getTotalHitsCount(), is(5));
499
500 assertEquals("found in jcl104-over-slf4j and commons-logging", 5, response.getTotalHits());
501 }
502
503 @Test
504 public void testGAVSearchNgWithHighlighting() throws Exception {
505 IteratorSearchRequest request = createHighlightedRequest(MAVEN.GROUP_ID, "commons", SearchType.SCORED);
506
507 IteratorSearchResponse response = nexusIndexer.searchIterator(request);
508
509 for (ArtifactInfo ai : response) {
510 for (MatchHighlight mh : ai.getMatchHighlights()) {
511 assertTrue(
512 "Group ID should be highlighted",
513 mh.getHighlightedMatch().contains("<B>commons</B>-logging")
514 || mh.getHighlightedMatch().contains("<B>commons</B>-cli"));
515 }
516 }
517
518 assertEquals("found in commons-logging and commons-cli", 15, response.getTotalHits());
519 }
520 }