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