Adding interfaces in documentation
[aai/sparky-be.git] / sparkybe-onap-service / src / test / java / org / onap / aai / sparky / search / UnifiedSearchProcessorTest.java
1 /**
2  * ============LICENSE_START===================================================
3  * SPARKY (AAI UI service)
4  * ============================================================================
5  * Copyright © 2017 AT&T Intellectual Property.
6  * Copyright © 2017 Amdocs
7  * All rights reserved.
8  * ============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=====================================================
21  *
22  * ECOMP and OpenECOMP are trademarks
23  * and service marks of AT&T Intellectual Property.
24  */
25
26 package org.onap.aai.sparky.search;
27
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertNotNull;
30 import static org.junit.Assert.assertNull;
31
32 import java.io.IOException;
33 import java.util.ArrayList;
34 import java.util.List;
35
36 import javax.servlet.http.HttpServletRequest;
37
38 import org.apache.camel.CamelContext;
39 import org.apache.camel.Exchange;
40 import org.apache.camel.Message;
41 import org.apache.camel.impl.DefaultCamelContext;
42 import org.apache.camel.impl.DefaultExchange;
43 import org.json.JSONObject;
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.mockito.Mockito;
47 import org.onap.aai.sparky.common.search.CommonSearchSuggestion;
48 import org.onap.aai.sparky.search.api.SearchProvider;
49 import org.onap.aai.sparky.search.entity.MockSearchResponse;
50 import org.onap.aai.sparky.search.entity.QuerySearchEntity;
51 import org.onap.aai.sparky.search.entity.SearchSuggestion;
52 import org.onap.aai.sparky.search.registry.SearchProviderRegistry;
53 import org.onap.aai.sparky.util.HttpServletHelper;
54
55 import com.fasterxml.jackson.databind.ObjectMapper;
56
57
58 public class UnifiedSearchProcessorTest {
59   
60   public interface Suggester {
61     public void addSuggestion( SearchSuggestion suggestion );
62   }
63   
64   private abstract class AbstractDummySearchProvider implements SearchProvider, Suggester {
65
66     protected List<SearchSuggestion> suggestions;
67
68     protected AbstractDummySearchProvider() {
69       suggestions = new ArrayList<SearchSuggestion>();
70     }
71
72     public List<SearchSuggestion> getSuggestions() {
73       return suggestions;
74     }
75
76     @Override
77     public List<SearchSuggestion> search(QuerySearchEntity queryRequest) {
78       return getSuggestions();
79     }
80   }
81
82   private class AlphaSearchProvider extends AbstractDummySearchProvider {
83     public AlphaSearchProvider() {
84       super();
85     }
86
87     @Override
88     public void addSuggestion(SearchSuggestion suggestion) {
89       if (suggestion != null) {
90         suggestions.add(suggestion);
91       }
92     }
93   }
94
95   private class BravoSearchProvider extends AbstractDummySearchProvider {
96     public BravoSearchProvider() {
97       super();
98     }
99
100     @Override
101     public void addSuggestion(SearchSuggestion suggestion) {
102       if (suggestion != null) {
103         suggestions.add(suggestion);
104       }
105     }
106   }
107
108   private class GammaSearchProvider extends AbstractDummySearchProvider {
109     public GammaSearchProvider() {
110       super();
111     }
112
113     @Override
114     public void addSuggestion(SearchSuggestion suggestion) {
115       if (suggestion != null) {
116         suggestions.add(suggestion);
117       }
118     }
119   }
120   
121   private SearchServiceAdapter mockSearchAdapter;
122   
123   private UnifiedSearchProcessor unifiedSearchProcessor;
124   private Message mockRequestMessage;
125   private ObjectMapper mapper;
126
127   private Exchange exchange;
128   private CamelContext camelContext;
129   
130   @Before
131   public void init() {
132     
133     camelContext = new DefaultCamelContext();
134     exchange = new DefaultExchange(camelContext);
135   
136     mockRequestMessage = Mockito.mock(Message.class);
137     exchange.setIn(mockRequestMessage);
138
139     unifiedSearchProcessor = new UnifiedSearchProcessor();
140     unifiedSearchProcessor.setUseOrderedSearchProviderKeys(true);
141
142     mapper = new ObjectMapper();
143     
144     mockSearchAdapter = Mockito.mock(SearchServiceAdapter.class);
145   }
146
147
148   @Test
149   public void validateDefaultConstructor() {
150
151     // initially it should be null until the bean wiring initializes it
152     assertNull(unifiedSearchProcessor.getSearchProviderRegistry());
153
154   }
155   
156   
157   @Test
158   public void validateAccessors() {
159
160     SearchProviderRegistry searchProviderRegistry = new SearchProviderRegistry();
161     unifiedSearchProcessor.setSearchProviderRegistry(searchProviderRegistry);
162     
163     // initially it should be null until the bean wiring initializes it
164     assertNotNull(unifiedSearchProcessor.getSearchProviderRegistry());
165     assertEquals(0, searchProviderRegistry.getSearchProviders().size());
166
167   }
168   
169   private void initializeSearchMocks(String requestPayload) {
170
171     HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
172     HttpServletHelper.setRequestPayload(request, "application/json", requestPayload);
173     
174     Mockito.when(request.getRequestURI()).thenReturn("fakeUri");
175     Mockito.when(request.getLocalPort()).thenReturn(8001);
176     Mockito.when(mockRequestMessage.getBody(Mockito.eq(HttpServletRequest.class))).thenReturn(request);
177     Mockito.when(mockRequestMessage.getBody(Mockito.eq(String.class))).thenReturn(requestPayload);
178
179   }
180   
181   private String getSearchRequestJson(String queryString, int maxResults) {
182     
183     JSONObject root = new JSONObject();
184     root.put("queryStr", queryString);
185     root.put("maxResults", maxResults);
186     
187     return root.toString();
188
189   }
190   
191   private String getExternalSearchRequestJson() {
192     JSONObject root = new JSONObject();
193     
194     root.put("view", "testView");
195     root.put("entityId", "thisIsAnId");
196     root.put("entityType", "pserver");
197     
198     return root.toString();
199   }
200   
201   
202   @Test
203   public void testSearch_search_when_noSearchProviders() throws IOException {
204
205     // mock env setup
206
207     initializeSearchMocks(getSearchRequestJson("vnfs",10));
208
209     SearchProviderRegistry searchProviderRegistry = new SearchProviderRegistry();
210     unifiedSearchProcessor.setSearchProviderRegistry(searchProviderRegistry);
211     
212     // method under test
213     unifiedSearchProcessor.search(exchange);
214     
215     assertEquals(200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));
216
217     String entityPayload = exchange.getOut().getBody(String.class); 
218     assertNotNull(entityPayload);
219
220     MockSearchResponse searchResponse = mapper.readValue(entityPayload, MockSearchResponse.class);
221
222     assertEquals(0, searchResponse.getTotalFound());
223     assertEquals(0, searchResponse.getSuggestions().size());
224     
225   }
226   
227   @Test
228   public void testSearch_search_when_ThreeSearchProviders_no_suggestions() throws IOException {
229
230     // mock env setup
231
232     initializeSearchMocks(getSearchRequestJson("vnfs",10));
233
234     SearchProviderRegistry searchProviderRegistry = new SearchProviderRegistry();
235     
236     AlphaSearchProvider alpha = new AlphaSearchProvider();
237     BravoSearchProvider bravo = new BravoSearchProvider();
238     GammaSearchProvider gamma = new GammaSearchProvider();
239     
240     searchProviderRegistry.addSearchProvider(alpha);
241     searchProviderRegistry.addSearchProvider(bravo);
242     searchProviderRegistry.addSearchProvider(gamma);
243     
244     unifiedSearchProcessor.setSearchProviderRegistry(searchProviderRegistry);
245
246     // method under test
247     unifiedSearchProcessor.search(exchange);
248     
249     assertEquals(200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));
250
251     String entityPayload = exchange.getOut().getBody(String.class); 
252     assertNotNull(entityPayload);
253
254     /*
255      * With a null view name, an empty filter set should be returned - there should be 0 filters
256      */
257
258     SearchResponse searchResponse = mapper.readValue(entityPayload, SearchResponse.class);
259
260     assertEquals(0, searchResponse.getTotalFound());
261     assertEquals(0, searchResponse.getSuggestions().size());
262     
263   }
264   
265   private void addSuggestions(int numSuggestions, String suggestionPrefix, Suggester suggester) {
266     for ( int x = 0; x < numSuggestions; x++ ){
267       CommonSearchSuggestion suggestion = new CommonSearchSuggestion();
268       suggestion.setText(suggestionPrefix + "-" + x);
269       suggester.addSuggestion(suggestion);
270     }
271   }
272   
273   private int countSuggestions(String suggestionPrefix, SearchResponse response) {
274     
275     int totalFound = 0;
276     
277     for ( SearchSuggestion suggestion : response.getSuggestions()) {
278       
279       if ( suggestion.getText() != null && suggestion.getText().startsWith(suggestionPrefix)) {
280         totalFound++;
281       }
282     }
283     
284     return totalFound;
285     
286   }
287   
288  private int countSuggestions(String suggestionPrefix, MockSearchResponse response) {
289     
290     int totalFound = 0;
291     
292     for ( SearchSuggestion suggestion : response.getSuggestions()) {
293       
294       if ( suggestion.getText() != null && suggestion.getText().startsWith(suggestionPrefix)) {
295         totalFound++;
296       }
297     }
298     
299     return totalFound;
300     
301   }
302   
303   
304   @Test
305   public void testSearch_search_when_ThreeSearchProviders_5suggestions_each() throws IOException {
306
307     // mock env setup
308
309     initializeSearchMocks(getSearchRequestJson("vnfs",10));
310
311     SearchProviderRegistry searchProviderRegistry = new SearchProviderRegistry();
312     
313     AlphaSearchProvider alpha = new AlphaSearchProvider();
314     BravoSearchProvider bravo = new BravoSearchProvider();
315     GammaSearchProvider gamma = new GammaSearchProvider();
316     
317     addSuggestions(5, "alpha", alpha);
318     addSuggestions(5, "bravo", bravo);
319     addSuggestions(5, "gamma", gamma);
320     
321     searchProviderRegistry.addSearchProvider(alpha);
322     searchProviderRegistry.addSearchProvider(bravo);
323     searchProviderRegistry.addSearchProvider(gamma);
324     
325     unifiedSearchProcessor.setSearchProviderRegistry(searchProviderRegistry);
326     
327     // method under test
328     unifiedSearchProcessor.search(exchange);
329
330     assertEquals(200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));
331
332     String entityPayload = exchange.getOut().getBody(String.class); 
333     assertNotNull(entityPayload);
334
335     MockSearchResponse searchResponse = mapper.readValue(entityPayload, MockSearchResponse.class);
336
337     assertEquals(10, searchResponse.getTotalFound());
338     assertEquals(10, searchResponse.getSuggestions().size());
339     
340     assertEquals( 4, countSuggestions("alpha", searchResponse));
341     assertEquals( 3, countSuggestions("bravo", searchResponse));
342     assertEquals( 3, countSuggestions("gamma", searchResponse));
343     
344   }
345
346   @Test
347   public void testSearch_search_when_ThreeSearchProviders_mixedNumSuggestions() throws IOException {
348
349     // mock env setup
350
351     initializeSearchMocks(getSearchRequestJson("vnfs",13));
352
353     SearchProviderRegistry searchProviderRegistry = new SearchProviderRegistry();
354     
355     AlphaSearchProvider alpha = new AlphaSearchProvider();
356     BravoSearchProvider bravo = new BravoSearchProvider();
357     GammaSearchProvider gamma = new GammaSearchProvider();
358     
359     searchProviderRegistry.addSearchProvider(alpha);
360     searchProviderRegistry.addSearchProvider(bravo);
361     searchProviderRegistry.addSearchProvider(gamma);
362     
363     unifiedSearchProcessor.setSearchProviderRegistry(searchProviderRegistry);
364     
365     addSuggestions(45,"alpha",alpha);
366     addSuggestions(1,"bravo",bravo);
367     addSuggestions(99,"gamma",gamma);
368     
369     // method under test
370     unifiedSearchProcessor.search(exchange);
371     
372     assertEquals(200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));
373
374     String entityPayload = exchange.getOut().getBody(String.class); 
375     assertNotNull(entityPayload);
376
377     MockSearchResponse searchResponse = mapper.readValue(entityPayload, MockSearchResponse.class);
378
379     assertEquals(13, searchResponse.getTotalFound());
380     assertEquals(13, searchResponse.getSuggestions().size());
381     
382     /**
383      * There should be an even divide of suggestions per search provider relative
384      * to the suggestions available per search provider.
385      * Alpha has 45 suggestions
386      * Bravo has 1  suggestion
387      * Gamma has 99 suggestions
388      * 
389      * We only asked for 13 suggestions to be returned, so based on the suggestion
390      * distribution algorithm we will get a fair distribution of suggestions per provider
391      * relative to what each provider has available.  Resulting in:
392      * 6 from Alpha
393      * 1 from Bravo
394      * 6 from Gamma
395      * 
396      */
397     
398     assertEquals( 6, countSuggestions("alpha", searchResponse));
399     assertEquals( 1, countSuggestions("bravo", searchResponse));
400     assertEquals( 6, countSuggestions("gamma", searchResponse));
401     
402   }
403   
404   @Test
405   public void testSearch_search_when_ThreeSearchProviders_wantedMoreSuggestionsThanAvailable() throws IOException {
406
407     // mock env setup
408
409     initializeSearchMocks(getSearchRequestJson("vnfs",13));
410
411     SearchProviderRegistry searchProviderRegistry = new SearchProviderRegistry();
412     
413     AlphaSearchProvider alpha = new AlphaSearchProvider();
414     BravoSearchProvider bravo = new BravoSearchProvider();
415     GammaSearchProvider gamma = new GammaSearchProvider();
416     
417     searchProviderRegistry.addSearchProvider(alpha);
418     searchProviderRegistry.addSearchProvider(bravo);
419     searchProviderRegistry.addSearchProvider(gamma);
420     
421     unifiedSearchProcessor.setSearchProviderRegistry(searchProviderRegistry);
422     
423     addSuggestions(1,"alpha",alpha);
424     addSuggestions(4,"bravo",bravo);
425     addSuggestions(0,"gamma",gamma);
426     
427     // method under test
428     unifiedSearchProcessor.search(exchange);
429     
430     assertEquals(200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));
431
432     String entityPayload = exchange.getOut().getBody(String.class); 
433     assertNotNull(entityPayload);
434
435     MockSearchResponse searchResponse = mapper.readValue(entityPayload, MockSearchResponse.class);
436
437     assertEquals(5, searchResponse.getTotalFound());
438     assertEquals(5, searchResponse.getSuggestions().size());
439     
440     assertEquals( 1, countSuggestions("alpha", searchResponse));
441     assertEquals( 4, countSuggestions("bravo", searchResponse));
442     assertEquals( 0, countSuggestions("gamma", searchResponse));
443     
444   }
445 }