d1124f3a8ffa64ad96671f27d37b8907be6f1cc0
[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
495
496     @Test
497     public void whenPushBulkJob_thenJobRequestIsSaveInJobRequestDb() {
498         Mockito.reset(asyncInstantiationRepository);
499         int bulkSize = 3;
500         final ServiceInstantiation request = prepareServiceInstantiation(true, bulkSize);
501         when(jobsBrokerServiceMock.add(any())).thenReturn(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID());
502         List<UUID> jobIds = asyncInstantiationBL.pushBulkJob(request, "abc");
503
504         ArgumentCaptor<JobAdapter.AsyncJobRequest> asyncJobRequestCaptor = ArgumentCaptor.forClass(JobAdapter.AsyncJobRequest.class);
505         ArgumentCaptor<ServiceInstantiation> requestsCaptor = ArgumentCaptor.forClass(ServiceInstantiation.class);
506         ArgumentCaptor<UUID> uuidsCaptor = ArgumentCaptor.forClass(UUID.class);
507         verify(asyncInstantiationRepository, times(bulkSize)).addJobRequest(uuidsCaptor.capture(), requestsCaptor.capture());
508         verify(jobsBrokerServiceMock, times(bulkSize)).add(any());
509         verify(jobAdapterMock, times(bulkSize)).createServiceInstantiationJob(any(), asyncJobRequestCaptor.capture(), any(), any(), any(), any(), any());
510
511         //verify that all for each job we saved an row in jobRequest table
512         assertThat(uuidsCaptor.getAllValues(), containsInAnyOrder(jobIds.toArray()));
513
514         //assert that each real job we created with the adaptor, request is save in jobRequest table
515         assertThat(requestsCaptor.getAllValues(), containsInAnyOrder(asyncJobRequestCaptor.getAllValues().toArray()));
516
517         assertThat(requestsCaptor.getAllValues(),everyItem(hasProperty("bulkSize", is(1))));
518
519         //assert that the requests that save in DB are the same as original request expect of the trackById
520         requestsCaptor.getAllValues().forEach(x->assertJsonEquals(request, x, whenIgnoringPaths(
521                 "bulkSize",
522                 "trackById",
523                 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.trackById",
524                 "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",
525                 "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"
526         )));
527
528         //assert that each trackById on all bulk jobs is unique
529         Set<String> usedUUID = new HashSet<>();
530         requestsCaptor.getAllValues().forEach(x->assertTrackByIdRecursively(x, uuidRegexMatcher, usedUUID));
531     }
532
533     @Test
534     public void whenRetryJob_prevJobRetryIsDisabled() {
535         reset(asyncInstantiationRepository);
536         UUID jobId = UUID.randomUUID();
537         String userID = generateRandomAlphaNumeric(8);
538         addOriginalService(jobId, userID);
539         doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
540         asyncInstantiationBL.retryJob(jobId, userID);
541         assertRetryDisabled(jobId);
542     }
543
544     @Test
545     public void whenRetryJobWithEditedData_prevJobRetryIsDisabled() {
546         reset(asyncInstantiationRepository);
547         UUID jobId = UUID.randomUUID();
548         String userID = generateRandomAlphaNumeric(8);
549         addOriginalService(jobId, userID);
550         ServiceInstantiation editedServiceInstantiation = prepareServiceInstantiation("editedProjectName", true, 1);
551         asyncInstantiationBL.retryJob(editedServiceInstantiation, jobId, userID);
552         assertRetryDisabled(jobId);
553     }
554
555     @Test
556     public void retryJobWithEditedData_expectedNewJobDifferentData() {
557         reset(asyncInstantiationRepository);
558         UUID jobId = UUID.randomUUID();
559         String userID = generateRandomAlphaNumeric(8);
560         addOriginalService(jobId, userID);
561         ServiceInstantiation editedServiceInstantiation = prepareServiceInstantiation("editedProjectName", true, 1);
562         List<UUID> newJobIds =  asyncInstantiationBL.retryJob(editedServiceInstantiation, jobId, userID);
563         assertNewJobExistsAsExpectedAfterRetry(newJobIds, editedServiceInstantiation, jobId, userID);
564     }
565
566     @Test
567     public void retryJob_expectedNewJob() {
568         reset(asyncInstantiationRepository);
569         UUID jobId = UUID.randomUUID();
570         String userID = "az2016";
571         ServiceInstantiation originalServiceInstantiation =  addOriginalService(jobId, userID);
572         doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
573         List<UUID> newJobIds = asyncInstantiationBL.retryJob(jobId, userID);
574         assertNewJobExistsAsExpectedAfterRetry(newJobIds, originalServiceInstantiation, jobId, userID);
575     }
576
577     @Test (dataProvider = "aLaCarteAndMacroPayload")
578     public void generateMockServiceInstantiationPayload_serializeBackAndForth_sourceShouldBeTheSame(ServiceInstantiation serviceInstantiationPayload) throws IOException {
579         ObjectMapper mapper = new ObjectMapper();
580         final String asString = mapper.writeValueAsString(serviceInstantiationPayload);
581
582         final ServiceInstantiation asObject = mapper.readValue(asString, ServiceInstantiation.class);
583         final String asString2 = mapper.writeValueAsString(asObject);
584
585         assertJsonEquals(asString, asString2);
586     }
587
588     @DataProvider
589     public Object[][] aLaCarteAndMacroPayload() {
590         ServiceInstantiation macroPayload = generateMockMacroServiceInstantiationPayload(
591                 false,
592                 createVnfList(instanceParamsMapWithoutParams, ImmutableList.of(vnfInstanceParamsMapWithParamsToRemove, vnfInstanceParamsMapWithParamsToRemove), true),
593                 2, false,PROJECT_NAME, false);
594         ServiceInstantiation aLaCartePayload = generateALaCarteServiceInstantiationPayload();
595
596         return new Object[][]{
597                 {macroPayload},
598                 {aLaCartePayload}
599         };
600     }
601
602     public static class ServiceInfoComparator implements Comparator<ServiceInfo> {
603
604         @Override
605         public int compare(ServiceInfo o1, ServiceInfo o2) {
606             int compare;
607
608             compare = o1.getCreatedBulkDate().compareTo(o2.getCreatedBulkDate());
609             if (compare != 0) {
610                 return -compare;
611             }
612
613             // check jobStatus priority
614             int o1Priority = getPriority(o1);
615             int o2Priority = getPriority(o2);
616             compare = o1Priority - o2Priority;
617             if (compare != 0) {
618                 return compare;
619             }
620
621             // check statusModifiedDate
622             return o1.getStatusModifiedDate().compareTo(o2.getStatusModifiedDate());
623         }
624
625         private int getPriority(ServiceInfo o) throws JSONException {
626             Job.JobStatus status = o.getJobStatus();
627             switch (status) {
628                 case COMPLETED:
629                 case FAILED:
630                     return 1;
631                 case IN_PROGRESS:
632                     return 2;
633                 case PAUSE:
634                     return 3;
635                 case STOPPED:
636                 case PENDING:
637                     return 4;
638                 default:
639                     return 5;
640             }
641         }
642     }
643
644     @DataProvider
645     public Object[][] pauseAndInstanceParams() {
646         return new Object[][]{
647                 {Boolean.TRUE, instanceParamsMapWithoutParams, Collections.EMPTY_LIST},
648                 {Boolean.FALSE, instanceParamsMapWithoutParams, Collections.EMPTY_LIST},
649                 {Boolean.TRUE, vfModuleInstanceParamsMapWithParamsToRemove, Collections.singletonList(vnfInstanceParamsMapWithParamsToRemove)}
650         };
651     }
652
653     @Test
654     public void testUpdateServiceInfo_WithExistingServiceInfo_ServiceInfoIsUpdated() {
655         UUID uuid = createFakedJobAndServiceInfo();
656         final String STEPH_CURRY = "Steph Curry";
657         asyncInstantiationBL.updateServiceInfo(uuid, x -> {
658             x.setServiceInstanceName(STEPH_CURRY);
659             x.setJobStatus(Job.JobStatus.IN_PROGRESS);
660         });
661         Optional<ServiceInfo> optionalServiceInfo = getJobById(uuid);
662         assertThat(optionalServiceInfo.get().getServiceInstanceName(), equalTo(STEPH_CURRY));
663         assertThat(optionalServiceInfo.get().getJobStatus(), equalTo(Job.JobStatus.IN_PROGRESS));
664     }
665
666     private Optional<ServiceInfo> getJobById(UUID jobId) {
667         List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, null);
668         return serviceInfoList.stream().filter(x -> jobId.equals(x.getJobId())).findFirst();
669     }
670
671     private UUID createFakedJobAndServiceInfo() {
672         UUID uuid = UUID.randomUUID();
673         addNewJob(uuid);
674         ServiceInfo serviceInfo = new ServiceInfo();
675         serviceInfo.setServiceInstanceName("Lebron James");
676         serviceInfo.setJobId(uuid);
677         serviceInfo.setJobStatus(Job.JobStatus.PENDING);
678         dataAccessService.saveDomainObject(serviceInfo, getPropsMap());
679         return uuid;
680     }
681
682     @Test(expectedExceptions = NotFoundException.class, expectedExceptionsMessageRegExp = UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE)
683     public void testUpdateServiceInfo_WithNonExisting_ThrowException() {
684         asyncInstantiationBL.updateServiceInfo(UUID.randomUUID(), x -> x.setServiceInstanceName("not matter"));
685     }
686
687     @Test(expectedExceptions = NotFoundException.class, expectedExceptionsMessageRegExp = UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE)
688     public void testUpdateServiceInfo_WithDoubleServiceWithSameJobUuid_ThrowException() {
689         UUID uuid = createFakedJobAndServiceInfo();
690         ServiceInfo serviceInfo = new ServiceInfo();
691         serviceInfo.setJobId(uuid);
692         dataAccessService.saveDomainObject(serviceInfo, getPropsMap());
693         asyncInstantiationBL.updateServiceInfo(UUID.randomUUID(), x -> x.setServiceInstanceName("not matter"));
694     }
695
696
697     @DataProvider
698     public static Object[][] isPauseAndPropertyDataProvider() {
699         return new Object[][]{
700                 {true, "mso.restapi.serviceInstanceAssign"},
701                 {false, "mso.restapi.service.instance"},
702         };
703     }
704
705
706     @Test(dataProvider = "isPauseAndPropertyDataProvider")
707     public void testServiceInstantiationPath_RequestPathIsAsExpected(boolean isPause, String expectedProperty) {
708         ServiceInstantiation serviceInstantiationPauseFlagTrue = generateMacroMockServiceInstantiationPayload(isPause, createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true));
709         String path = asyncInstantiationBL.getServiceInstantiationPath(serviceInstantiationPauseFlagTrue);
710         Assert.assertEquals(path, SystemProperties.getProperty(expectedProperty));
711     }
712
713     @Test
714     public void testCreateVnfEndpoint_useProvidedInstanceId() {
715         String path = asyncInstantiationBL.getVnfInstantiationPath("myGreatId");
716         assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myGreatId/vnfs"));
717     }
718
719
720
721     @Test
722     public void pushBulkJob_macroServiceverifyCreatedDateBehavior_createdDateIsTheSameForAllServicesInSameBulk() {
723         LocalDateTime startTestDate = LocalDateTime.now().withNano(0);
724         final ServiceInstantiation request = generateMockMacroServiceInstantiationPayload(
725                 false,
726                 createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true),
727                 100, true,PROJECT_NAME, true
728         );
729
730         pushJobAndAssertDates(startTestDate, request);
731     }
732
733     @Test
734     public void whenCreateServiceInfo_thenModelId_isModelVersionId() {
735         ServiceInfo serviceInfo = asyncInstantiationBL.createServiceInfo("userID",
736                 generateALaCarteWithVnfsServiceInstantiationPayload(),
737                 UUID.randomUUID(),
738                 UUID.randomUUID(),
739                 new Date(),
740                 "myName", ServiceInfo.ServiceAction.INSTANTIATE);
741         assertEquals(SERVICE_MODEL_VERSION_ID, serviceInfo.getServiceModelId());
742
743     }
744
745     @Test
746     public void pushBulkJob_aLaCarteServiceverifyCreatedDateBehavior_createdDateIsTheSameForAllServicesInSameBulk() {
747         LocalDateTime startTestDate = LocalDateTime.now().withNano(0);
748         final ServiceInstantiation request = generateALaCarteServiceInstantiationPayload();
749         pushJobAndAssertDates(startTestDate, request);
750     }
751
752     protected void pushJobAndAssertDates(LocalDateTime startTestDate, ServiceInstantiation request) {
753         // in "createServiceInstantiationJob()" we will probe the service, with the generated names
754         configureMockitoWithMockedJob();
755
756         asyncInstantiationBL.pushBulkJob(request, "myUserId");
757         List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, getPropsMap());
758
759         List<Date> creationDates = new ArrayList<>();
760         for (ServiceInfo serviceInfo : serviceInfoList) {
761             creationDates.add(serviceInfo.getCreatedBulkDate());
762         }
763         LocalDateTime endTestDate = LocalDateTime.now();
764
765         //creation date of all services is the same
766         Assert.assertTrue(creationDates.stream().distinct().count() <= 1);
767         LocalDateTime creationDate = fromDate(creationDates.get(0));
768         assertFalse(creationDate.isBefore(startTestDate));
769         assertFalse(creationDate.isAfter(endTestDate));
770     }
771
772     protected void configureMockitoWithMockedJob() {
773         Mockito.reset(jobAdapterMock);
774         final Job job = mock(Job.class);
775         when(job.getStatus()).thenReturn(PENDING);
776         when(job.getUuid()).thenReturn(UUID.fromString("db2c5ed9-1c19-41ce-9cb7-edf0d878cdeb"));
777         when(jobAdapterMock.createServiceInstantiationJob(any(), any(), any(), any(), any(), any(), any())).thenReturn(job);
778         when(jobsBrokerServiceMock.add(job)).thenReturn(UUID.randomUUID());
779     }
780
781     @DataProvider
782     public static Object[][] msoToJobStatusDataProvider() {
783         return new Object[][]{
784                 {"IN_PROGRESS", JobStatus.IN_PROGRESS},
785                 {"INPROGRESS", JobStatus.IN_PROGRESS},
786                 {"IN ProGREsS", JobStatus.IN_PROGRESS},
787                 {"JAMES_HARDEN", JobStatus.IN_PROGRESS},
788                 {"FAILED", JobStatus.FAILED},
789                 {"COMpleTE", JobStatus.COMPLETED},
790                 {"PENDING", JobStatus.IN_PROGRESS},
791                 {"Paused", JobStatus.PAUSE},
792                 {"Pause", JobStatus.PAUSE},
793                 {"PENDING_MANUAL_TASK", JobStatus.PAUSE},
794                 {"UNLOCKED", JobStatus.IN_PROGRESS},
795                 {"AbORtEd", COMPLETED_WITH_ERRORS},
796                 {"RoLlED_baCK", FAILED},
797                 {"ROllED_BAcK_To_ASsIGnED", FAILED},
798                 {"rOLLED_bACK_tO_CrEATeD", FAILED},
799         };
800     }
801
802     @Test(dataProvider = "msoToJobStatusDataProvider")
803     public void whenGetStatusFromMso_calcRightJobStatus(String msoStatus, Job.JobStatus expectedJobStatus) {
804         AsyncRequestStatus asyncRequestStatus = asyncRequestStatusResponse(msoStatus);
805         assertThat(asyncInstantiationBL.calcStatus(asyncRequestStatus), equalTo(expectedJobStatus));
806     }
807
808     @DataProvider
809     public static Object[][] msoRequestStatusFiles(Method test) {
810         return new Object[][]{
811                 {"/responses/mso/orchestrationRequestsServiceInstance.json"},
812                 {"/responses/mso/orchestrationRequestsVnf.json"},
813                 {"/responses/mso/orchestrationRequestsMockedMinimalResponse.json"}
814         };
815     }
816
817     @Test(dataProvider="msoRequestStatusFiles")
818     public void verifyAsyncRequestStatus_canBeReadFromSample(String msoResponseFile) throws IOException {
819         AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
820                 msoResponseFile,
821                 AsyncRequestStatus.class);
822         assertThat(asyncRequestStatus.request.requestStatus.getRequestState(), equalTo("COMPLETE"));
823     }
824
825     @Test
826     public void deleteJobInfo_pending_deleted() {
827         doNothing().when(jobsBrokerServiceMock).delete(any());
828         UUID uuid = createServicesInfoWithDefaultValues(PENDING);
829         asyncInstantiationBL.deleteJob(uuid);
830         assertNotNull(asyncInstantiationRepository.getServiceInfoByJobId(uuid).getDeletedAt(), "service info wasn't deleted");
831     }
832
833     @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE)
834     public void deleteJobInfo_notAllowdStatus_shouldSendError() {
835         UUID uuid = createServicesInfoWithDefaultValues(COMPLETED);
836         doThrow(new IllegalStateException(DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE)).when(jobsBrokerServiceMock).delete(any());
837         try {
838             asyncInstantiationBL.deleteJob(uuid);
839         } catch (Exception e) {
840             assertNull(asyncInstantiationRepository.getServiceInfoByJobId(uuid).getDeletedAt(), "service info shouldn't deleted");
841             throw e;
842         }
843     }
844
845     @DataProvider
846     public Object[][] jobStatusesFinal() {
847         return Arrays.stream(Job.JobStatus.values())
848                 .filter(t -> ImmutableList.of(COMPLETED, FAILED, STOPPED).contains(t))
849                 .map(v -> new Object[]{v}).collect(Collectors.toList()).toArray(new Object[][]{});
850     }
851
852     @Test(dataProvider = "jobStatusesFinal")
853     public void whenHideService_theServiceNotReturnedInServiceList(JobStatus jobStatus) {
854         UUID uuidToHide = createServicesInfoWithDefaultValues(jobStatus);
855         UUID uuidToShown = createServicesInfoWithDefaultValues(jobStatus);
856         List<UUID> serviceInfoList = listServicesUUID();
857         assertThat(serviceInfoList, hasItems(uuidToHide, uuidToShown));
858
859         asyncInstantiationBL.hideServiceInfo(uuidToHide);
860         serviceInfoList = listServicesUUID();
861         assertThat(serviceInfoList, hasItem(uuidToShown));
862         assertThat(serviceInfoList, not(hasItem(uuidToHide)));
863
864     }
865
866     protected List<UUID> listServicesUUID() {
867         return asyncInstantiationBL.getAllServicesInfo().stream().map(ServiceInfo::getJobId).collect(Collectors.toList());
868     }
869
870     @DataProvider
871     public Object[][] jobStatusesNotFinal() {
872         return Arrays.stream(Job.JobStatus.values())
873                 .filter(t -> ImmutableList.of(PENDING, IN_PROGRESS, PAUSE).contains(t))
874                 .map(v -> new Object[]{v}).collect(Collectors.toList()).toArray(new Object[][]{});
875     }
876
877     @Test(dataProvider = "jobStatusesNotFinal",
878             expectedExceptions = OperationNotAllowedException.class,
879             expectedExceptionsMessageRegExp = "jobId.*Service status does not allow hide service, status = .*")
880     public void hideServiceInfo_notAllowedStatus_shouldSendError(JobStatus jobStatus) {
881         UUID uuid = createServicesInfoWithDefaultValues(jobStatus);
882         try {
883             asyncInstantiationBL.hideServiceInfo(uuid);
884         } catch (Exception e) {
885             assertFalse(asyncInstantiationRepository.getServiceInfoByJobId(uuid).isHidden(), "service info shouldn't be hidden");
886             throw e;
887         }
888     }
889
890     @Test
891     public void whenUseGetCounterInMultiThreads_EachThreadGetDifferentCounter() throws InterruptedException {
892         int SIZE = 200;
893         ExecutorService executor = Executors.newFixedThreadPool(SIZE);
894         List<Callable<Integer>> tasks = IntStream.rangeClosed(0, SIZE)
895                 .mapToObj(x-> ((Callable<Integer>)() -> asyncInstantiationBL.getCounterForName("a")))
896                 .collect(Collectors.toList());
897         Set<Integer> expectedResults = IntStream.rangeClosed(0, SIZE).boxed().collect(Collectors.toSet());
898         executor.invokeAll(tasks)
899                 .forEach(future -> {
900                     try {
901                         assertTrue( expectedResults.remove(future.get()), "got unexpected counter");
902                     }
903                     catch (Exception e) {
904                         throw new RuntimeException(e);
905                     }
906                 });
907
908         assertThat(expectedResults.size(), is(0));
909     }
910
911     @Test
912     public void whenUseGetCounterForSameName_numbersReturnedByOrder() {
913
914         String name = UUID.randomUUID().toString();
915         int SIZE=10;
916         for (int i=0; i<SIZE; i++) {
917             assertThat(asyncInstantiationBL.getCounterForName(name), is(i));
918         }
919     }
920
921     @Test
922     public void whenNamedInUsedInAai_getNextNumber() {
923         String name = someCommonStepsAndGetName();
924         ResourceType type = ResourceType.GENERIC_VNF;
925         when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(true);
926         when(aaiClient.isNodeTypeExistsByName(name+"_001", type)).thenReturn(false);
927         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name+"_001"));
928     }
929
930     @Test(enabled = false) //skip till we will handle macro bulk again...
931     public void whenNamedNotInUsedInAai_getSameNameTwice() {
932         String name = someCommonStepsAndGetName();
933         ResourceType type = ResourceType.GENERIC_VNF;
934         when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(false);
935         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name));
936         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name));
937         when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(true);
938         assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name+"_001"));
939     }
940
941     private String someCommonStepsAndGetName() {
942         mockAaiClientAaiStatusOK();
943         return UUID.randomUUID().toString();
944     }
945
946     @Test(expectedExceptions= ExceptionWithRequestInfo.class)
947     public void whenAaiBadResponseCode_throwInvalidAAIResponseException() {
948         String name = someCommonStepsAndGetName();
949         ResourceType type = ResourceType.SERVICE_INSTANCE;
950         when(aaiClient.isNodeTypeExistsByName(name, type)).thenThrow(aaiNodeQueryBadResponseException());
951         asyncInstantiationBL.getUniqueName(name, type);
952     }
953
954     @Test(expectedExceptions=MaxRetriesException.class)
955     public void whenAaiAlwaysReturnNameUsed_throwInvalidAAIResponseException() {
956         String name = someCommonStepsAndGetName();
957         ResourceType type = ResourceType.VF_MODULE;
958         when(aaiClient.isNodeTypeExistsByName(any(), eq(type))).thenReturn(true);
959         asyncInstantiationBL.setMaxRetriesGettingFreeNameFromAai(10);
960         asyncInstantiationBL.getUniqueName(name, type);
961     }
962
963     @Test
964     public void testFormattingOfNameAndCounter() {
965         AsyncInstantiationBusinessLogicImpl bl = (AsyncInstantiationBusinessLogicImpl) asyncInstantiationBL;
966         assertThat(bl.formatNameAndCounter("x", 0), equalTo("x"));
967         assertThat(bl.formatNameAndCounter("x", 3), equalTo("x_003"));
968         assertThat(bl.formatNameAndCounter("x", 99), equalTo("x_099"));
969         assertThat(bl.formatNameAndCounter("x", 100), equalTo("x_100"));
970         assertThat(bl.formatNameAndCounter("x", 1234), equalTo("x_1234"));
971     }
972
973     @Test
974     public void pushBulkJob_verifyAlacarteFlow_useALaCartServiceInstantiationJobType(){
975         final ServiceInstantiation request = generateALaCarteServiceInstantiationPayload();
976
977         // in "createServiceInstantiationJob()" we will probe the service, with the generated names
978         configureMockitoWithMockedJob();
979
980         ArgumentCaptor<JobType> argumentCaptor = ArgumentCaptor.forClass(JobType.class);
981         asyncInstantiationBL.pushBulkJob(request, "myUserId");
982         verify(jobAdapterMock).createServiceInstantiationJob(argumentCaptor.capture(),any(),any(),anyString(), anyString(),  anyString(), anyInt());
983         assertTrue(argumentCaptor.getValue().equals(JobType.ALaCarteServiceInstantiation));
984     }
985
986     @Test
987     public void pushBulkJob_verifyMacroFlow_useMacroServiceInstantiationJobType(){
988         final ServiceInstantiation request = generateMacroMockServiceInstantiationPayload(false, Collections.emptyMap());
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(), any(),  anyString(), anyInt());
996         assertTrue(argumentCaptor.getValue().equals(JobType.MacroServiceInstantiation));
997     }
998
999
1000
1001     @Test
1002     public void getALaCarteServiceDeletionPath_verifyPathIsAsExpected() {
1003
1004         String expected = "/serviceInstantiation/v7/serviceInstances/f36f5734-e9df-4fbf-9f35-61be13f028a1";
1005
1006         String result = asyncInstantiationBL.getServiceDeletionPath("f36f5734-e9df-4fbf-9f35-61be13f028a1");
1007
1008         assertThat(expected,equalTo(result));
1009     }
1010
1011     @Test
1012     public void getResumeRequestPath_verifyPathIsAsExpected() {
1013
1014         String expected = "/orchestrationRequests/v7/rq1234d1-5a33-55df-13ab-12abad84e333/resume";
1015
1016         String result = asyncInstantiationBL.getResumeRequestPath("rq1234d1-5a33-55df-13ab-12abad84e333");
1017
1018         assertThat(expected, equalTo(result));
1019     }
1020
1021     @Test
1022     public void getInstanceGroupsDeletionPath_verifyPathIsAsExpected()  {
1023         assertEquals(asyncInstantiationBL.getInstanceGroupDeletePath("9aada4af-0f9b-424f-ae21-e693bd3e005b"),
1024                 "/serviceInstantiation/v7/instanceGroups/9aada4af-0f9b-424f-ae21-e693bd3e005b");
1025     }
1026
1027     @Test
1028     public void whenLcpRegionNotEmpty_thenCloudRegionIdOfResourceIsLegacy() {
1029         String legacyCloudRegion = "legacyCloudRegion";
1030         Vnf vnf = new Vnf(new ModelInfo(), null, null, Action.Create.name(), null, "anyCloudRegion", legacyCloudRegion,
1031                 null, null, null, false, null, null, UUID.randomUUID().toString(), null, null, null);
1032         assertThat(vnf.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
1033     }
1034
1035     @Test
1036     public void whenLcpRegionNotEmpty_thenCloudRegionIdOfServiceIsLegacy() {
1037         String legacyCloudRegion = "legacyCloudRegion";
1038         ServiceInstantiation service = new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
1039                 null, null, "anyCloudRegion", legacyCloudRegion, null, null, null, null, null, null, null, null, null,
1040                 false, 1,false, false, null, null, Action.Create.name(), UUID.randomUUID().toString(), null, null, null);
1041         assertThat(service.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
1042     }
1043
1044     @DataProvider
1045     public static Object[][] getJobTypeByRequest_verifyResultAsExpectedDataProvider() {
1046         return new Object[][]{
1047                 {false, Action.Create, JobType.MacroServiceInstantiation},
1048                 {true, Action.Create, JobType.ALaCarteServiceInstantiation},
1049                 {true, Action.Delete, JobType.ALaCarteService},
1050         };
1051     }
1052
1053     @Test(dataProvider = "getJobTypeByRequest_verifyResultAsExpectedDataProvider")
1054     public void getJobTypeByRequest_verifyResultAsExpected(boolean isALaCarte, Action action, JobType expectedJobType) {
1055         ServiceInstantiation service = createServiceWithIsALaCarteAndAction(isALaCarte, action);
1056         assertThat(asyncInstantiationBL.getJobType(service), equalTo(expectedJobType));
1057     }
1058
1059     @NotNull
1060     protected ServiceInstantiation createServiceWithIsALaCarteAndAction(boolean isALaCarte, Action action) {
1061         return new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
1062                 null, null, null, null, null, null, null, null, null, null, null, null, null,
1063                 false, 1, false, isALaCarte, null, null, action.name(),
1064                 UUID.randomUUID().toString(), null, null, null);
1065     }
1066
1067     @DataProvider
1068     public static Object[][] isRetryEnabledForStatusDataProvider(Method test) {
1069         return new Object[][]{
1070                 {FAILED, true, true},
1071                 {COMPLETED_WITH_ERRORS, true, true},
1072                 {COMPLETED_WITH_NO_ACTION, true, false},
1073                 {COMPLETED, true, false},
1074                 {IN_PROGRESS, true, false},
1075                 {FAILED, false, false},
1076                 {COMPLETED_WITH_ERRORS, false, false},
1077                 {COMPLETED, false, false},
1078         };
1079     }
1080
1081     @Test(dataProvider = "isRetryEnabledForStatusDataProvider")
1082     public void whenUpdateServiceInfoAndAuditStatus_thenServiceInfoRowIsUpdatedAndIsRetryIsRight(
1083             JobStatus jobStatus, boolean isRetryfeatureEnabled, boolean expectedIsRetry) {
1084         when(featureManager.isActive(Features.FLAG_1902_RETRY_JOB)).thenReturn(isRetryfeatureEnabled);
1085         UUID uuid = createFakedJobAndServiceInfo();
1086         asyncInstantiationBL.updateServiceInfoAndAuditStatus(uuid, jobStatus);
1087         ServiceInfo serviceInfo = ((List<ServiceInfo>)dataAccessService.getList(ServiceInfo.class, getPropsMap())).
1088                 stream().filter(x->x.getJobId().equals(uuid)).findFirst().get();
1089         assertEquals(jobStatus, serviceInfo.getJobStatus());
1090
1091         //we don't test serviceInfo.getStatusModifiedDate() because it's too complicated
1092
1093         assertEquals(expectedIsRetry, serviceInfo.isRetryEnabled());
1094     }
1095
1096     @Test
1097     public void givenServiceWithNullTrackByIds_whenReplaceTrackByIds_thenAllLevelsHasTrackByIdWithUUID() {
1098         ServiceInstantiation serviceInstantiation = FakeResourceCreator.createServiceWith2InstancesInEachLevel(Action.Create);
1099         //assert for the given that all trackById are null
1100         assertTrackByIdRecursively(serviceInstantiation, is(nullValue()), new HashSet<>());
1101         ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.prepareServiceToBeUnique(serviceInstantiation);
1102         assertTrackByIdRecursively(modifiedServiceInstantiation, uuidRegexMatcher, new HashSet<>());
1103     }
1104
1105     private void assertTrackByIdRecursively(BaseResource baseResource, org.hamcrest.Matcher matcher, Set<String> usedUuids) {
1106         assertThat(baseResource.getTrackById(), matcher);
1107         if (baseResource.getTrackById()!=null) {
1108             assertThat(usedUuids, not(hasItem(baseResource.getTrackById())));
1109             usedUuids.add(baseResource.getTrackById());
1110         }
1111         baseResource.getChildren().forEach(x->assertTrackByIdRecursively(x, matcher, usedUuids));
1112     }
1113
1114     @Test
1115     public void givenServicefromDB_returnsTheBulkRequest() throws IOException {
1116         ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1Request.json", ServiceInstantiation.class);
1117         UUID jobId = UUID.randomUUID();
1118         doReturn(serviceInstantiation).when(asyncInstantiationRepository).getJobRequest(jobId);
1119         doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
1120         ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.getBulkForRetry(jobId);
1121         assertThat(modifiedServiceInstantiation, jsonEquals(serviceInstantiation).when(IGNORING_ARRAY_ORDER));
1122     }
1123
1124     @Test
1125     public void givenServiceFromDB_returnsResolvedData() throws IOException {
1126         ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1Request.json", ServiceInstantiation.class);
1127         ServiceInstantiation expectedServiceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1RequestResolvedForRetry.json", ServiceInstantiation.class);
1128         UUID jobId = UUID.randomUUID();
1129         AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
1130                 "/responses/mso/orchestrationRequestsVnf.json",
1131                 AsyncRequestStatus.class);
1132         Map<String, ResourceInfo> mockedResourceInfoMap = ImmutableMap.of(
1133                 "groupingservicefortest..ResourceInstanceGroup..0:001", new ResourceInfo("groupingservicefortest..ResourceInstanceGroup..0:001",jobId,"VNF_GROUP1_INSTANCE_ID", COMPLETED, asyncRequestStatus),// TODO case: delete completed
1134                 "ag5aav86u4j", new ResourceInfo("ag5aav86u4j",jobId, null, FAILED, asyncRequestStatus),// case: failed
1135                 "asedrftjko", new ResourceInfo("asedrftjko",jobId, "VNF_GROUP1_INSTANCE_ID_3", COMPLETED, asyncRequestStatus),//case: completed after retry failed
1136                 "rgedfdged4", new ResourceInfo("rgedfdged4", jobId,"VNF_GROUP1_INSTANCE_ID_4", COMPLETED, asyncRequestStatus ));// case: create completed
1137
1138         doReturn(mockedResourceInfoMap).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
1139         ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.enrichBulkForRetry(serviceInstantiation,jobId);
1140         assertThat(modifiedServiceInstantiation, jsonEquals(expectedServiceInstantiation).when(IGNORING_ARRAY_ORDER));
1141     }
1142
1143     @DataProvider
1144     public static Object[][] readStatusMsgDataProvider(Method test) throws IOException {
1145         AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
1146                 "/responses/mso/orchestrationRequestsVnf.json",
1147                 AsyncRequestStatus.class);
1148         return new Object[][]{
1149                 {null, null},
1150                 {new AsyncRequestStatus(), null},
1151                 {new AsyncRequestStatus(new AsyncRequestStatus.Request()), null},
1152                 {new AsyncRequestStatus(new AsyncRequestStatus.Request(new RequestStatus())), null},
1153                 {asyncRequestStatus, "Vnf has been created successfully."}
1154         };
1155     }
1156
1157     @Test(dataProvider = "readStatusMsgDataProvider")
1158     public void resourceInfoReadStatusMsg_returnsStatusMsgOrNull(AsyncRequestStatus asyncRequestStatus, String expected) {
1159         ResourceInfo resourceInfo = new ResourceInfo("groupingservicefortest..ResourceInstanceGroup..0:001",UUID.randomUUID(),"VNF_GROUP1_INSTANCE_ID", COMPLETED, asyncRequestStatus);
1160         String msg= asyncInstantiationBL.readStatusMsg(resourceInfo);
1161         assertThat(msg, equalTo( expected));
1162     }
1163
1164     @Test
1165     public void testAddResourceInfoForOkResponse() {
1166         reset(asyncInstantiationRepository);
1167         String serviceInstanceId = "service-instance-id";
1168         UUID jobUuid = UUID.randomUUID();
1169
1170         asyncInstantiationBL.addResourceInfo(prepareSharedDataForAddResourceInfo(jobUuid), JobStatus.IN_PROGRESS, serviceInstanceId);
1171
1172         ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1173         verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1174
1175         ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1176         assertResourceInfoValues(resourceInfo, serviceInstanceId, jobUuid, JobStatus.IN_PROGRESS);
1177         assertThat(resourceInfo.getErrorMessage(), is(nullValue()));
1178     }
1179
1180     private JobSharedData prepareSharedDataForAddResourceInfo(UUID jobUuid) {
1181         ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class);
1182         when(serviceInstantiation.getTrackById()).thenReturn("track-by-id");
1183         return new JobSharedData(jobUuid, "", serviceInstantiation, "");
1184     }
1185
1186     private void assertResourceInfoValues(ResourceInfo resourceInfo, String serviceInstanceId, UUID jobUuid, JobStatus jobStatus) {
1187         assertThat(resourceInfo.getInstanceId(), equalTo(serviceInstanceId));
1188         assertThat(resourceInfo.getJobStatus(), equalTo(jobStatus));
1189         assertThat(resourceInfo.getRootJobId(), equalTo(jobUuid));
1190         assertThat(resourceInfo.getTrackById(), equalTo("track-by-id"));
1191     }
1192
1193     @DataProvider
1194     public static Object[][] addResourceInfoWithError() {
1195         String message = "Failed to create service instance";
1196         return new Object[][]{
1197                 {500, message},
1198                 {199, "{\"serviceException\":{\"messageId\":\"SVC2000\",\"text\":\"Error: " + message + "\"}}"}
1199         };
1200     }
1201
1202     @Test(dataProvider = "addResourceInfoWithError")
1203     public void testAddResourceInfoForErrorResponse(int errorCode, String errorMessage) {
1204         reset(asyncInstantiationRepository);
1205         UUID jobUuid = UUID.randomUUID();
1206
1207         RestObject restObject = mock(RestObject.class);
1208         when(restObject.getStatusCode()).thenReturn(errorCode);
1209         when(restObject.getRaw()).thenReturn(errorMessage);
1210         asyncInstantiationBL.addFailedResourceInfo(prepareSharedDataForAddResourceInfo(jobUuid), restObject);
1211
1212         ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1213         verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1214
1215         ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1216         assertResourceInfoValues(resourceInfo, null, jobUuid, JobStatus.FAILED);
1217         assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), containsString("Failed to create service instance"));
1218         assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), containsString(String.valueOf(errorCode)));
1219         ZonedDateTime parsedDate = TimeUtils.parseZonedDateTime(resourceInfo.getErrorMessage().request.requestStatus.getTimestamp());
1220         assertThat(parsedDate.toLocalDate(), is(LocalDate.now()));
1221
1222         doReturn(resourceInfo).when(asyncInstantiationRepository).getResourceInfoByTrackId(any());
1223         JobAuditStatus jobAuditStatus = auditService.getResourceAuditStatus(resourceInfo.getTrackById());
1224         assertThat(jobAuditStatus.getJobStatus(), equalTo("FAILED"));
1225         assertThat(jobAuditStatus.getAdditionalInfo(), containsString("Failed to create service instance"));
1226         assertThat(jobAuditStatus.getAdditionalInfo(), containsString(String.valueOf(errorCode)));
1227         assertTrue(DateUtils.isSameDay(jobAuditStatus.getCreatedDate(), new Date()));
1228     }
1229
1230     @DataProvider
1231     public static Object[][] updateResourceInfoParameters() {
1232         return new Object[][] {
1233                 {JobStatus.COMPLETED, "Instance was created successfully"},
1234                 {JobStatus.FAILED, "Failed to create instance"}
1235         };
1236     }
1237
1238     @Test(dataProvider = "updateResourceInfoParameters")
1239     public void testUpdateResourceInfo(JobStatus jobStatus, String message) {
1240         reset(asyncInstantiationRepository);
1241         UUID jobUuid = UUID.randomUUID();
1242         JobSharedData sharedData = new JobSharedData(jobUuid, "", mock(ServiceInstantiation.class),"");
1243
1244         ResourceInfo resourceInfoMock = new ResourceInfo();
1245         resourceInfoMock.setTrackById(UUID.randomUUID().toString());
1246         doReturn(resourceInfoMock).when(asyncInstantiationRepository).getResourceInfoByTrackId(any());
1247
1248         AsyncRequestStatus asyncRequestStatus = asyncInstantiationBL.convertMessageToAsyncRequestStatus(message);
1249
1250         asyncInstantiationBL.updateResourceInfo(sharedData, jobStatus, asyncRequestStatus);
1251
1252         ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1253         verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1254
1255         ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1256         assertThat(resourceInfo.getJobStatus(), equalTo(jobStatus));
1257         if (jobStatus == JobStatus.FAILED) {
1258             assertThat(resourceInfo.getErrorMessage(), is(not(nullValue())));
1259             assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), equalTo(message));
1260             ZonedDateTime parsedDate = TimeUtils.parseZonedDateTime(resourceInfo.getErrorMessage().request.requestStatus.getTimestamp());
1261             assertThat(parsedDate.toLocalDate(), is(LocalDate.now()));
1262         } else {
1263             assertThat(resourceInfo.getErrorMessage(), is(nullValue()));
1264         }
1265
1266         JobAuditStatus jobAuditStatus = auditService.getResourceAuditStatus(resourceInfo.getTrackById());
1267         if (jobStatus == JobStatus.FAILED) {
1268             assertThat(jobAuditStatus.getJobStatus(), equalTo("FAILED"));
1269             assertThat(jobAuditStatus.getAdditionalInfo(), equalTo(message));
1270         } else {
1271             assertThat(jobAuditStatus, is(nullValue()));
1272         }
1273
1274     }
1275
1276     static class MockedJob implements Job {
1277
1278         private static Map<UUID, MockedJob> uuidToJob = new HashMap<>();
1279
1280         public static void putJob(UUID uuid, MockedJob job) {
1281             uuidToJob.put(uuid, job);
1282         }
1283
1284         public static MockedJob getJob(UUID uuid) {
1285             return uuidToJob.get(uuid);
1286         }
1287
1288
1289         private String optimisticUniqueServiceInstanceName;
1290
1291         public MockedJob(String optimisticUniqueServiceInstanceName) {
1292             this.optimisticUniqueServiceInstanceName = optimisticUniqueServiceInstanceName;
1293         }
1294
1295         private UUID uuid = UUID.randomUUID();
1296
1297         @Override
1298         public UUID getUuid() {
1299             return uuid;
1300         }
1301
1302         @Override
1303         public void setUuid(UUID uuid) {
1304             this.uuid = uuid;
1305         }
1306
1307         @Override
1308         public JobStatus getStatus() {
1309             return JobStatus.PENDING;
1310         }
1311
1312         @Override
1313         public void setStatus(JobStatus status) {
1314
1315         }
1316
1317         @Override
1318         public Map<String, Object> getData() {
1319             return null;
1320         }
1321
1322         @Override
1323         public JobSharedData getSharedData() {
1324             return new JobSharedData(uuid, "", null,"");
1325         }
1326
1327         @Override
1328         public void setTypeAndData(JobType jobType, Map<String, Object> commandData) {
1329
1330         }
1331
1332         @Override
1333         public UUID getTemplateId() {
1334             return null;
1335         }
1336
1337         @Override
1338         public void setTemplateId(UUID templateId) {
1339
1340         }
1341
1342         @Override
1343         public Integer getIndexInBulk() {
1344             return null;
1345         }
1346
1347         @Override
1348         public void setIndexInBulk(Integer indexInBulk) {
1349
1350         }
1351
1352         @Override
1353         public JobType getType() {
1354             return null;
1355         }
1356
1357         public String getOptimisticUniqueServiceInstanceName() {
1358             return optimisticUniqueServiceInstanceName;
1359         }
1360     }
1361
1362
1363     @Test
1364     public void testGetVfModuleReplacePath_asMSOexpected()
1365     {
1366         String path = asyncInstantiationBL.getVfModuleReplacePath("myService", "myVNF", "myVFModule");
1367         assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myService/vnfs/myVNF/vfModules/myVFModule/replace"));
1368
1369     }
1370
1371 }