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