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