Add test to verify the count amount of networks during summarizing.
[vid.git] / vid-app-common / src / test / java / org / onap / vid / services / AsyncInstantiationBusinessLogicTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.vid.services;
22
23 import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
24 import static net.javacrumbs.jsonunit.JsonAssert.whenIgnoringPaths;
25 import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
26 import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
27 import static org.hamcrest.MatcherAssert.assertThat;
28 import static org.hamcrest.Matchers.containsInAnyOrder;
29 import static org.hamcrest.Matchers.containsString;
30 import static org.hamcrest.Matchers.hasItem;
31 import static org.hamcrest.Matchers.hasItems;
32 import static org.hamcrest.Matchers.hasProperty;
33 import static org.hamcrest.Matchers.hasSize;
34 import static org.hamcrest.Matchers.is;
35 import static org.hamcrest.Matchers.matchesPattern;
36 import static org.hamcrest.Matchers.not;
37 import static org.hamcrest.Matchers.nullValue;
38 import static org.hamcrest.core.Every.everyItem;
39 import static org.hamcrest.core.IsEqual.equalTo;
40 import static org.mockito.ArgumentMatchers.any;
41 import static org.mockito.ArgumentMatchers.anyInt;
42 import static org.mockito.ArgumentMatchers.anyString;
43 import static org.mockito.ArgumentMatchers.eq;
44 import static org.mockito.Mockito.doNothing;
45 import static org.mockito.Mockito.doReturn;
46 import static org.mockito.Mockito.doThrow;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.reset;
49 import static org.mockito.Mockito.spy;
50 import static org.mockito.Mockito.times;
51 import static org.mockito.Mockito.verify;
52 import static org.mockito.Mockito.when;
53 import static org.onap.vid.job.Job.JobStatus.COMPLETED;
54 import static org.onap.vid.job.Job.JobStatus.COMPLETED_WITH_ERRORS;
55 import static org.onap.vid.job.Job.JobStatus.COMPLETED_WITH_NO_ACTION;
56 import static org.onap.vid.job.Job.JobStatus.FAILED;
57 import static org.onap.vid.job.Job.JobStatus.IN_PROGRESS;
58 import static org.onap.vid.job.Job.JobStatus.PAUSE;
59 import static org.onap.vid.job.Job.JobStatus.PENDING;
60 import static org.onap.vid.job.Job.JobStatus.STOPPED;
61 import static org.onap.vid.testUtils.TestUtils.generateRandomAlphaNumeric;
62 import static org.testng.Assert.assertEquals;
63 import static org.testng.Assert.assertFalse;
64 import static org.testng.Assert.assertNotNull;
65 import static org.testng.Assert.assertNull;
66 import static org.testng.Assert.assertTrue;
67
68 import com.fasterxml.jackson.databind.ObjectMapper;
69 import com.google.common.collect.ImmutableList;
70 import com.google.common.collect.ImmutableMap;
71 import java.io.IOException;
72 import java.lang.reflect.Method;
73 import java.net.URL;
74 import java.time.Instant;
75 import java.time.LocalDate;
76 import java.time.LocalDateTime;
77 import java.time.ZoneId;
78 import java.time.ZonedDateTime;
79 import java.util.ArrayList;
80 import java.util.Arrays;
81 import java.util.Collections;
82 import java.util.Comparator;
83 import java.util.Date;
84 import java.util.HashMap;
85 import java.util.HashSet;
86 import java.util.List;
87 import java.util.Map;
88 import java.util.Optional;
89 import java.util.Set;
90 import java.util.UUID;
91 import java.util.concurrent.Callable;
92 import java.util.concurrent.ExecutorService;
93 import java.util.concurrent.Executors;
94 import java.util.stream.Collectors;
95 import java.util.stream.IntStream;
96 import org.apache.commons.io.IOUtils;
97 import org.apache.commons.lang3.time.DateUtils;
98 import org.jetbrains.annotations.NotNull;
99 import org.json.JSONException;
100 import org.mockito.ArgumentCaptor;
101 import org.mockito.Mock;
102 import org.mockito.Mockito;
103 import org.mockito.MockitoAnnotations;
104 import org.mockito.stubbing.Answer;
105 import org.onap.portalsdk.core.util.SystemProperties;
106 import org.onap.vid.aai.ExceptionWithRequestInfo;
107 import org.onap.vid.aai.model.ResourceType;
108 import org.onap.vid.changeManagement.RequestDetailsWrapper;
109 import org.onap.vid.config.DataSourceConfig;
110 import org.onap.vid.config.MockedAaiClientAndFeatureManagerConfig;
111 import org.onap.vid.dal.AsyncInstantiationRepository;
112 import org.onap.vid.exceptions.MaxRetriesException;
113 import org.onap.vid.exceptions.NotFoundException;
114 import org.onap.vid.exceptions.OperationNotAllowedException;
115 import org.onap.vid.job.Job;
116 import org.onap.vid.job.Job.JobStatus;
117 import org.onap.vid.job.JobAdapter;
118 import org.onap.vid.job.JobType;
119 import org.onap.vid.job.JobsBrokerService;
120 import org.onap.vid.job.command.MsoRequestBuilder;
121 import org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator;
122 import org.onap.vid.job.impl.JobDaoImpl;
123 import org.onap.vid.job.impl.JobSharedData;
124 import org.onap.vid.model.Action;
125 import org.onap.vid.model.JobAuditStatus;
126 import org.onap.vid.model.NameCounter;
127 import org.onap.vid.model.ResourceInfo;
128 import org.onap.vid.model.ServiceInfo;
129 import org.onap.vid.model.serviceInstantiation.BaseResource;
130 import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
131 import org.onap.vid.model.serviceInstantiation.Vnf;
132 import org.onap.vid.mso.MsoOperationalEnvironmentTest;
133 import org.onap.vid.mso.RestObject;
134 import org.onap.vid.mso.model.ModelInfo;
135 import org.onap.vid.mso.model.ServiceInstantiationRequestDetails;
136 import org.onap.vid.mso.rest.AsyncRequestStatus;
137 import org.onap.vid.mso.rest.RequestStatus;
138 import org.onap.vid.properties.Features;
139 import org.onap.vid.testUtils.TestUtils;
140 import org.onap.vid.utils.DaoUtils;
141 import org.onap.vid.utils.TimeUtils;
142 import org.springframework.test.context.ContextConfiguration;
143 import org.testng.Assert;
144 import org.testng.annotations.AfterMethod;
145 import org.testng.annotations.BeforeClass;
146 import org.testng.annotations.BeforeMethod;
147 import org.testng.annotations.DataProvider;
148 import org.testng.annotations.Test;
149
150 @ContextConfiguration(classes = {DataSourceConfig.class, SystemProperties.class, MockedAaiClientAndFeatureManagerConfig.class})
151 public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseTest {
152
153
154
155     @Mock
156     private JobAdapter jobAdapterMock;
157
158     @Mock
159     private JobsBrokerService jobsBrokerServiceMock;
160
161     private AsyncInstantiationRepository asyncInstantiationRepository;
162
163     private AuditService auditService;
164
165
166     private AsyncInstantiationBusinessLogicImpl asyncInstantiationBL;
167
168     protected MsoRequestBuilder msoRequestBuilder;
169
170     private static final String UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE =
171             "Failed to retrieve class .*ServiceInfo with jobId .* from table. no resource found";
172
173     private static final String DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE =
174             "Service status does not allow deletion from the queue";
175
176     private String uuidRegex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
177     private org.hamcrest.Matcher uuidRegexMatcher = is(matchesPattern(uuidRegex));
178
179
180     @BeforeClass
181     void initServicesInfoService() {
182         MockitoAnnotations.initMocks(this);
183         doReturn(false).when(featureManager).isActive(Features.FLAG_DISABLE_HOMING);
184         AsyncInstantiationRepository realAsyncInstantiationRepository = new AsyncInstantiationRepository(dataAccessService);
185         asyncInstantiationRepository = spy(realAsyncInstantiationRepository);
186
187         auditService = new AuditServiceImpl(null, asyncInstantiationRepository);
188
189         AsyncInstantiationBusinessLogicImpl realAsyncInstantiationBL = new AsyncInstantiationBusinessLogicImpl(jobAdapterMock, jobsBrokerServiceMock, sessionFactory, aaiClient, featureManager, cloudOwnerService, asyncInstantiationRepository, auditService);
190         asyncInstantiationBL = Mockito.spy(realAsyncInstantiationBL);
191
192         msoRequestBuilder = new MsoRequestBuilder(asyncInstantiationBL, cloudOwnerService, aaiClient, featureManager);
193
194         createInstanceParamsMaps();
195     }
196
197     @BeforeMethod
198     void defineMocks() {
199         Mockito.reset(aaiClient);
200         Mockito.reset(jobAdapterMock);
201         Mockito.reset(jobsBrokerServiceMock);
202         Mockito.reset(asyncInstantiationRepository);
203         mockAaiClientAnyNameFree();
204         enableAddCloudOwnerOnMsoRequest();
205     }
206
207     @BeforeMethod
208     void resetServiceCount() {
209         serviceCount = 0;
210     }
211
212     @AfterMethod
213     void clearDb() {
214         dataAccessService.deleteDomainObjects(JobDaoImpl.class, "1=1", getPropsMap());
215         dataAccessService.deleteDomainObjects(ServiceInfo.class, "1=1", getPropsMap());
216         dataAccessService.deleteDomainObjects(JobAuditStatus.class, "1=1", getPropsMap());
217         dataAccessService.deleteDomainObjects(NameCounter.class, "1=1", getPropsMap());
218     }
219
220
221     private void createNewTestServicesInfoForFilter(String userId) {
222         LocalDateTime createdDate, modifiedDate;
223         LocalDateTime NOW = LocalDateTime.now();
224         UUID uuid;
225
226         // Old job
227         uuid = UUID.randomUUID();
228         addNewJob(uuid);
229         createdDate = NOW.minusYears(1);
230         addNewServiceInfo(uuid, userId, "Old", createdDate, createdDate, COMPLETED, false, false,
231             MODEL_UUID);
232
233         uuid = UUID.randomUUID();
234         addNewJob(uuid);
235         createdDate = NOW.minusDays(20);
236         modifiedDate = NOW.minusDays(19);
237         addNewServiceInfo(uuid, userId, "Hidden", createdDate, modifiedDate, PAUSE, true, false,
238             MODEL_UUID);
239
240         createNewTestServicesInfo(String.valueOf(userId));
241     }
242
243     private void createNewTestServicesInfo(String userId) {
244
245         LocalDateTime createdDate, modifiedDate;
246         LocalDateTime NOW = LocalDateTime.now();
247         UUID uuid;
248
249         uuid = UUID.randomUUID();
250         addNewJob(uuid);
251
252         createdDate = NOW.minusDays(40);
253         addNewServiceInfo(uuid, userId, "service instance 5", createdDate, createdDate, COMPLETED, false, false,
254             MODEL_UUID);
255         addNewServiceInfo(uuid, userId, "service instance 6", createdDate, createdDate, STOPPED, false, false,
256             MODEL_UUID);
257
258         uuid = UUID.randomUUID();
259         addNewJob(uuid);
260
261         createdDate = NOW.minusDays(20);
262         modifiedDate = NOW.minusDays(10);
263         addNewServiceInfo(uuid, userId, "service instance 4", createdDate, modifiedDate, STOPPED, false, false,
264             MODEL_UUID);
265         addNewServiceInfo(uuid, userId, "service instance 2", createdDate, modifiedDate, COMPLETED, false, false,
266             MODEL_UUID);
267         addNewServiceInfo(uuid, userId, "service instance 3", createdDate, modifiedDate, PAUSE, false, false,
268             MODEL_UUID);
269
270         modifiedDate = NOW.minusDays(19);
271         addNewServiceInfo(uuid, userId, "service instance 1", createdDate, modifiedDate, FAILED, false, false,
272             MODEL_UUID);
273
274
275         // Job to a different user
276         uuid = UUID.randomUUID();
277         addNewJob(uuid);
278
279         createdDate = NOW.minusMonths(2);
280         addNewServiceInfo(uuid, "2221", "service instance 7", createdDate, createdDate, COMPLETED, false, false,
281             MODEL_UUID);
282
283     }
284
285
286
287     private UUID createServicesInfoWithDefaultValues(Job.JobStatus status) {
288
289         LocalDateTime NOW = LocalDateTime.now();
290         UUID uuid;
291
292         uuid = UUID.randomUUID();
293         addNewJob(uuid, status);
294
295         addNewServiceInfo(uuid, null, "service instance 1", NOW, NOW, status, false, false,
296             MODEL_UUID);
297
298         return uuid;
299
300     }
301
302     private List<ServiceInfo> getFullList() {
303         List<ServiceInfo> expectedOrderServiceInfo = dataAccessService.getList(ServiceInfo.class, getPropsMap());
304         assertThat("Failed to retrieve all predefined services", expectedOrderServiceInfo.size(), equalTo(serviceCount));
305         expectedOrderServiceInfo.sort(new ServiceInfoComparator());
306         return expectedOrderServiceInfo;
307     }
308
309
310
311     private LocalDateTime fromDate(Date date) {
312         return Instant.ofEpochMilli(date.getTime())
313                 .atZone(ZoneId.systemDefault())
314                 .toLocalDateTime();
315     }
316
317     private void setCreateDateToServiceInfo(UUID jobUuid, LocalDateTime createDate) {
318         List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, getPropsMap());
319         DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
320             serviceInfoList.stream()
321                     .filter(serviceInfo -> jobUuid.equals(serviceInfo.getJobId()))
322                     .forEach(serviceInfo -> {
323                         serviceInfo.setCreated(toDate(createDate));
324                         session.saveOrUpdate(serviceInfo);
325                     });
326             return 1;
327         });
328     }
329
330     private void addNewJob(UUID uuid) {
331         addNewJob(uuid, null);
332     }
333
334     private void addNewJob(UUID uuid, Job.JobStatus status) {
335         JobDaoImpl jobDao = new JobDaoImpl();
336         jobDao.setUuid(uuid);
337         jobDao.setStatus(status);
338         dataAccessService.saveDomainObject(jobDao, getPropsMap());
339     }
340
341     private ServiceInstantiation addOriginalService(UUID jobId, String userID){
342         addNewServiceInfo(jobId, userID, "name", LocalDateTime.now(), LocalDateTime.now(), COMPLETED_WITH_ERRORS, false,
343             true,
344             MODEL_UUID);
345         assertThat(asyncInstantiationRepository.getServiceInfoByJobId(jobId).isRetryEnabled(), is(true));
346         ServiceInstantiation originalServiceInstantiation = prepareServiceInstantiation(true, 1);
347         doReturn(originalServiceInstantiation).when(asyncInstantiationRepository).getJobRequest(jobId);
348         return originalServiceInstantiation;
349     }
350
351     private void assertRetryDisabled(UUID jobId){
352         assertThat(asyncInstantiationRepository.getServiceInfoByJobId(jobId).isRetryEnabled(), is(false));
353     }
354
355     private void assertNewJobExistsAsExpectedAfterRetry(List<UUID> newJobIds, ServiceInstantiation expectedServiceInstantiation, UUID jobId, String userId){
356         assertThat(newJobIds, hasSize(1));
357         assertThat(newJobIds.get(0), not(equalTo(jobId)));
358
359         ArgumentCaptor<ServiceInstantiation> requestsCaptor = ArgumentCaptor.forClass(ServiceInstantiation.class);
360         ArgumentCaptor<UUID> uuidsCaptor = ArgumentCaptor.forClass(UUID.class);
361         ArgumentCaptor<JobType> jobTypeCaptor = ArgumentCaptor.forClass(JobType.class);
362
363         verify(asyncInstantiationRepository).addJobRequest(uuidsCaptor.capture(), requestsCaptor.capture());
364         verify(jobAdapterMock).createServiceInstantiationJob(jobTypeCaptor.capture(), requestsCaptor.capture(), uuidsCaptor.capture(), eq(userId), any(), anyString(), anyInt());
365         verify(jobsBrokerServiceMock).add(any());
366
367         requestsCaptor.getAllValues().forEach(x->assertJsonEquals(expectedServiceInstantiation, x, whenIgnoringPaths(
368                 "trackById",
369                 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.trackById",
370                 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:001.trackById",
371                 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:002.trackById"
372         )));
373
374     }
375
376     @Test
377     public void testServiceInfoAreOrderedAsExpected() {
378         int userId = 2222;
379         createNewTestServicesInfo(String.valueOf(userId));
380         List<ServiceInfo> expectedOrderServiceInfo = getFullList();
381         List<ServiceInfo> serviceInfoListResult = asyncInstantiationBL.getAllServicesInfo();
382         assertThat("Services aren't ordered as expected", serviceInfoListResult, equalTo(expectedOrderServiceInfo));
383     }
384
385     @Test
386     public void whenNewServiceInfoCreated_isRetryEnablesIsFalse() {
387         UUID uuid = createServicesInfoWithDefaultValues(PENDING);
388         assertFalse(asyncInstantiationRepository.getServiceInfoByJobId(uuid).isRetryEnabled());
389     }
390
391     @Test
392     public void testServiceInfoAreFilteredAsExpected() {
393         int userId = 2222;
394         createNewTestServicesInfoForFilter(String.valueOf(userId));
395         List<ServiceInfo> expectedOrderServiceInfo = getFullList();
396
397         List<ServiceInfo> expectedFilterByUser = expectedOrderServiceInfo.stream().filter(x ->
398                 !x.getServiceInstanceName().equals("Old") && !x.getServiceInstanceName().equals("Hidden")
399
400         ).collect(Collectors.toList());
401
402
403         List<ServiceInfo> serviceInfoFilteredByUser = asyncInstantiationBL.getAllServicesInfo();
404         assertThat("Services aren't ordered filtered as expected", serviceInfoFilteredByUser, equalTo(expectedFilterByUser));
405     }
406
407     @Test(dataProvider = "pauseAndInstanceParams")
408     public void createMacroServiceInstantiationMsoRequestUniqueName(Boolean isPause, HashMap<String, String> vfModuleInstanceParamsMap, List vnfInstanceParams) throws Exception {
409         defineMocks();
410         ServiceInstantiation serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(isPause, createVnfList(vfModuleInstanceParamsMap, vnfInstanceParams, true), 2, true, PROJECT_NAME, false);
411         final URL resource = this.getClass().getResource("/payload_jsons/bulk_service_request_unique_names.json");
412         when(jobAdapterMock.createServiceInstantiationJob(any(), any(), any(), any(), any(), anyString(), any())).thenAnswer(invocation -> {
413             Object[] args = invocation.getArguments();
414             return new MockedJob((String)args[5]);
415         });
416
417         when(jobsBrokerServiceMock.add(any(MockedJob.class))).thenAnswer((Answer<UUID>) invocation -> {
418             Object[] args = invocation.getArguments();
419             MockedJob job = (MockedJob) args[0];
420             MockedJob.putJob(job.uuid, job);
421             return job.getUuid();
422         });
423
424         when(asyncInstantiationBL.isPartOfBulk(any())).thenReturn(true);
425
426         List<UUID> uuids = asyncInstantiationBL.pushBulkJob(serviceInstantiationPayload, "az2016");
427         for (int i = 0; i < 2; i++) {
428             UUID currentUuid = uuids.get(i);
429             RequestDetailsWrapper<ServiceInstantiationRequestDetails> result =
430                     msoRequestBuilder.generateMacroServiceInstantiationRequest(currentUuid, serviceInstantiationPayload,
431                             MockedJob.getJob(currentUuid).getOptimisticUniqueServiceInstanceName(), "az2016");
432             String unique =  i==0 ? "" : String.format("_00%s", i);
433             String expected = IOUtils.toString(resource, "UTF-8")
434                     .replace("{SERVICE_UNIQENESS}", unique)
435                     .replace("{VNF_UNIQENESS}", unique)
436                     .replace("{VF_MODULE_UNIQENESS}", unique)
437                     .replace("{VF_MODULE_2_UNIQENESS}", unique)
438                     .replace("{VG_UNIQUENESS}", unique);
439             MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
440             Optional<ServiceInfo> optionalServiceInfo = getJobById(currentUuid);
441             assertThat(optionalServiceInfo.get().getServiceInstanceName(), equalTo("vPE_Service" + unique));
442             verifySearchNodeTypeByName(unique, "vPE_Service", ResourceType.SERVICE_INSTANCE);
443             verifySearchNodeTypeByName(unique, VNF_NAME, ResourceType.GENERIC_VNF);
444             verifySearchNodeTypeByName(unique, "vmxnjr001_AVPN_base_vPE_BV_base", ResourceType.VF_MODULE);
445             verifySearchNodeTypeByName(unique, "vmxnjr001_AVPN_base_vRE_BV_expansion", ResourceType.VF_MODULE);
446             verifySearchNodeTypeByName(unique, "myVgName", ResourceType.VOLUME_GROUP);
447         }
448     }
449
450     protected void verifySearchNodeTypeByName(String unique, String resourceName, ResourceType serviceInstance) {
451         String uniqueName = resourceName + unique;
452         verify(aaiClient, times(1)).isNodeTypeExistsByName(uniqueName, serviceInstance);
453         when(aaiClient.isNodeTypeExistsByName(uniqueName, serviceInstance)).thenReturn(true);
454     }
455
456
457
458
459     @DataProvider
460     public static Object[][] dataProviderForInstanceNames() {
461         return new Object[][]{
462                 {true, ImmutableList.of("vPE_Service", "vPE_Service_001", "vPE_Service_002")},
463                 {false, ImmutableList.of("", "", "")},
464         };
465     }
466
467     @Test(dataProvider="dataProviderForInstanceNames")
468     public void pushBulkJob_bulkWithSize3_instancesNamesAreExactlyAsExpected(boolean isUserProvidedNaming, List<String> expectedNames) {
469         final ServiceInstantiation request = prepareServiceInstantiation(isUserProvidedNaming, 3);
470
471
472         asyncInstantiationBL.pushBulkJob(request, "myUserId");
473
474         List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, getPropsMap());
475         assertEquals(serviceInfoList.stream().map(ServiceInfo::getServiceInstanceName).collect(Collectors.toList()), expectedNames);
476     }
477
478     protected ServiceInstantiation prepareServiceInstantiation(String projectName, boolean isUserProvidedNaming, int bulkSize) {
479         final ServiceInstantiation request = generateMockMacroServiceInstantiationPayload(
480                 false,
481                 createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true),
482                 bulkSize, isUserProvidedNaming, projectName, true
483         );
484
485         // in "createServiceInstantiationJob()" we will probe the service, with the generated names
486         configureMockitoWithMockedJob();
487         return request;
488     }
489
490     protected ServiceInstantiation prepareServiceInstantiation(boolean isUserProvidedNaming, int bulkSize) {
491         return prepareServiceInstantiation(PROJECT_NAME, isUserProvidedNaming, bulkSize);
492     }
493
494     @Test
495     public void getSummarizedMap(){
496         ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject(
497             "/payload_jsons/templateSummarize4vnfs6vfmodules.json", ServiceInstantiation.class);
498         Map<String, Long> childrenMap =  asyncInstantiationBL.getSummarizedChildrenMap(serviceInstantiation);
499         Map<String, Long> expectedMap = ImmutableMap.of(
500             "vnf", 4L,
501             "vfModule", 6L,
502             "network", 2L
503         );
504         assertEquals(childrenMap,expectedMap);
505
506     }
507
508
509     @Test
510     public void whenPushBulkJob_thenJobRequestIsSaveInJobRequestDb() {
511         Mockito.reset(asyncInstantiationRepository);
512         int bulkSize = 3;
513         final ServiceInstantiation request = prepareServiceInstantiation(true, bulkSize);
514         when(jobsBrokerServiceMock.add(any())).thenReturn(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID());
515         List<UUID> jobIds = asyncInstantiationBL.pushBulkJob(request, "abc");
516
517         ArgumentCaptor<JobAdapter.AsyncJobRequest> asyncJobRequestCaptor = ArgumentCaptor.forClass(JobAdapter.AsyncJobRequest.class);
518         ArgumentCaptor<ServiceInstantiation> requestsCaptor = ArgumentCaptor.forClass(ServiceInstantiation.class);
519         ArgumentCaptor<UUID> uuidsCaptor = ArgumentCaptor.forClass(UUID.class);
520         verify(asyncInstantiationRepository, times(bulkSize)).addJobRequest(uuidsCaptor.capture(), requestsCaptor.capture());
521         verify(jobsBrokerServiceMock, times(bulkSize)).add(any());
522         verify(jobAdapterMock, times(bulkSize)).createServiceInstantiationJob(any(), asyncJobRequestCaptor.capture(), any(), any(), any(), any(), any());
523
524         //verify that all for each job we saved an row in jobRequest table
525         assertThat(uuidsCaptor.getAllValues(), containsInAnyOrder(jobIds.toArray()));
526
527         //assert that each real job we created with the adaptor, request is save in jobRequest table
528         assertThat(requestsCaptor.getAllValues(), containsInAnyOrder(asyncJobRequestCaptor.getAllValues().toArray()));
529
530         assertThat(requestsCaptor.getAllValues(),everyItem(hasProperty("bulkSize", is(1))));
531
532         //assert that the requests that save in DB are the same as original request expect of the trackById
533         requestsCaptor.getAllValues().forEach(x->assertJsonEquals(request, x, whenIgnoringPaths(
534                 "bulkSize",
535                 "trackById",
536                 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.trackById",
537                 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:001.trackById",
538                 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:002.trackById"
539         )));
540
541         //assert that each trackById on all bulk jobs is unique
542         Set<String> usedUUID = new HashSet<>();
543         requestsCaptor.getAllValues().forEach(x->assertTrackByIdRecursively(x, uuidRegexMatcher, usedUUID));
544     }
545
546     @Test
547     public void whenRetryJob_prevJobRetryIsDisabled() {
548         reset(asyncInstantiationRepository);
549         UUID jobId = UUID.randomUUID();
550         String userID = generateRandomAlphaNumeric(8);
551         addOriginalService(jobId, userID);
552         doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
553         asyncInstantiationBL.retryJob(jobId, userID);
554         assertRetryDisabled(jobId);
555     }
556
557     @Test
558     public void whenRetryJobWithEditedData_prevJobRetryIsDisabled() {
559         reset(asyncInstantiationRepository);
560         UUID jobId = UUID.randomUUID();
561         String userID = generateRandomAlphaNumeric(8);
562         addOriginalService(jobId, userID);
563         ServiceInstantiation editedServiceInstantiation = prepareServiceInstantiation("editedProjectName", true, 1);
564         asyncInstantiationBL.retryJob(editedServiceInstantiation, jobId, userID);
565         assertRetryDisabled(jobId);
566     }
567
568     @Test
569     public void retryJobWithEditedData_expectedNewJobDifferentData() {
570         reset(asyncInstantiationRepository);
571         UUID jobId = UUID.randomUUID();
572         String userID = generateRandomAlphaNumeric(8);
573         addOriginalService(jobId, userID);
574         ServiceInstantiation editedServiceInstantiation = prepareServiceInstantiation("editedProjectName", true, 1);
575         List<UUID> newJobIds =  asyncInstantiationBL.retryJob(editedServiceInstantiation, jobId, userID);
576         assertNewJobExistsAsExpectedAfterRetry(newJobIds, editedServiceInstantiation, jobId, userID);
577     }
578
579     @Test
580     public void retryJob_expectedNewJob() {
581         reset(asyncInstantiationRepository);
582         UUID jobId = UUID.randomUUID();
583         String userID = "az2016";
584         ServiceInstantiation originalServiceInstantiation =  addOriginalService(jobId, userID);
585         doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
586         List<UUID> newJobIds = asyncInstantiationBL.retryJob(jobId, userID);
587         assertNewJobExistsAsExpectedAfterRetry(newJobIds, originalServiceInstantiation, jobId, userID);
588     }
589
590     @Test (dataProvider = "aLaCarteAndMacroPayload")
591     public void generateMockServiceInstantiationPayload_serializeBackAndForth_sourceShouldBeTheSame(ServiceInstantiation serviceInstantiationPayload) throws IOException {
592         ObjectMapper mapper = new ObjectMapper();
593         final String asString = mapper.writeValueAsString(serviceInstantiationPayload);
594
595         final ServiceInstantiation asObject = mapper.readValue(asString, ServiceInstantiation.class);
596         final String asString2 = mapper.writeValueAsString(asObject);
597
598         assertJsonEquals(asString, asString2);
599     }
600
601     @DataProvider
602     public Object[][] aLaCarteAndMacroPayload() {
603         ServiceInstantiation macroPayload = generateMockMacroServiceInstantiationPayload(
604                 false,
605                 createVnfList(instanceParamsMapWithoutParams, ImmutableList.of(vnfInstanceParamsMapWithParamsToRemove, vnfInstanceParamsMapWithParamsToRemove), true),
606                 2, false,PROJECT_NAME, false);
607         ServiceInstantiation aLaCartePayload = generateALaCarteServiceInstantiationPayload();
608
609         return new Object[][]{
610                 {macroPayload},
611                 {aLaCartePayload}
612         };
613     }
614
615     public static class ServiceInfoComparator implements Comparator<ServiceInfo> {
616
617         @Override
618         public int compare(ServiceInfo o1, ServiceInfo o2) {
619             int compare;
620
621             compare = o1.getCreatedBulkDate().compareTo(o2.getCreatedBulkDate());
622             if (compare != 0) {
623                 return -compare;
624             }
625
626             // check jobStatus priority
627             int o1Priority = getPriority(o1);
628             int o2Priority = getPriority(o2);
629             compare = o1Priority - o2Priority;
630             if (compare != 0) {
631                 return compare;
632             }
633
634             // check statusModifiedDate
635             return o1.getStatusModifiedDate().compareTo(o2.getStatusModifiedDate());
636         }
637
638         private int getPriority(ServiceInfo o) throws JSONException {
639             Job.JobStatus status = o.getJobStatus();
640             switch (status) {
641                 case COMPLETED:
642                 case FAILED:
643                     return 1;
644                 case IN_PROGRESS:
645                     return 2;
646                 case PAUSE:
647                     return 3;
648                 case STOPPED:
649                 case PENDING:
650                     return 4;
651                 default:
652                     return 5;
653             }
654         }
655     }
656
657     @DataProvider
658     public Object[][] pauseAndInstanceParams() {
659         return new Object[][]{
660                 {Boolean.TRUE, instanceParamsMapWithoutParams, Collections.EMPTY_LIST},
661                 {Boolean.FALSE, instanceParamsMapWithoutParams, Collections.EMPTY_LIST},
662                 {Boolean.TRUE, vfModuleInstanceParamsMapWithParamsToRemove, Collections.singletonList(vnfInstanceParamsMapWithParamsToRemove)}
663         };
664     }
665
666     @Test
667     public void testUpdateServiceInfo_WithExistingServiceInfo_ServiceInfoIsUpdated() {
668         UUID uuid = createFakedJobAndServiceInfo();
669         final String STEPH_CURRY = "Steph Curry";
670         asyncInstantiationBL.updateServiceInfo(uuid, x -> {
671             x.setServiceInstanceName(STEPH_CURRY);
672             x.setJobStatus(Job.JobStatus.IN_PROGRESS);
673         });
674         Optional<ServiceInfo> optionalServiceInfo = getJobById(uuid);
675         assertThat(optionalServiceInfo.get().getServiceInstanceName(), equalTo(STEPH_CURRY));
676         assertThat(optionalServiceInfo.get().getJobStatus(), equalTo(Job.JobStatus.IN_PROGRESS));
677     }
678
679     private Optional<ServiceInfo> getJobById(UUID jobId) {
680         List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, null);
681         return serviceInfoList.stream().filter(x -> jobId.equals(x.getJobId())).findFirst();
682     }
683
684     private UUID createFakedJobAndServiceInfo() {
685         UUID uuid = UUID.randomUUID();
686         addNewJob(uuid);
687         ServiceInfo serviceInfo = new ServiceInfo();
688         serviceInfo.setServiceInstanceName("Lebron James");
689         serviceInfo.setJobId(uuid);
690         serviceInfo.setJobStatus(Job.JobStatus.PENDING);
691         dataAccessService.saveDomainObject(serviceInfo, getPropsMap());
692         return uuid;
693     }
694
695     @Test(expectedExceptions = NotFoundException.class, expectedExceptionsMessageRegExp = UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE)
696     public void testUpdateServiceInfo_WithNonExisting_ThrowException() {
697         asyncInstantiationBL.updateServiceInfo(UUID.randomUUID(), x -> x.setServiceInstanceName("not matter"));
698     }
699
700     @Test(expectedExceptions = NotFoundException.class, expectedExceptionsMessageRegExp = UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE)
701     public void testUpdateServiceInfo_WithDoubleServiceWithSameJobUuid_ThrowException() {
702         UUID uuid = createFakedJobAndServiceInfo();
703         ServiceInfo serviceInfo = new ServiceInfo();
704         serviceInfo.setJobId(uuid);
705         dataAccessService.saveDomainObject(serviceInfo, getPropsMap());
706         asyncInstantiationBL.updateServiceInfo(UUID.randomUUID(), x -> x.setServiceInstanceName("not matter"));
707     }
708
709
710     @DataProvider
711     public static Object[][] isPauseAndPropertyDataProvider() {
712         return new Object[][]{
713                 {true, "mso.restapi.serviceInstanceAssign"},
714                 {false, "mso.restapi.service.instance"},
715         };
716     }
717
718
719     @Test(dataProvider = "isPauseAndPropertyDataProvider")
720     public void testServiceInstantiationPath_RequestPathIsAsExpected(boolean isPause, String expectedProperty) {
721         ServiceInstantiation serviceInstantiationPauseFlagTrue = generateMacroMockServiceInstantiationPayload(isPause, createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true));
722         String path = asyncInstantiationBL.getServiceInstantiationPath(serviceInstantiationPauseFlagTrue);
723         Assert.assertEquals(path, SystemProperties.getProperty(expectedProperty));
724     }
725
726     @Test
727     public void testCreateVnfEndpoint_useProvidedInstanceId() {
728         String path = asyncInstantiationBL.getVnfInstantiationPath("myGreatId");
729         assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myGreatId/vnfs"));
730     }
731
732
733
734     @Test
735     public void pushBulkJob_macroServiceverifyCreatedDateBehavior_createdDateIsTheSameForAllServicesInSameBulk() {
736         LocalDateTime startTestDate = LocalDateTime.now().withNano(0);
737         final ServiceInstantiation request = generateMockMacroServiceInstantiationPayload(
738                 false,
739                 createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true),
740                 100, true,PROJECT_NAME, true
741         );
742
743         pushJobAndAssertDates(startTestDate, request);
744     }
745
746     @Test
747     public void whenCreateServiceInfo_thenModelId_isModelVersionId() {
748         ServiceInfo serviceInfo = asyncInstantiationBL.createServiceInfo("userID",
749                 generateALaCarteWithVnfsServiceInstantiationPayload(),
750                 UUID.randomUUID(),
751                 UUID.randomUUID(),
752                 new Date(),
753                 "myName", ServiceInfo.ServiceAction.INSTANTIATE);
754         assertEquals(SERVICE_MODEL_VERSION_ID, serviceInfo.getServiceModelId());
755
756     }
757
758     @Test
759     public void pushBulkJob_aLaCarteServiceverifyCreatedDateBehavior_createdDateIsTheSameForAllServicesInSameBulk() {
760         LocalDateTime startTestDate = LocalDateTime.now().withNano(0);
761         final ServiceInstantiation request = generateALaCarteServiceInstantiationPayload();
762         pushJobAndAssertDates(startTestDate, request);
763     }
764
765     protected void pushJobAndAssertDates(LocalDateTime startTestDate, ServiceInstantiation request) {
766         // in "createServiceInstantiationJob()" we will probe the service, with the generated names
767         configureMockitoWithMockedJob();
768
769         asyncInstantiationBL.pushBulkJob(request, "myUserId");
770         List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, getPropsMap());
771
772         List<Date> creationDates = new ArrayList<>();
773         for (ServiceInfo serviceInfo : serviceInfoList) {
774             creationDates.add(serviceInfo.getCreatedBulkDate());
775         }
776         LocalDateTime endTestDate = LocalDateTime.now();
777
778         //creation date of all services is the same
779         Assert.assertTrue(creationDates.stream().distinct().count() <= 1);
780         LocalDateTime creationDate = fromDate(creationDates.get(0));
781         assertFalse(creationDate.isBefore(startTestDate));
782         assertFalse(creationDate.isAfter(endTestDate));
783     }
784
785     protected void configureMockitoWithMockedJob() {
786         Mockito.reset(jobAdapterMock);
787         final Job job = mock(Job.class);
788         when(job.getStatus()).thenReturn(PENDING);
789         when(job.getUuid()).thenReturn(UUID.fromString("db2c5ed9-1c19-41ce-9cb7-edf0d878cdeb"));
790         when(jobAdapterMock.createServiceInstantiationJob(any(), any(), any(), any(), any(), any(), any())).thenReturn(job);
791         when(jobsBrokerServiceMock.add(job)).thenReturn(UUID.randomUUID());
792     }
793
794     @DataProvider
795     public static Object[][] msoToJobStatusDataProvider() {
796         return new Object[][]{
797                 {"IN_PROGRESS", JobStatus.IN_PROGRESS},
798                 {"INPROGRESS", JobStatus.IN_PROGRESS},
799                 {"IN ProGREsS", JobStatus.IN_PROGRESS},
800                 {"JAMES_HARDEN", JobStatus.IN_PROGRESS},
801                 {"FAILED", JobStatus.FAILED},
802                 {"COMpleTE", JobStatus.COMPLETED},
803                 {"PENDING", JobStatus.IN_PROGRESS},
804                 {"Paused", JobStatus.PAUSE},
805                 {"Pause", JobStatus.PAUSE},
806                 {"PENDING_MANUAL_TASK", JobStatus.PAUSE},
807                 {"UNLOCKED", JobStatus.IN_PROGRESS},
808                 {"AbORtEd", COMPLETED_WITH_ERRORS},
809                 {"RoLlED_baCK", FAILED},
810                 {"ROllED_BAcK_To_ASsIGnED", FAILED},
811                 {"rOLLED_bACK_tO_CrEATeD", FAILED},
812         };
813     }
814
815     @Test(dataProvider = "msoToJobStatusDataProvider")
816     public void whenGetStatusFromMso_calcRightJobStatus(String msoStatus, Job.JobStatus expectedJobStatus) {
817         AsyncRequestStatus asyncRequestStatus = asyncRequestStatusResponse(msoStatus);
818         assertThat(asyncInstantiationBL.calcStatus(asyncRequestStatus), equalTo(expectedJobStatus));
819     }
820
821     @DataProvider
822     public static Object[][] msoRequestStatusFiles(Method test) {
823         return new Object[][]{
824                 {"/responses/mso/orchestrationRequestsServiceInstance.json"},
825                 {"/responses/mso/orchestrationRequestsVnf.json"},
826                 {"/responses/mso/orchestrationRequestsMockedMinimalResponse.json"}
827         };
828     }
829
830     @Test(dataProvider="msoRequestStatusFiles")
831     public void verifyAsyncRequestStatus_canBeReadFromSample(String msoResponseFile) throws IOException {
832         AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
833                 msoResponseFile,
834                 AsyncRequestStatus.class);
835         assertThat(asyncRequestStatus.request.requestStatus.getRequestState(), equalTo("COMPLETE"));
836     }
837
838     @Test
839     public void deleteJobInfo_pending_deleted() {
840         doNothing().when(jobsBrokerServiceMock).delete(any());
841         UUID uuid = createServicesInfoWithDefaultValues(PENDING);
842         asyncInstantiationBL.deleteJob(uuid);
843         assertNotNull(asyncInstantiationRepository.getServiceInfoByJobId(uuid).getDeletedAt(), "service info wasn't deleted");
844     }
845
846     @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE)
847     public void deleteJobInfo_notAllowdStatus_shouldSendError() {
848         UUID uuid = createServicesInfoWithDefaultValues(COMPLETED);
849         doThrow(new IllegalStateException(DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE)).when(jobsBrokerServiceMock).delete(any());
850         try {
851             asyncInstantiationBL.deleteJob(uuid);
852         } catch (Exception e) {
853             assertNull(asyncInstantiationRepository.getServiceInfoByJobId(uuid).getDeletedAt(), "service info shouldn't deleted");
854             throw e;
855         }
856     }
857
858     @DataProvider
859     public Object[][] jobStatusesFinal() {
860         return Arrays.stream(Job.JobStatus.values())
861                 .filter(t -> ImmutableList.of(COMPLETED, FAILED, STOPPED).contains(t))
862                 .map(v -> new Object[]{v}).collect(Collectors.toList()).toArray(new Object[][]{});
863     }
864
865     @Test(dataProvider = "jobStatusesFinal")
866     public void whenHideService_theServiceNotReturnedInServiceList(JobStatus jobStatus) {
867         UUID uuidToHide = createServicesInfoWithDefaultValues(jobStatus);
868         UUID uuidToShown = createServicesInfoWithDefaultValues(jobStatus);
869         List<UUID> serviceInfoList = listServicesUUID();
870         assertThat(serviceInfoList, hasItems(uuidToHide, uuidToShown));
871
872         asyncInstantiationBL.hideServiceInfo(uuidToHide);
873         serviceInfoList = listServicesUUID();
874         assertThat(serviceInfoList, hasItem(uuidToShown));
875         assertThat(serviceInfoList, not(hasItem(uuidToHide)));
876
877     }
878
879     protected List<UUID> listServicesUUID() {
880         return asyncInstantiationBL.getAllServicesInfo().stream().map(ServiceInfo::getJobId).collect(Collectors.toList());
881     }
882
883     @DataProvider
884     public Object[][] jobStatusesNotFinal() {
885         return Arrays.stream(Job.JobStatus.values())
886                 .filter(t -> ImmutableList.of(PENDING, IN_PROGRESS, PAUSE).contains(t))
887                 .map(v -> new Object[]{v}).collect(Collectors.toList()).toArray(new Object[][]{});
888     }
889
890     @Test(dataProvider = "jobStatusesNotFinal",
891             expectedExceptions = OperationNotAllowedException.class,
892             expectedExceptionsMessageRegExp = "jobId.*Service status does not allow hide service, status = .*")
893     public void hideServiceInfo_notAllowedStatus_shouldSendError(JobStatus jobStatus) {
894         UUID uuid = createServicesInfoWithDefaultValues(jobStatus);
895         try {
896             asyncInstantiationBL.hideServiceInfo(uuid);
897         } catch (Exception e) {
898             assertFalse(asyncInstantiationRepository.getServiceInfoByJobId(uuid).isHidden(), "service info shouldn't be hidden");
899             throw e;
900         }
901     }
902
903     @Test
904     public void whenUseGetCounterInMultiThreads_EachThreadGetDifferentCounter() throws InterruptedException {
905         int SIZE = 200;
906         ExecutorService executor = Executors.newFixedThreadPool(SIZE);
907         List<Callable<Integer>> tasks = IntStream.rangeClosed(0, SIZE)
908                 .mapToObj(x-> ((Callable<Integer>)() -> asyncInstantiationBL.getCounterForName("a")))
909                 .collect(Collectors.toList());
910         Set<Integer> expectedResults = IntStream.rangeClosed(0, SIZE).boxed().collect(Collectors.toSet());
911         executor.invokeAll(tasks)
912                 .forEach(future -> {
913                     try {
914                         assertTrue( expectedResults.remove(future.get()), "got unexpected counter");
915                     }
916                     catch (Exception e) {
917                         throw new RuntimeException(e);
918                     }
919                 });
920
921         assertThat(expectedResults.size(), is(0));
922     }
923
924     @Test
925     public void whenUseGetCounterForSameName_numbersReturnedByOrder() {
926
927         String name = UUID.randomUUID().toString();
928         int SIZE=10;
929         for (int i=0; i<SIZE; i++) {
930             assertThat(asyncInstantiationBL.getCounterForName(name), is(i));
931         }
932     }
933
934     @Test
935     public void whenNamedInUsedInAai_getNextNumber() {
936         String name = someCommonStepsAndGetName();
937         ResourceType type = ResourceType.GENERIC_VNF;
938         when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(true);
939         when(aaiClient.isNodeTypeExistsByName(name+"_001", type)).thenReturn(false);
940         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name+"_001"));
941     }
942
943     @Test(enabled = false) //skip till we will handle macro bulk again...
944     public void whenNamedNotInUsedInAai_getSameNameTwice() {
945         String name = someCommonStepsAndGetName();
946         ResourceType type = ResourceType.GENERIC_VNF;
947         when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(false);
948         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name));
949         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name));
950         when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(true);
951         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name+"_001"));
952     }
953
954     private String someCommonStepsAndGetName() {
955         mockAaiClientAaiStatusOK();
956         return UUID.randomUUID().toString();
957     }
958
959     @Test(expectedExceptions= ExceptionWithRequestInfo.class)
960     public void whenAaiBadResponseCode_throwInvalidAAIResponseException() {
961         String name = someCommonStepsAndGetName();
962         ResourceType type = ResourceType.SERVICE_INSTANCE;
963         when(aaiClient.isNodeTypeExistsByName(name, type)).thenThrow(aaiNodeQueryBadResponseException());
964         asyncInstantiationBL.getUniqueName(name, type);
965     }
966
967     @Test(expectedExceptions=MaxRetriesException.class)
968     public void whenAaiAlwaysReturnNameUsed_throwInvalidAAIResponseException() {
969         String name = someCommonStepsAndGetName();
970         ResourceType type = ResourceType.VF_MODULE;
971         when(aaiClient.isNodeTypeExistsByName(any(), eq(type))).thenReturn(true);
972         asyncInstantiationBL.setMaxRetriesGettingFreeNameFromAai(10);
973         asyncInstantiationBL.getUniqueName(name, type);
974     }
975
976     @Test
977     public void testFormattingOfNameAndCounter() {
978         AsyncInstantiationBusinessLogicImpl bl = (AsyncInstantiationBusinessLogicImpl) asyncInstantiationBL;
979         assertThat(bl.formatNameAndCounter("x", 0), equalTo("x"));
980         assertThat(bl.formatNameAndCounter("x", 3), equalTo("x_003"));
981         assertThat(bl.formatNameAndCounter("x", 99), equalTo("x_099"));
982         assertThat(bl.formatNameAndCounter("x", 100), equalTo("x_100"));
983         assertThat(bl.formatNameAndCounter("x", 1234), equalTo("x_1234"));
984     }
985
986     @Test
987     public void pushBulkJob_verifyAlacarteFlow_useALaCartServiceInstantiationJobType(){
988         final ServiceInstantiation request = generateALaCarteServiceInstantiationPayload();
989
990         // in "createServiceInstantiationJob()" we will probe the service, with the generated names
991         configureMockitoWithMockedJob();
992
993         ArgumentCaptor<JobType> argumentCaptor = ArgumentCaptor.forClass(JobType.class);
994         asyncInstantiationBL.pushBulkJob(request, "myUserId");
995         verify(jobAdapterMock).createServiceInstantiationJob(argumentCaptor.capture(),any(),any(),anyString(), anyString(),  anyString(), anyInt());
996         assertTrue(argumentCaptor.getValue().equals(JobType.ALaCarteServiceInstantiation));
997     }
998
999     @Test
1000     public void pushBulkJob_verifyMacroFlow_useMacroServiceInstantiationJobType(){
1001         final ServiceInstantiation request = generateMacroMockServiceInstantiationPayload(false, Collections.emptyMap());
1002
1003         // in "createServiceInstantiationJob()" we will probe the service, with the generated names
1004         configureMockitoWithMockedJob();
1005
1006         ArgumentCaptor<JobType> argumentCaptor = ArgumentCaptor.forClass(JobType.class);
1007         asyncInstantiationBL.pushBulkJob(request, "myUserId");
1008         verify(jobAdapterMock).createServiceInstantiationJob(argumentCaptor.capture(),any(),any(),anyString(), any(),  anyString(), anyInt());
1009         assertTrue(argumentCaptor.getValue().equals(JobType.MacroServiceInstantiation));
1010     }
1011
1012
1013
1014     @Test
1015     public void getALaCarteServiceDeletionPath_verifyPathIsAsExpected() {
1016
1017         String expected = "/serviceInstantiation/v7/serviceInstances/f36f5734-e9df-4fbf-9f35-61be13f028a1";
1018
1019         String result = asyncInstantiationBL.getServiceDeletionPath("f36f5734-e9df-4fbf-9f35-61be13f028a1");
1020
1021         assertThat(expected,equalTo(result));
1022     }
1023
1024     @Test
1025     public void getResumeRequestPath_verifyPathIsAsExpected() {
1026
1027         String expected = "/orchestrationRequests/v7/rq1234d1-5a33-55df-13ab-12abad84e333/resume";
1028
1029         String result = asyncInstantiationBL.getResumeRequestPath("rq1234d1-5a33-55df-13ab-12abad84e333");
1030
1031         assertThat(expected, equalTo(result));
1032     }
1033
1034     @Test
1035     public void getInstanceGroupsDeletionPath_verifyPathIsAsExpected()  {
1036         assertEquals(asyncInstantiationBL.getInstanceGroupDeletePath("9aada4af-0f9b-424f-ae21-e693bd3e005b"),
1037                 "/serviceInstantiation/v7/instanceGroups/9aada4af-0f9b-424f-ae21-e693bd3e005b");
1038     }
1039
1040     @Test
1041     public void whenLcpRegionNotEmpty_thenCloudRegionIdOfResourceIsLegacy() {
1042         String legacyCloudRegion = "legacyCloudRegion";
1043         Vnf vnf = new Vnf(new ModelInfo(), null, null, Action.Create.name(), null, "anyCloudRegion", legacyCloudRegion,
1044                 null, null, null, false, null, null, UUID.randomUUID().toString(), null, null, null);
1045         assertThat(vnf.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
1046     }
1047
1048     @Test
1049     public void whenLcpRegionNotEmpty_thenCloudRegionIdOfServiceIsLegacy() {
1050         String legacyCloudRegion = "legacyCloudRegion";
1051         ServiceInstantiation service = new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
1052                 null, null, "anyCloudRegion", legacyCloudRegion, null, null, null, null, null, null, null, null, null,
1053                 false, 1,false, false, null, null, Action.Create.name(), UUID.randomUUID().toString(), null, null, null);
1054         assertThat(service.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
1055     }
1056
1057     @DataProvider
1058     public static Object[][] getJobTypeByRequest_verifyResultAsExpectedDataProvider() {
1059         return new Object[][]{
1060                 {false, Action.Create, JobType.MacroServiceInstantiation},
1061                 {true, Action.Create, JobType.ALaCarteServiceInstantiation},
1062                 {true, Action.Delete, JobType.ALaCarteService},
1063         };
1064     }
1065
1066     @Test(dataProvider = "getJobTypeByRequest_verifyResultAsExpectedDataProvider")
1067     public void getJobTypeByRequest_verifyResultAsExpected(boolean isALaCarte, Action action, JobType expectedJobType) {
1068         ServiceInstantiation service = createServiceWithIsALaCarteAndAction(isALaCarte, action);
1069         assertThat(asyncInstantiationBL.getJobType(service), equalTo(expectedJobType));
1070     }
1071
1072     @NotNull
1073     protected ServiceInstantiation createServiceWithIsALaCarteAndAction(boolean isALaCarte, Action action) {
1074         return new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
1075                 null, null, null, null, null, null, null, null, null, null, null, null, null,
1076                 false, 1, false, isALaCarte, null, null, action.name(),
1077                 UUID.randomUUID().toString(), null, null, null);
1078     }
1079
1080     @DataProvider
1081     public static Object[][] isRetryEnabledForStatusDataProvider(Method test) {
1082         return new Object[][]{
1083                 {FAILED, true, true},
1084                 {COMPLETED_WITH_ERRORS, true, true},
1085                 {COMPLETED_WITH_NO_ACTION, true, false},
1086                 {COMPLETED, true, false},
1087                 {IN_PROGRESS, true, false},
1088                 {FAILED, false, false},
1089                 {COMPLETED_WITH_ERRORS, false, false},
1090                 {COMPLETED, false, false},
1091         };
1092     }
1093
1094     @Test(dataProvider = "isRetryEnabledForStatusDataProvider")
1095     public void whenUpdateServiceInfoAndAuditStatus_thenServiceInfoRowIsUpdatedAndIsRetryIsRight(
1096             JobStatus jobStatus, boolean isRetryfeatureEnabled, boolean expectedIsRetry) {
1097         when(featureManager.isActive(Features.FLAG_1902_RETRY_JOB)).thenReturn(isRetryfeatureEnabled);
1098         UUID uuid = createFakedJobAndServiceInfo();
1099         asyncInstantiationBL.updateServiceInfoAndAuditStatus(uuid, jobStatus);
1100         ServiceInfo serviceInfo = ((List<ServiceInfo>)dataAccessService.getList(ServiceInfo.class, getPropsMap())).
1101                 stream().filter(x->x.getJobId().equals(uuid)).findFirst().get();
1102         assertEquals(jobStatus, serviceInfo.getJobStatus());
1103
1104         //we don't test serviceInfo.getStatusModifiedDate() because it's too complicated
1105
1106         assertEquals(expectedIsRetry, serviceInfo.isRetryEnabled());
1107     }
1108
1109     @Test
1110     public void givenServiceWithNullTrackByIds_whenReplaceTrackByIds_thenAllLevelsHasTrackByIdWithUUID() {
1111         ServiceInstantiation serviceInstantiation = FakeResourceCreator.createServiceWith2InstancesInEachLevel(Action.Create);
1112         //assert for the given that all trackById are null
1113         assertTrackByIdRecursively(serviceInstantiation, is(nullValue()), new HashSet<>());
1114         ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.prepareServiceToBeUnique(serviceInstantiation);
1115         assertTrackByIdRecursively(modifiedServiceInstantiation, uuidRegexMatcher, new HashSet<>());
1116     }
1117
1118     private void assertTrackByIdRecursively(BaseResource baseResource, org.hamcrest.Matcher matcher, Set<String> usedUuids) {
1119         assertThat(baseResource.getTrackById(), matcher);
1120         if (baseResource.getTrackById()!=null) {
1121             assertThat(usedUuids, not(hasItem(baseResource.getTrackById())));
1122             usedUuids.add(baseResource.getTrackById());
1123         }
1124         baseResource.getChildren().forEach(x->assertTrackByIdRecursively(x, matcher, usedUuids));
1125     }
1126
1127     @Test
1128     public void givenServicefromDB_returnsTheBulkRequest() throws IOException {
1129         ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1Request.json", ServiceInstantiation.class);
1130         UUID jobId = UUID.randomUUID();
1131         doReturn(serviceInstantiation).when(asyncInstantiationRepository).getJobRequest(jobId);
1132         doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
1133         ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.getBulkForRetry(jobId);
1134         assertThat(modifiedServiceInstantiation, jsonEquals(serviceInstantiation).when(IGNORING_ARRAY_ORDER));
1135     }
1136
1137     @Test
1138     public void givenServiceFromDB_returnsResolvedData() throws IOException {
1139         ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1Request.json", ServiceInstantiation.class);
1140         ServiceInstantiation expectedServiceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1RequestResolvedForRetry.json", ServiceInstantiation.class);
1141         UUID jobId = UUID.randomUUID();
1142         AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
1143                 "/responses/mso/orchestrationRequestsVnf.json",
1144                 AsyncRequestStatus.class);
1145         Map<String, ResourceInfo> mockedResourceInfoMap = ImmutableMap.of(
1146                 "groupingservicefortest..ResourceInstanceGroup..0:001", new ResourceInfo("groupingservicefortest..ResourceInstanceGroup..0:001",jobId,"VNF_GROUP1_INSTANCE_ID", COMPLETED, asyncRequestStatus),// TODO case: delete completed
1147                 "ag5aav86u4j", new ResourceInfo("ag5aav86u4j",jobId, null, FAILED, asyncRequestStatus),// case: failed
1148                 "asedrftjko", new ResourceInfo("asedrftjko",jobId, "VNF_GROUP1_INSTANCE_ID_3", COMPLETED, asyncRequestStatus),//case: completed after retry failed
1149                 "rgedfdged4", new ResourceInfo("rgedfdged4", jobId,"VNF_GROUP1_INSTANCE_ID_4", COMPLETED, asyncRequestStatus ));// case: create completed
1150
1151         doReturn(mockedResourceInfoMap).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
1152         ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.enrichBulkForRetry(serviceInstantiation,jobId);
1153         assertThat(modifiedServiceInstantiation, jsonEquals(expectedServiceInstantiation).when(IGNORING_ARRAY_ORDER));
1154     }
1155
1156     @DataProvider
1157     public static Object[][] readStatusMsgDataProvider(Method test) throws IOException {
1158         AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
1159                 "/responses/mso/orchestrationRequestsVnf.json",
1160                 AsyncRequestStatus.class);
1161         return new Object[][]{
1162                 {null, null},
1163                 {new AsyncRequestStatus(), null},
1164                 {new AsyncRequestStatus(new AsyncRequestStatus.Request()), null},
1165                 {new AsyncRequestStatus(new AsyncRequestStatus.Request(new RequestStatus())), null},
1166                 {asyncRequestStatus, "Vnf has been created successfully."}
1167         };
1168     }
1169
1170     @Test(dataProvider = "readStatusMsgDataProvider")
1171     public void resourceInfoReadStatusMsg_returnsStatusMsgOrNull(AsyncRequestStatus asyncRequestStatus, String expected) {
1172         ResourceInfo resourceInfo = new ResourceInfo("groupingservicefortest..ResourceInstanceGroup..0:001",UUID.randomUUID(),"VNF_GROUP1_INSTANCE_ID", COMPLETED, asyncRequestStatus);
1173         String msg= asyncInstantiationBL.readStatusMsg(resourceInfo);
1174         assertThat(msg, equalTo( expected));
1175     }
1176
1177     @Test
1178     public void testAddResourceInfoForOkResponse() {
1179         reset(asyncInstantiationRepository);
1180         String serviceInstanceId = "service-instance-id";
1181         UUID jobUuid = UUID.randomUUID();
1182
1183         asyncInstantiationBL.addResourceInfo(prepareSharedDataForAddResourceInfo(jobUuid), JobStatus.IN_PROGRESS, serviceInstanceId);
1184
1185         ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1186         verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1187
1188         ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1189         assertResourceInfoValues(resourceInfo, serviceInstanceId, jobUuid, JobStatus.IN_PROGRESS);
1190         assertThat(resourceInfo.getErrorMessage(), is(nullValue()));
1191     }
1192
1193     private JobSharedData prepareSharedDataForAddResourceInfo(UUID jobUuid) {
1194         ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class);
1195         when(serviceInstantiation.getTrackById()).thenReturn("track-by-id");
1196         return new JobSharedData(jobUuid, "", serviceInstantiation, "");
1197     }
1198
1199     private void assertResourceInfoValues(ResourceInfo resourceInfo, String serviceInstanceId, UUID jobUuid, JobStatus jobStatus) {
1200         assertThat(resourceInfo.getInstanceId(), equalTo(serviceInstanceId));
1201         assertThat(resourceInfo.getJobStatus(), equalTo(jobStatus));
1202         assertThat(resourceInfo.getRootJobId(), equalTo(jobUuid));
1203         assertThat(resourceInfo.getTrackById(), equalTo("track-by-id"));
1204     }
1205
1206     @DataProvider
1207     public static Object[][] addResourceInfoWithError() {
1208         String message = "Failed to create service instance";
1209         return new Object[][]{
1210                 {500, message},
1211                 {199, "{\"serviceException\":{\"messageId\":\"SVC2000\",\"text\":\"Error: " + message + "\"}}"}
1212         };
1213     }
1214
1215     @Test(dataProvider = "addResourceInfoWithError")
1216     public void testAddResourceInfoForErrorResponse(int errorCode, String errorMessage) {
1217         reset(asyncInstantiationRepository);
1218         UUID jobUuid = UUID.randomUUID();
1219
1220         RestObject restObject = mock(RestObject.class);
1221         when(restObject.getStatusCode()).thenReturn(errorCode);
1222         when(restObject.getRaw()).thenReturn(errorMessage);
1223         asyncInstantiationBL.addFailedResourceInfo(prepareSharedDataForAddResourceInfo(jobUuid), restObject);
1224
1225         ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1226         verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1227
1228         ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1229         assertResourceInfoValues(resourceInfo, null, jobUuid, JobStatus.FAILED);
1230         assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), containsString("Failed to create service instance"));
1231         assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), containsString(String.valueOf(errorCode)));
1232         ZonedDateTime parsedDate = TimeUtils.parseZonedDateTime(resourceInfo.getErrorMessage().request.requestStatus.getTimestamp());
1233         assertThat(parsedDate.toLocalDate(), is(LocalDate.now()));
1234
1235         doReturn(resourceInfo).when(asyncInstantiationRepository).getResourceInfoByTrackId(any());
1236         JobAuditStatus jobAuditStatus = auditService.getResourceAuditStatus(resourceInfo.getTrackById());
1237         assertThat(jobAuditStatus.getJobStatus(), equalTo("FAILED"));
1238         assertThat(jobAuditStatus.getAdditionalInfo(), containsString("Failed to create service instance"));
1239         assertThat(jobAuditStatus.getAdditionalInfo(), containsString(String.valueOf(errorCode)));
1240         assertTrue(DateUtils.isSameDay(jobAuditStatus.getCreatedDate(), new Date()));
1241     }
1242
1243     @DataProvider
1244     public static Object[][] updateResourceInfoParameters() {
1245         return new Object[][] {
1246                 {JobStatus.COMPLETED, "Instance was created successfully"},
1247                 {JobStatus.FAILED, "Failed to create instance"}
1248         };
1249     }
1250
1251     @Test(dataProvider = "updateResourceInfoParameters")
1252     public void testUpdateResourceInfo(JobStatus jobStatus, String message) {
1253         reset(asyncInstantiationRepository);
1254         UUID jobUuid = UUID.randomUUID();
1255         JobSharedData sharedData = new JobSharedData(jobUuid, "", mock(ServiceInstantiation.class),"");
1256
1257         ResourceInfo resourceInfoMock = new ResourceInfo();
1258         resourceInfoMock.setTrackById(UUID.randomUUID().toString());
1259         doReturn(resourceInfoMock).when(asyncInstantiationRepository).getResourceInfoByTrackId(any());
1260
1261         AsyncRequestStatus asyncRequestStatus = asyncInstantiationBL.convertMessageToAsyncRequestStatus(message);
1262
1263         asyncInstantiationBL.updateResourceInfo(sharedData, jobStatus, asyncRequestStatus);
1264
1265         ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1266         verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1267
1268         ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1269         assertThat(resourceInfo.getJobStatus(), equalTo(jobStatus));
1270         if (jobStatus == JobStatus.FAILED) {
1271             assertThat(resourceInfo.getErrorMessage(), is(not(nullValue())));
1272             assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), equalTo(message));
1273             ZonedDateTime parsedDate = TimeUtils.parseZonedDateTime(resourceInfo.getErrorMessage().request.requestStatus.getTimestamp());
1274             assertThat(parsedDate.toLocalDate(), is(LocalDate.now()));
1275         } else {
1276             assertThat(resourceInfo.getErrorMessage(), is(nullValue()));
1277         }
1278
1279         JobAuditStatus jobAuditStatus = auditService.getResourceAuditStatus(resourceInfo.getTrackById());
1280         if (jobStatus == JobStatus.FAILED) {
1281             assertThat(jobAuditStatus.getJobStatus(), equalTo("FAILED"));
1282             assertThat(jobAuditStatus.getAdditionalInfo(), equalTo(message));
1283         } else {
1284             assertThat(jobAuditStatus, is(nullValue()));
1285         }
1286
1287     }
1288
1289     static class MockedJob implements Job {
1290
1291         private static Map<UUID, MockedJob> uuidToJob = new HashMap<>();
1292
1293         public static void putJob(UUID uuid, MockedJob job) {
1294             uuidToJob.put(uuid, job);
1295         }
1296
1297         public static MockedJob getJob(UUID uuid) {
1298             return uuidToJob.get(uuid);
1299         }
1300
1301
1302         private String optimisticUniqueServiceInstanceName;
1303
1304         public MockedJob(String optimisticUniqueServiceInstanceName) {
1305             this.optimisticUniqueServiceInstanceName = optimisticUniqueServiceInstanceName;
1306         }
1307
1308         private UUID uuid = UUID.randomUUID();
1309
1310         @Override
1311         public UUID getUuid() {
1312             return uuid;
1313         }
1314
1315         @Override
1316         public void setUuid(UUID uuid) {
1317             this.uuid = uuid;
1318         }
1319
1320         @Override
1321         public JobStatus getStatus() {
1322             return JobStatus.PENDING;
1323         }
1324
1325         @Override
1326         public void setStatus(JobStatus status) {
1327
1328         }
1329
1330         @Override
1331         public Map<String, Object> getData() {
1332             return null;
1333         }
1334
1335         @Override
1336         public JobSharedData getSharedData() {
1337             return new JobSharedData(uuid, "", null,"");
1338         }
1339
1340         @Override
1341         public void setTypeAndData(JobType jobType, Map<String, Object> commandData) {
1342
1343         }
1344
1345         @Override
1346         public UUID getTemplateId() {
1347             return null;
1348         }
1349
1350         @Override
1351         public void setTemplateId(UUID templateId) {
1352
1353         }
1354
1355         @Override
1356         public Integer getIndexInBulk() {
1357             return null;
1358         }
1359
1360         @Override
1361         public void setIndexInBulk(Integer indexInBulk) {
1362
1363         }
1364
1365         @Override
1366         public JobType getType() {
1367             return null;
1368         }
1369
1370         public String getOptimisticUniqueServiceInstanceName() {
1371             return optimisticUniqueServiceInstanceName;
1372         }
1373     }
1374
1375
1376     @Test
1377     public void testGetVfModuleReplacePath_asMSOexpected()
1378     {
1379         String path = asyncInstantiationBL.getVfModuleReplacePath("myService", "myVNF", "myVFModule");
1380         assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myService/vnfs/myVNF/vfModules/myVFModule/replace"));
1381
1382     }
1383
1384 }