2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.aai.sparky.sync;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
27 import java.security.SecureRandom;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
33 import javax.ws.rs.core.MediaType;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.mockito.Matchers;
38 import org.mockito.Mockito;
39 import org.onap.aai.restclient.client.OperationResult;
40 import org.onap.aai.sparky.aggregation.sync.AggregationSynchronizer;
41 import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor;
42 import org.onap.aai.sparky.config.oxm.OxmEntityLookup;
43 import org.onap.aai.sparky.dal.ActiveInventoryAdapter;
44 import org.onap.aai.sparky.search.SearchServiceAdapter;
45 import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig;
46 import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig;
47 import org.onap.aai.sparky.sync.enumeration.OperationState;
48 import org.onap.aai.sparky.sync.enumeration.SynchronizerState;
49 import org.onap.aai.sparky.util.TestResourceLoader;
51 public class AggregationSynchronizerTest {
53 //private static Logger LOG = LoggerFactory.getInstance().getLogger(AggregationSynchronizerTest.class);
54 private static SecureRandom secureRandom = new SecureRandom();
55 private AggregationSynchronizer aggregationSynchronizer;
57 private ElasticSearchSchemaConfig esSchemaConfig;
58 private NetworkStatisticsConfig aaiStatConfig;
59 private NetworkStatisticsConfig esStatConfig;
60 private OxmEntityLookup oxmEntityLookup;
61 private SearchServiceAdapter searchServiceAdapter;
62 private ActiveInventoryAdapter aaiAdapter;
67 public void init() throws Exception {
69 esSchemaConfig = new ElasticSearchSchemaConfig();
70 esSchemaConfig.setIndexDocType("default");
71 esSchemaConfig.setIndexMappingsFileName(null);
72 esSchemaConfig.setIndexName("aggregation-index-name");
73 esSchemaConfig.setIndexSettingsFileName(null);
76 aaiStatConfig = new NetworkStatisticsConfig();
78 aaiStatConfig.setNumSamplesPerThreadForRunningAverage(100);
80 aaiStatConfig.setBytesHistogramLabel("[Response Size In Bytes]");
81 aaiStatConfig.setBytesHistogramMaxYAxis(1000000L);
82 aaiStatConfig.setBytesHistogramNumBins(20);
83 aaiStatConfig.setBytesHistogramNumDecimalPoints(2);
85 aaiStatConfig.setQueueLengthHistogramLabel("[Queue Item Length]");
86 aaiStatConfig.setQueueLengthHistogramMaxYAxis(20000);
87 aaiStatConfig.setQueueLengthHistogramNumBins(20);
88 aaiStatConfig.setQueueLengthHistogramNumDecimalPoints(2);
90 aaiStatConfig.setTaskAgeHistogramLabel("[Task Age In Ms]");
91 aaiStatConfig.setTaskAgeHistogramMaxYAxis(600000L);
92 aaiStatConfig.setTaskAgeHistogramNumBins(20);
93 aaiStatConfig.setTaskAgeHistogramNumDecimalPoints(2);
95 aaiStatConfig.setResponseTimeHistogramLabel("[Response Time In Ms]");
96 aaiStatConfig.setResponseTimeHistogramMaxYAxis(1000L);
97 aaiStatConfig.setResponseTimeHistogramNumBins(20);
98 aaiStatConfig.setResponseTimeHistogramNumDecimalPoints(2);
100 aaiStatConfig.setTpsHistogramLabel("[Transactions Per Second]");
101 aaiStatConfig.setTpsHistogramMaxYAxis(100);
102 aaiStatConfig.setTpsHistogramNumBins(20);
103 aaiStatConfig.setTpsHistogramNumDecimalPoints(2);
105 esStatConfig = new NetworkStatisticsConfig();
107 esStatConfig.setNumSamplesPerThreadForRunningAverage(100);
109 esStatConfig.setBytesHistogramLabel("[Response Size In Bytes]");
110 esStatConfig.setBytesHistogramMaxYAxis(1000000L);
111 esStatConfig.setBytesHistogramNumBins(20);
112 esStatConfig.setBytesHistogramNumDecimalPoints(2);
114 esStatConfig.setQueueLengthHistogramLabel("[Queue Item Length]");
115 esStatConfig.setQueueLengthHistogramMaxYAxis(20000);
116 esStatConfig.setQueueLengthHistogramNumBins(20);
117 esStatConfig.setQueueLengthHistogramNumDecimalPoints(2);
119 esStatConfig.setTaskAgeHistogramLabel("[Task Age In Ms]");
120 esStatConfig.setTaskAgeHistogramMaxYAxis(600000L);
121 esStatConfig.setTaskAgeHistogramNumBins(20);
122 esStatConfig.setTaskAgeHistogramNumDecimalPoints(2);
124 esStatConfig.setResponseTimeHistogramLabel("[Response Time In Ms]");
125 esStatConfig.setResponseTimeHistogramMaxYAxis(10000L);
126 esStatConfig.setResponseTimeHistogramNumBins(20);
127 esStatConfig.setResponseTimeHistogramNumDecimalPoints(2);
129 esStatConfig.setTpsHistogramLabel("[Transactions Per Second]");
130 esStatConfig.setTpsHistogramMaxYAxis(100);
131 esStatConfig.setTpsHistogramNumBins(20);
132 esStatConfig.setTpsHistogramNumDecimalPoints(2);
134 oxmEntityLookup = new OxmEntityLookup();
136 searchServiceAdapter = Mockito.mock(SearchServiceAdapter.class);
137 aaiAdapter = Mockito.mock(ActiveInventoryAdapter.class);
139 Map<String,OxmEntityDescriptor> oxmEntityDescriptors = new HashMap<String,OxmEntityDescriptor>();
141 OxmEntityDescriptor complexDescriptor = new OxmEntityDescriptor();
142 complexDescriptor.setEntityName("complex");
143 List<String> pkeyNames = new ArrayList<String>();
144 pkeyNames.add("physical-location-id");
146 complexDescriptor.setPrimaryKeyAttributeNames(pkeyNames);
148 oxmEntityDescriptors.put("complex", complexDescriptor);
150 oxmEntityLookup.setEntityDescriptors(oxmEntityDescriptors);
157 public void validateBasicConstruction() throws Exception {
159 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
160 esStatConfig, oxmEntityLookup);
162 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
163 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
165 assertNotNull(aggregationSynchronizer.getAaiAdapter());
166 assertNotNull(aggregationSynchronizer.getSearchServiceAdapter());
171 public void validateSmallSync() throws Exception {
173 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
174 esStatConfig, oxmEntityLookup);
176 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
177 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
179 String nodesQueryResponse = TestResourceLoader
180 .getTestResourceDataJson("/sync/aai/activeInventory_complex_nodesQuery_response.json");
182 OperationResult complexSelfLinks = new OperationResult();
184 complexSelfLinks.setResultCode(200);
185 complexSelfLinks.setResult(nodesQueryResponse);
187 Mockito.when( aaiAdapter.getSelfLinksByEntityType("complex")).thenReturn(complexSelfLinks);
189 for (int x = 1; x <= 5; x++) {
191 Mockito.when(aaiAdapter.repairSelfLink(Matchers.contains("complex" + x), Mockito.anyString()))
192 .thenReturn("https://server.proxy:8443/aai/v11/cloud-infrastructure/complexes/complex" + x);
194 Mockito.when(aaiAdapter.queryActiveInventoryWithRetries(Matchers.contains("complex" + x),
195 Mockito.anyString(), Mockito.anyInt(),Mockito.anyString()))
196 .thenReturn(new OperationResult(200, TestResourceLoader
197 .getTestResourceDataJson("/sync/aai/complex" + x + "_fullDepth_aaiEntityRetrieval.json")));
201 Mockito.when(searchServiceAdapter.buildSearchServiceDocUrl(Mockito.anyString(), Mockito.anyString())).thenReturn(
202 "http://localhost:9200/myindex/mytype/doc1", "http://localhost:9200/myindex/mytype/doc2",
203 "http://localhost:9200/myindex/mytype/doc3", "http://localhost:9200/myindex/mytype/doc4",
204 "http://localhost:9200/myindex/mytype/doc5");
207 * Our initial gets from elastic search should be record-not-found
209 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc1"), Mockito.any())).thenReturn(new OperationResult(404,null));
210 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc2"), Mockito.any())).thenReturn(new OperationResult(404,null));
211 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc3"), Mockito.any())).thenReturn(new OperationResult(404,null));
212 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc4"), Mockito.any())).thenReturn(new OperationResult(404,null));
213 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc5"), Mockito.any())).thenReturn(new OperationResult(404,null));
216 Mockito.when(searchServiceAdapter.doPut(Matchers.contains("doc"), Mockito.any(), Mockito.any()))
217 .thenReturn(new OperationResult(200, null));
219 OperationState syncState = aggregationSynchronizer.doSync();
220 assertEquals(OperationState.OK, syncState);
222 assertEquals(SynchronizerState.IDLE, aggregationSynchronizer.getState());
223 assertNotNull(aggregationSynchronizer.getStatReport(false));
224 assertNotNull(aggregationSynchronizer.getStatReport(true));
226 aggregationSynchronizer.clearCache();
227 aggregationSynchronizer.shutdown();
233 public void validateSmallSyncWithRetries() throws Exception {
235 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
236 esStatConfig, oxmEntityLookup);
238 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
239 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
241 String nodesQueryResponse = TestResourceLoader
242 .getTestResourceDataJson("/sync/aai/activeInventory_complex_nodesQuery_response.json");
244 OperationResult complexSelfLinks = new OperationResult();
246 complexSelfLinks.setResultCode(200);
247 complexSelfLinks.setResult(nodesQueryResponse);
249 Mockito.when( aaiAdapter.getSelfLinksByEntityType("complex")).thenReturn(complexSelfLinks);
251 for (int x = 1; x <= 5; x++) {
253 Mockito.when(aaiAdapter.repairSelfLink(Matchers.contains("complex" + x), Mockito.anyString()))
254 .thenReturn("https://server.proxy:8443/aai/v11/cloud-infrastructure/complexes/complex" + x);
256 Mockito.when(aaiAdapter.queryActiveInventoryWithRetries(Matchers.contains("complex" + x),
257 Mockito.anyString(), Mockito.anyInt(),Mockito.anyString()))
258 .thenReturn(new OperationResult(200, TestResourceLoader
259 .getTestResourceDataJson("/sync/aai/complex" + x + "_fullDepth_aaiEntityRetrieval.json")));
263 Mockito.when(searchServiceAdapter.buildSearchServiceDocUrl(Mockito.anyString(), Mockito.anyString())).thenReturn(
264 "http://localhost:9200/myindex/mytype/doc1", "http://localhost:9200/myindex/mytype/doc2",
265 "http://localhost:9200/myindex/mytype/doc3", "http://localhost:9200/myindex/mytype/doc4",
266 "http://localhost:9200/myindex/mytype/doc5");
269 * Our initial gets from elastic search should be record-not-found
271 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc1"), Mockito.any())).thenReturn(new OperationResult(404,null));
272 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc2"), Mockito.any())).thenReturn(new OperationResult(404,null));
273 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc3"), Mockito.any())).thenReturn(new OperationResult(404,null));
274 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc4"), Mockito.any())).thenReturn(new OperationResult(404,null));
275 Mockito.when( searchServiceAdapter.doGet(Matchers.contains("doc5"), Mockito.any())).thenReturn(new OperationResult(404,null));
278 // 409 is the elastic search version conflict code, which will result in the entries being added
279 // to our retry queue and re-attempted a couple times.
281 Mockito.when(searchServiceAdapter.doPut(Matchers.contains("doc"), Mockito.any(), Mockito.any()))
282 .thenReturn(new OperationResult(409, null));
284 OperationState syncState = aggregationSynchronizer.doSync();
285 assertEquals(OperationState.OK, syncState);
287 assertEquals(SynchronizerState.IDLE, aggregationSynchronizer.getState());
288 assertNotNull(aggregationSynchronizer.getStatReport(false));
289 assertNotNull(aggregationSynchronizer.getStatReport(true));
291 aggregationSynchronizer.clearCache();
292 aggregationSynchronizer.shutdown();
297 public void validateSmallSyncWithDocumentElementMerges() throws Exception {
299 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
300 esStatConfig, oxmEntityLookup);
302 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
303 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
305 String nodesQueryResponse = TestResourceLoader
306 .getTestResourceDataJson("/sync/aai/activeInventory_complex_nodesQuery_response.json");
308 OperationResult complexSelfLinks = new OperationResult();
310 complexSelfLinks.setResultCode(200);
311 complexSelfLinks.setResult(nodesQueryResponse);
313 Mockito.when( aaiAdapter.getSelfLinksByEntityType("complex")).thenReturn(complexSelfLinks);
315 for (int x = 1; x <= 5; x++) {
317 Mockito.when(aaiAdapter.repairSelfLink(Matchers.contains("complex" + x), Mockito.anyString()))
318 .thenReturn("https://server.proxy:8443/aai/v11/cloud-infrastructure/complexes/complex" + x);
320 Mockito.when(aaiAdapter.queryActiveInventoryWithRetries(Matchers.contains("complex" + x),
321 Mockito.anyString(), Mockito.anyInt(),Mockito.anyString()))
322 .thenReturn(new OperationResult(200, TestResourceLoader
323 .getTestResourceDataJson("/sync/aai/complex" + x + "_fullDepth_aaiEntityRetrieval.json")));
327 Mockito.when(searchServiceAdapter.buildSearchServiceDocUrl(Mockito.anyString(), Mockito.anyString())).thenReturn(
328 "http://localhost:9200/myindex/mytype/doc1", "http://localhost:9200/myindex/mytype/doc2",
329 "http://localhost:9200/myindex/mytype/doc3", "http://localhost:9200/myindex/mytype/doc4",
330 "http://localhost:9200/myindex/mytype/doc5");
333 * Our initial gets from elastic search return 200 ok with a found entity document requiring a doc update
335 Mockito.when(searchServiceAdapter.doGet(Matchers.contains("doc1"), Mockito.any())).thenReturn(new OperationResult(200,
336 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch1.json")));
338 Mockito.when(searchServiceAdapter.doGet(Matchers.contains("doc2"), Mockito.any())).thenReturn(new OperationResult(200,
339 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch2.json")));
341 Mockito.when(searchServiceAdapter.doGet(Matchers.contains("doc3"), Mockito.any())).thenReturn(new OperationResult(200,
342 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch3.json")));
344 Mockito.when(searchServiceAdapter.doGet(Matchers.contains("doc4"), Mockito.any())).thenReturn(new OperationResult(200,
345 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch4.json")));
347 Mockito.when(searchServiceAdapter.doGet(Matchers.contains("doc5"), Mockito.any())).thenReturn(new OperationResult(200,
348 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch5.json")));
350 Mockito.when(searchServiceAdapter.doPut(Matchers.contains("doc"), Mockito.any(), Mockito.any()))
351 .thenReturn(new OperationResult(200, null));
353 OperationState syncState = aggregationSynchronizer.doSync();
354 assertEquals(OperationState.OK, syncState);
356 assertEquals(SynchronizerState.IDLE, aggregationSynchronizer.getState());
357 assertNotNull(aggregationSynchronizer.getStatReport(false));
358 assertNotNull(aggregationSynchronizer.getStatReport(true));
360 aggregationSynchronizer.clearCache();
361 aggregationSynchronizer.shutdown();