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 org.junit.Before;
34 import org.junit.Test;
35 import org.mockito.ArgumentMatchers;
36 import org.mockito.Mockito;
37 import org.onap.aai.restclient.client.OperationResult;
38 import org.onap.aai.sparky.aggregation.sync.AggregationSynchronizer;
39 import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor;
40 import org.onap.aai.sparky.config.oxm.OxmEntityLookup;
41 import org.onap.aai.sparky.dal.ActiveInventoryAdapter;
42 import org.onap.aai.sparky.search.SearchServiceAdapter;
43 import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig;
44 import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig;
45 import org.onap.aai.sparky.sync.enumeration.OperationState;
46 import org.onap.aai.sparky.sync.enumeration.SynchronizerState;
47 import org.onap.aai.sparky.util.TestResourceLoader;
49 public class AggregationSynchronizerTest {
51 //private static Logger LOG = LoggerFactory.getInstance().getLogger(AggregationSynchronizerTest.class);
52 private static SecureRandom secureRandom = new SecureRandom();
53 private AggregationSynchronizer aggregationSynchronizer;
55 private ElasticSearchSchemaConfig esSchemaConfig;
56 private NetworkStatisticsConfig aaiStatConfig;
57 private NetworkStatisticsConfig esStatConfig;
58 private OxmEntityLookup oxmEntityLookup;
59 private SearchServiceAdapter searchServiceAdapter;
60 private ActiveInventoryAdapter aaiAdapter;
65 public void init() throws Exception {
67 esSchemaConfig = new ElasticSearchSchemaConfig();
68 esSchemaConfig.setIndexDocType("default");
69 esSchemaConfig.setIndexMappingsFileName(null);
70 esSchemaConfig.setIndexName("aggregation-index-name");
71 esSchemaConfig.setIndexSettingsFileName(null);
74 aaiStatConfig = new NetworkStatisticsConfig();
76 aaiStatConfig.setNumSamplesPerThreadForRunningAverage(100);
78 aaiStatConfig.setBytesHistogramLabel("[Response Size In Bytes]");
79 aaiStatConfig.setBytesHistogramMaxYAxis(1000000L);
80 aaiStatConfig.setBytesHistogramNumBins(20);
81 aaiStatConfig.setBytesHistogramNumDecimalPoints(2);
83 aaiStatConfig.setQueueLengthHistogramLabel("[Queue Item Length]");
84 aaiStatConfig.setQueueLengthHistogramMaxYAxis(20000);
85 aaiStatConfig.setQueueLengthHistogramNumBins(20);
86 aaiStatConfig.setQueueLengthHistogramNumDecimalPoints(2);
88 aaiStatConfig.setTaskAgeHistogramLabel("[Task Age In Ms]");
89 aaiStatConfig.setTaskAgeHistogramMaxYAxis(600000L);
90 aaiStatConfig.setTaskAgeHistogramNumBins(20);
91 aaiStatConfig.setTaskAgeHistogramNumDecimalPoints(2);
93 aaiStatConfig.setResponseTimeHistogramLabel("[Response Time In Ms]");
94 aaiStatConfig.setResponseTimeHistogramMaxYAxis(1000L);
95 aaiStatConfig.setResponseTimeHistogramNumBins(20);
96 aaiStatConfig.setResponseTimeHistogramNumDecimalPoints(2);
98 aaiStatConfig.setTpsHistogramLabel("[Transactions Per Second]");
99 aaiStatConfig.setTpsHistogramMaxYAxis(100);
100 aaiStatConfig.setTpsHistogramNumBins(20);
101 aaiStatConfig.setTpsHistogramNumDecimalPoints(2);
103 esStatConfig = new NetworkStatisticsConfig();
105 esStatConfig.setNumSamplesPerThreadForRunningAverage(100);
107 esStatConfig.setBytesHistogramLabel("[Response Size In Bytes]");
108 esStatConfig.setBytesHistogramMaxYAxis(1000000L);
109 esStatConfig.setBytesHistogramNumBins(20);
110 esStatConfig.setBytesHistogramNumDecimalPoints(2);
112 esStatConfig.setQueueLengthHistogramLabel("[Queue Item Length]");
113 esStatConfig.setQueueLengthHistogramMaxYAxis(20000);
114 esStatConfig.setQueueLengthHistogramNumBins(20);
115 esStatConfig.setQueueLengthHistogramNumDecimalPoints(2);
117 esStatConfig.setTaskAgeHistogramLabel("[Task Age In Ms]");
118 esStatConfig.setTaskAgeHistogramMaxYAxis(600000L);
119 esStatConfig.setTaskAgeHistogramNumBins(20);
120 esStatConfig.setTaskAgeHistogramNumDecimalPoints(2);
122 esStatConfig.setResponseTimeHistogramLabel("[Response Time In Ms]");
123 esStatConfig.setResponseTimeHistogramMaxYAxis(10000L);
124 esStatConfig.setResponseTimeHistogramNumBins(20);
125 esStatConfig.setResponseTimeHistogramNumDecimalPoints(2);
127 esStatConfig.setTpsHistogramLabel("[Transactions Per Second]");
128 esStatConfig.setTpsHistogramMaxYAxis(100);
129 esStatConfig.setTpsHistogramNumBins(20);
130 esStatConfig.setTpsHistogramNumDecimalPoints(2);
132 oxmEntityLookup = new OxmEntityLookup();
134 searchServiceAdapter = Mockito.mock(SearchServiceAdapter.class);
135 aaiAdapter = Mockito.mock(ActiveInventoryAdapter.class);
137 Map<String,OxmEntityDescriptor> oxmEntityDescriptors = new HashMap<String,OxmEntityDescriptor>();
139 OxmEntityDescriptor complexDescriptor = new OxmEntityDescriptor();
140 complexDescriptor.setEntityName("complex");
141 List<String> pkeyNames = new ArrayList<String>();
142 pkeyNames.add("physical-location-id");
144 complexDescriptor.setPrimaryKeyAttributeNames(pkeyNames);
146 oxmEntityDescriptors.put("complex", complexDescriptor);
148 oxmEntityLookup.setEntityDescriptors(oxmEntityDescriptors);
155 public void validateBasicConstruction() throws Exception {
157 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
158 esStatConfig, oxmEntityLookup);
160 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
161 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
163 assertNotNull(aggregationSynchronizer.getAaiAdapter());
164 assertNotNull(aggregationSynchronizer.getSearchServiceAdapter());
169 public void validateSmallSync() throws Exception {
171 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
172 esStatConfig, oxmEntityLookup);
174 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
175 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
177 String nodesQueryResponse = TestResourceLoader
178 .getTestResourceDataJson("/sync/aai/activeInventory_complex_nodesQuery_response.json");
180 OperationResult complexSelfLinks = new OperationResult();
182 complexSelfLinks.setResultCode(200);
183 complexSelfLinks.setResult(nodesQueryResponse);
185 Mockito.when( aaiAdapter.getSelfLinksByEntityType("complex")).thenReturn(complexSelfLinks);
187 for (int x = 1; x <= 5; x++) {
189 Mockito.when(aaiAdapter.repairSelfLink(ArgumentMatchers.contains("complex" + x), Mockito.anyString()))
190 .thenReturn("https://server.proxy:8443/aai/v11/cloud-infrastructure/complexes/complex" + x);
192 Mockito.when(aaiAdapter.queryActiveInventoryWithRetries(ArgumentMatchers.contains("complex" + x),
193 Mockito.anyString(), Mockito.anyInt(),Mockito.anyString()))
194 .thenReturn(new OperationResult(200, TestResourceLoader
195 .getTestResourceDataJson("/sync/aai/complex" + x + "_fullDepth_aaiEntityRetrieval.json")));
199 Mockito.when(searchServiceAdapter.buildSearchServiceDocUrl(Mockito.anyString(), Mockito.anyString())).thenReturn(
200 "http://localhost:9200/myindex/mytype/doc1", "http://localhost:9200/myindex/mytype/doc2",
201 "http://localhost:9200/myindex/mytype/doc3", "http://localhost:9200/myindex/mytype/doc4",
202 "http://localhost:9200/myindex/mytype/doc5");
205 * Our initial gets from elastic search should be record-not-found
207 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc1"), Mockito.any())).thenReturn(new OperationResult(404,null));
208 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc2"), Mockito.any())).thenReturn(new OperationResult(404,null));
209 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc3"), Mockito.any())).thenReturn(new OperationResult(404,null));
210 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc4"), Mockito.any())).thenReturn(new OperationResult(404,null));
211 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc5"), Mockito.any())).thenReturn(new OperationResult(404,null));
214 Mockito.when(searchServiceAdapter.doPut(ArgumentMatchers.contains("doc"), Mockito.any(), Mockito.any()))
215 .thenReturn(new OperationResult(200, null));
217 OperationState syncState = aggregationSynchronizer.doSync();
218 assertEquals(OperationState.OK, syncState);
220 assertEquals(SynchronizerState.IDLE, aggregationSynchronizer.getState());
221 assertNotNull(aggregationSynchronizer.getStatReport(false));
222 assertNotNull(aggregationSynchronizer.getStatReport(true));
224 aggregationSynchronizer.clearCache();
225 aggregationSynchronizer.shutdown();
231 public void validateSmallSyncWithRetries() throws Exception {
233 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
234 esStatConfig, oxmEntityLookup);
236 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
237 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
239 String nodesQueryResponse = TestResourceLoader
240 .getTestResourceDataJson("/sync/aai/activeInventory_complex_nodesQuery_response.json");
242 OperationResult complexSelfLinks = new OperationResult();
244 complexSelfLinks.setResultCode(200);
245 complexSelfLinks.setResult(nodesQueryResponse);
247 Mockito.when( aaiAdapter.getSelfLinksByEntityType("complex")).thenReturn(complexSelfLinks);
249 for (int x = 1; x <= 5; x++) {
251 Mockito.when(aaiAdapter.repairSelfLink(ArgumentMatchers.contains("complex" + x), Mockito.anyString()))
252 .thenReturn("https://server.proxy:8443/aai/v11/cloud-infrastructure/complexes/complex" + x);
254 Mockito.when(aaiAdapter.queryActiveInventoryWithRetries(ArgumentMatchers.contains("complex" + x),
255 Mockito.anyString(), Mockito.anyInt(),Mockito.anyString()))
256 .thenReturn(new OperationResult(200, TestResourceLoader
257 .getTestResourceDataJson("/sync/aai/complex" + x + "_fullDepth_aaiEntityRetrieval.json")));
261 Mockito.when(searchServiceAdapter.buildSearchServiceDocUrl(Mockito.anyString(), Mockito.anyString())).thenReturn(
262 "http://localhost:9200/myindex/mytype/doc1", "http://localhost:9200/myindex/mytype/doc2",
263 "http://localhost:9200/myindex/mytype/doc3", "http://localhost:9200/myindex/mytype/doc4",
264 "http://localhost:9200/myindex/mytype/doc5");
267 * Our initial gets from elastic search should be record-not-found
269 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc1"), Mockito.any())).thenReturn(new OperationResult(404,null));
270 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc2"), Mockito.any())).thenReturn(new OperationResult(404,null));
271 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc3"), Mockito.any())).thenReturn(new OperationResult(404,null));
272 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc4"), Mockito.any())).thenReturn(new OperationResult(404,null));
273 Mockito.when( searchServiceAdapter.doGet(ArgumentMatchers.contains("doc5"), Mockito.any())).thenReturn(new OperationResult(404,null));
276 // 409 is the elastic search version conflict code, which will result in the entries being added
277 // to our retry queue and re-attempted a couple times.
279 Mockito.when(searchServiceAdapter.doPut(ArgumentMatchers.contains("doc"), Mockito.any(), Mockito.any()))
280 .thenReturn(new OperationResult(409, null));
282 OperationState syncState = aggregationSynchronizer.doSync();
283 assertEquals(OperationState.OK, syncState);
285 assertEquals(SynchronizerState.IDLE, aggregationSynchronizer.getState());
286 assertNotNull(aggregationSynchronizer.getStatReport(false));
287 assertNotNull(aggregationSynchronizer.getStatReport(true));
289 aggregationSynchronizer.clearCache();
290 aggregationSynchronizer.shutdown();
295 public void validateSmallSyncWithDocumentElementMerges() throws Exception {
297 aggregationSynchronizer = new AggregationSynchronizer("complex", esSchemaConfig, 5, 5, 5, aaiStatConfig,
298 esStatConfig, oxmEntityLookup);
300 aggregationSynchronizer.setAaiAdapter(aaiAdapter);
301 aggregationSynchronizer.setSearchServiceAdapter(searchServiceAdapter);
303 String nodesQueryResponse = TestResourceLoader
304 .getTestResourceDataJson("/sync/aai/activeInventory_complex_nodesQuery_response.json");
306 OperationResult complexSelfLinks = new OperationResult();
308 complexSelfLinks.setResultCode(200);
309 complexSelfLinks.setResult(nodesQueryResponse);
311 Mockito.when( aaiAdapter.getSelfLinksByEntityType("complex")).thenReturn(complexSelfLinks);
313 for (int x = 1; x <= 5; x++) {
315 Mockito.when(aaiAdapter.repairSelfLink(ArgumentMatchers.contains("complex" + x), Mockito.anyString()))
316 .thenReturn("https://server.proxy:8443/aai/v11/cloud-infrastructure/complexes/complex" + x);
318 Mockito.when(aaiAdapter.queryActiveInventoryWithRetries(ArgumentMatchers.contains("complex" + x),
319 Mockito.anyString(), Mockito.anyInt(),Mockito.anyString()))
320 .thenReturn(new OperationResult(200, TestResourceLoader
321 .getTestResourceDataJson("/sync/aai/complex" + x + "_fullDepth_aaiEntityRetrieval.json")));
325 Mockito.when(searchServiceAdapter.buildSearchServiceDocUrl(Mockito.anyString(), Mockito.anyString())).thenReturn(
326 "http://localhost:9200/myindex/mytype/doc1", "http://localhost:9200/myindex/mytype/doc2",
327 "http://localhost:9200/myindex/mytype/doc3", "http://localhost:9200/myindex/mytype/doc4",
328 "http://localhost:9200/myindex/mytype/doc5");
331 * Our initial gets from elastic search return 200 ok with a found entity document requiring a doc update
333 Mockito.when(searchServiceAdapter.doGet(ArgumentMatchers.contains("doc1"), Mockito.any())).thenReturn(new OperationResult(200,
334 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch1.json")));
336 Mockito.when(searchServiceAdapter.doGet(ArgumentMatchers.contains("doc2"), Mockito.any())).thenReturn(new OperationResult(200,
337 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch2.json")));
339 Mockito.when(searchServiceAdapter.doGet(ArgumentMatchers.contains("doc3"), Mockito.any())).thenReturn(new OperationResult(200,
340 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch3.json")));
342 Mockito.when(searchServiceAdapter.doGet(ArgumentMatchers.contains("doc4"), Mockito.any())).thenReturn(new OperationResult(200,
343 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch4.json")));
345 Mockito.when(searchServiceAdapter.doGet(ArgumentMatchers.contains("doc5"), Mockito.any())).thenReturn(new OperationResult(200,
346 TestResourceLoader.getTestResourceDataJson("/sync/ElasticSearch/docEntityFromElasticSearch5.json")));
348 Mockito.when(searchServiceAdapter.doPut(ArgumentMatchers.contains("doc"), Mockito.any(), Mockito.any()))
349 .thenReturn(new OperationResult(200, null));
351 OperationState syncState = aggregationSynchronizer.doSync();
352 assertEquals(OperationState.OK, syncState);
354 assertEquals(SynchronizerState.IDLE, aggregationSynchronizer.getState());
355 assertNotNull(aggregationSynchronizer.getStatReport(false));
356 assertNotNull(aggregationSynchronizer.getStatReport(true));
358 aggregationSynchronizer.clearCache();
359 aggregationSynchronizer.shutdown();