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