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