2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.vid.services;
23 import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
24 import static net.javacrumbs.jsonunit.JsonAssert.whenIgnoringPaths;
25 import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
26 import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
27 import static org.hamcrest.MatcherAssert.assertThat;
28 import static org.hamcrest.Matchers.containsInAnyOrder;
29 import static org.hamcrest.Matchers.containsString;
30 import static org.hamcrest.Matchers.hasItem;
31 import static org.hamcrest.Matchers.hasItems;
32 import static org.hamcrest.Matchers.hasProperty;
33 import static org.hamcrest.Matchers.hasSize;
34 import static org.hamcrest.Matchers.is;
35 import static org.hamcrest.Matchers.matchesPattern;
36 import static org.hamcrest.Matchers.not;
37 import static org.hamcrest.Matchers.nullValue;
38 import static org.hamcrest.core.Every.everyItem;
39 import static org.hamcrest.core.IsEqual.equalTo;
40 import static org.mockito.ArgumentMatchers.any;
41 import static org.mockito.ArgumentMatchers.anyInt;
42 import static org.mockito.ArgumentMatchers.anyString;
43 import static org.mockito.ArgumentMatchers.eq;
44 import static org.mockito.Mockito.doNothing;
45 import static org.mockito.Mockito.doReturn;
46 import static org.mockito.Mockito.doThrow;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.reset;
49 import static org.mockito.Mockito.spy;
50 import static org.mockito.Mockito.times;
51 import static org.mockito.Mockito.verify;
52 import static org.mockito.Mockito.when;
53 import static org.onap.vid.job.Job.JobStatus.COMPLETED;
54 import static org.onap.vid.job.Job.JobStatus.COMPLETED_WITH_ERRORS;
55 import static org.onap.vid.job.Job.JobStatus.COMPLETED_WITH_NO_ACTION;
56 import static org.onap.vid.job.Job.JobStatus.FAILED;
57 import static org.onap.vid.job.Job.JobStatus.IN_PROGRESS;
58 import static org.onap.vid.job.Job.JobStatus.PAUSE;
59 import static org.onap.vid.job.Job.JobStatus.PENDING;
60 import static org.onap.vid.job.Job.JobStatus.STOPPED;
61 import static org.onap.vid.testUtils.TestUtils.generateRandomAlphaNumeric;
62 import static org.testng.Assert.assertEquals;
63 import static org.testng.Assert.assertFalse;
64 import static org.testng.Assert.assertNotNull;
65 import static org.testng.Assert.assertNull;
66 import static org.testng.Assert.assertTrue;
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;
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;
88 import java.util.Optional;
90 import java.util.UUID;
91 import java.util.concurrent.Callable;
92 import java.util.concurrent.ExecutorService;
93 import java.util.concurrent.Executors;
94 import java.util.stream.Collectors;
95 import java.util.stream.IntStream;
96 import org.apache.commons.io.IOUtils;
97 import org.apache.commons.lang3.time.DateUtils;
98 import org.jetbrains.annotations.NotNull;
99 import org.json.JSONException;
100 import org.mockito.ArgumentCaptor;
101 import org.mockito.Mock;
102 import org.mockito.Mockito;
103 import org.mockito.MockitoAnnotations;
104 import org.mockito.stubbing.Answer;
105 import org.onap.portalsdk.core.util.SystemProperties;
106 import org.onap.vid.aai.ExceptionWithRequestInfo;
107 import org.onap.vid.aai.model.ResourceType;
108 import org.onap.vid.changeManagement.RequestDetailsWrapper;
109 import org.onap.vid.config.DataSourceConfig;
110 import org.onap.vid.config.MockedAaiClientAndFeatureManagerConfig;
111 import org.onap.vid.dal.AsyncInstantiationRepository;
112 import org.onap.vid.exceptions.MaxRetriesException;
113 import org.onap.vid.exceptions.NotFoundException;
114 import org.onap.vid.exceptions.OperationNotAllowedException;
115 import org.onap.vid.job.Job;
116 import org.onap.vid.job.Job.JobStatus;
117 import org.onap.vid.job.JobAdapter;
118 import org.onap.vid.job.JobType;
119 import org.onap.vid.job.JobsBrokerService;
120 import org.onap.vid.job.command.MsoRequestBuilder;
121 import org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator;
122 import org.onap.vid.job.impl.JobDaoImpl;
123 import org.onap.vid.job.impl.JobSharedData;
124 import org.onap.vid.model.Action;
125 import org.onap.vid.model.JobAuditStatus;
126 import org.onap.vid.model.NameCounter;
127 import org.onap.vid.model.ResourceInfo;
128 import org.onap.vid.model.ServiceInfo;
129 import org.onap.vid.model.serviceInstantiation.BaseResource;
130 import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
131 import org.onap.vid.model.serviceInstantiation.Vnf;
132 import org.onap.vid.mso.MsoOperationalEnvironmentTest;
133 import org.onap.vid.mso.RestObject;
134 import org.onap.vid.mso.model.ModelInfo;
135 import org.onap.vid.mso.model.ServiceInstantiationRequestDetails;
136 import org.onap.vid.mso.rest.AsyncRequestStatus;
137 import org.onap.vid.mso.rest.RequestStatus;
138 import org.onap.vid.properties.Features;
139 import org.onap.vid.testUtils.TestUtils;
140 import org.onap.vid.utils.DaoUtils;
141 import org.onap.vid.utils.TimeUtils;
142 import org.springframework.test.context.ContextConfiguration;
143 import org.testng.Assert;
144 import org.testng.annotations.AfterMethod;
145 import org.testng.annotations.BeforeClass;
146 import org.testng.annotations.BeforeMethod;
147 import org.testng.annotations.DataProvider;
148 import org.testng.annotations.Test;
150 @ContextConfiguration(classes = {DataSourceConfig.class, SystemProperties.class, MockedAaiClientAndFeatureManagerConfig.class})
151 public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseTest {
156 private JobAdapter jobAdapterMock;
159 private JobsBrokerService jobsBrokerServiceMock;
161 private AsyncInstantiationRepository asyncInstantiationRepository;
163 private AuditService auditService;
166 private AsyncInstantiationBusinessLogicImpl asyncInstantiationBL;
168 protected MsoRequestBuilder msoRequestBuilder;
170 private static final String UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE =
171 "Failed to retrieve class .*ServiceInfo with jobId .* from table. no resource found";
173 private static final String DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE =
174 "Service status does not allow deletion from the queue";
176 private String uuidRegex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
177 private org.hamcrest.Matcher uuidRegexMatcher = is(matchesPattern(uuidRegex));
181 void initServicesInfoService() {
182 MockitoAnnotations.initMocks(this);
183 doReturn(false).when(featureManager).isActive(Features.FLAG_DISABLE_HOMING);
184 AsyncInstantiationRepository realAsyncInstantiationRepository = new AsyncInstantiationRepository(dataAccessService);
185 asyncInstantiationRepository = spy(realAsyncInstantiationRepository);
187 auditService = new AuditServiceImpl(null, asyncInstantiationRepository);
189 AsyncInstantiationBusinessLogicImpl realAsyncInstantiationBL = new AsyncInstantiationBusinessLogicImpl(jobAdapterMock, jobsBrokerServiceMock, sessionFactory, aaiClient, featureManager, cloudOwnerService, asyncInstantiationRepository, auditService);
190 asyncInstantiationBL = Mockito.spy(realAsyncInstantiationBL);
192 msoRequestBuilder = new MsoRequestBuilder(asyncInstantiationBL, cloudOwnerService, aaiClient, featureManager);
194 createInstanceParamsMaps();
199 Mockito.reset(aaiClient);
200 Mockito.reset(jobAdapterMock);
201 Mockito.reset(jobsBrokerServiceMock);
202 Mockito.reset(asyncInstantiationRepository);
203 mockAaiClientAnyNameFree();
204 enableAddCloudOwnerOnMsoRequest();
208 void resetServiceCount() {
214 dataAccessService.deleteDomainObjects(JobDaoImpl.class, "1=1", getPropsMap());
215 dataAccessService.deleteDomainObjects(ServiceInfo.class, "1=1", getPropsMap());
216 dataAccessService.deleteDomainObjects(JobAuditStatus.class, "1=1", getPropsMap());
217 dataAccessService.deleteDomainObjects(NameCounter.class, "1=1", getPropsMap());
221 private void createNewTestServicesInfoForFilter(String userId) {
222 LocalDateTime createdDate, modifiedDate;
223 LocalDateTime NOW = LocalDateTime.now();
227 uuid = UUID.randomUUID();
229 createdDate = NOW.minusYears(1);
230 addNewServiceInfo(uuid, userId, "Old", createdDate, createdDate, COMPLETED, false, false,
233 uuid = UUID.randomUUID();
235 createdDate = NOW.minusDays(20);
236 modifiedDate = NOW.minusDays(19);
237 addNewServiceInfo(uuid, userId, "Hidden", createdDate, modifiedDate, PAUSE, true, false,
240 createNewTestServicesInfo(String.valueOf(userId));
243 private void createNewTestServicesInfo(String userId) {
245 LocalDateTime createdDate, modifiedDate;
246 LocalDateTime NOW = LocalDateTime.now();
249 uuid = UUID.randomUUID();
252 createdDate = NOW.minusDays(40);
253 addNewServiceInfo(uuid, userId, "service instance 5", createdDate, createdDate, COMPLETED, false, false,
255 addNewServiceInfo(uuid, userId, "service instance 6", createdDate, createdDate, STOPPED, false, false,
258 uuid = UUID.randomUUID();
261 createdDate = NOW.minusDays(20);
262 modifiedDate = NOW.minusDays(10);
263 addNewServiceInfo(uuid, userId, "service instance 4", createdDate, modifiedDate, STOPPED, false, false,
265 addNewServiceInfo(uuid, userId, "service instance 2", createdDate, modifiedDate, COMPLETED, false, false,
267 addNewServiceInfo(uuid, userId, "service instance 3", createdDate, modifiedDate, PAUSE, false, false,
270 modifiedDate = NOW.minusDays(19);
271 addNewServiceInfo(uuid, userId, "service instance 1", createdDate, modifiedDate, FAILED, false, false,
275 // Job to a different user
276 uuid = UUID.randomUUID();
279 createdDate = NOW.minusMonths(2);
280 addNewServiceInfo(uuid, "2221", "service instance 7", createdDate, createdDate, COMPLETED, false, false,
287 private UUID createServicesInfoWithDefaultValues(Job.JobStatus status) {
289 LocalDateTime NOW = LocalDateTime.now();
292 uuid = UUID.randomUUID();
293 addNewJob(uuid, status);
295 addNewServiceInfo(uuid, null, "service instance 1", NOW, NOW, status, false, false,
302 private List<ServiceInfo> getFullList() {
303 List<ServiceInfo> expectedOrderServiceInfo = dataAccessService.getList(ServiceInfo.class, getPropsMap());
304 assertThat("Failed to retrieve all predefined services", expectedOrderServiceInfo.size(), equalTo(serviceCount));
305 expectedOrderServiceInfo.sort(new ServiceInfoComparator());
306 return expectedOrderServiceInfo;
311 private LocalDateTime fromDate(Date date) {
312 return Instant.ofEpochMilli(date.getTime())
313 .atZone(ZoneId.systemDefault())
317 private void setCreateDateToServiceInfo(UUID jobUuid, LocalDateTime createDate) {
318 List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, getPropsMap());
319 DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
320 serviceInfoList.stream()
321 .filter(serviceInfo -> jobUuid.equals(serviceInfo.getJobId()))
322 .forEach(serviceInfo -> {
323 serviceInfo.setCreated(toDate(createDate));
324 session.saveOrUpdate(serviceInfo);
330 private void addNewJob(UUID uuid) {
331 addNewJob(uuid, null);
334 private void addNewJob(UUID uuid, Job.JobStatus status) {
335 JobDaoImpl jobDao = new JobDaoImpl();
336 jobDao.setUuid(uuid);
337 jobDao.setStatus(status);
338 dataAccessService.saveDomainObject(jobDao, getPropsMap());
341 private ServiceInstantiation addOriginalService(UUID jobId, String userID){
342 addNewServiceInfo(jobId, userID, "name", LocalDateTime.now(), LocalDateTime.now(), COMPLETED_WITH_ERRORS, false,
345 assertThat(asyncInstantiationRepository.getServiceInfoByJobId(jobId).isRetryEnabled(), is(true));
346 ServiceInstantiation originalServiceInstantiation = prepareServiceInstantiation(true, 1);
347 doReturn(originalServiceInstantiation).when(asyncInstantiationRepository).getJobRequest(jobId);
348 return originalServiceInstantiation;
351 private void assertRetryDisabled(UUID jobId){
352 assertThat(asyncInstantiationRepository.getServiceInfoByJobId(jobId).isRetryEnabled(), is(false));
355 private void assertNewJobExistsAsExpectedAfterRetry(List<UUID> newJobIds, ServiceInstantiation expectedServiceInstantiation, UUID jobId, String userId){
356 assertThat(newJobIds, hasSize(1));
357 assertThat(newJobIds.get(0), not(equalTo(jobId)));
359 ArgumentCaptor<ServiceInstantiation> requestsCaptor = ArgumentCaptor.forClass(ServiceInstantiation.class);
360 ArgumentCaptor<UUID> uuidsCaptor = ArgumentCaptor.forClass(UUID.class);
361 ArgumentCaptor<JobType> jobTypeCaptor = ArgumentCaptor.forClass(JobType.class);
363 verify(asyncInstantiationRepository).addJobRequest(uuidsCaptor.capture(), requestsCaptor.capture());
364 verify(jobAdapterMock).createServiceInstantiationJob(jobTypeCaptor.capture(), requestsCaptor.capture(), uuidsCaptor.capture(), eq(userId), any(), anyString(), anyInt());
365 verify(jobsBrokerServiceMock).add(any());
367 requestsCaptor.getAllValues().forEach(x->assertJsonEquals(expectedServiceInstantiation, x, whenIgnoringPaths(
369 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.trackById",
370 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:001.trackById",
371 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:002.trackById"
377 public void testServiceInfoAreOrderedAsExpected() {
379 createNewTestServicesInfo(String.valueOf(userId));
380 List<ServiceInfo> expectedOrderServiceInfo = getFullList();
381 List<ServiceInfo> serviceInfoListResult = asyncInstantiationBL.getAllServicesInfo();
382 assertThat("Services aren't ordered as expected", serviceInfoListResult, equalTo(expectedOrderServiceInfo));
386 public void whenNewServiceInfoCreated_isRetryEnablesIsFalse() {
387 UUID uuid = createServicesInfoWithDefaultValues(PENDING);
388 assertFalse(asyncInstantiationRepository.getServiceInfoByJobId(uuid).isRetryEnabled());
392 public void testServiceInfoAreFilteredAsExpected() {
394 createNewTestServicesInfoForFilter(String.valueOf(userId));
395 List<ServiceInfo> expectedOrderServiceInfo = getFullList();
397 List<ServiceInfo> expectedFilterByUser = expectedOrderServiceInfo.stream().filter(x ->
398 !x.getServiceInstanceName().equals("Old") && !x.getServiceInstanceName().equals("Hidden")
400 ).collect(Collectors.toList());
403 List<ServiceInfo> serviceInfoFilteredByUser = asyncInstantiationBL.getAllServicesInfo();
404 assertThat("Services aren't ordered filtered as expected", serviceInfoFilteredByUser, equalTo(expectedFilterByUser));
407 @Test(dataProvider = "pauseAndInstanceParams")
408 public void createMacroServiceInstantiationMsoRequestUniqueName(Boolean isPause, HashMap<String, String> vfModuleInstanceParamsMap, List vnfInstanceParams) throws Exception {
410 ServiceInstantiation serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(isPause, createVnfList(vfModuleInstanceParamsMap, vnfInstanceParams, true), 2, true, PROJECT_NAME, false);
411 final URL resource = this.getClass().getResource("/payload_jsons/bulk_service_request_unique_names.json");
412 when(jobAdapterMock.createServiceInstantiationJob(any(), any(), any(), any(), any(), anyString(), any())).thenAnswer(invocation -> {
413 Object[] args = invocation.getArguments();
414 return new MockedJob((String)args[5]);
417 when(jobsBrokerServiceMock.add(any(MockedJob.class))).thenAnswer((Answer<UUID>) invocation -> {
418 Object[] args = invocation.getArguments();
419 MockedJob job = (MockedJob) args[0];
420 MockedJob.putJob(job.uuid, job);
421 return job.getUuid();
424 when(asyncInstantiationBL.isPartOfBulk(any())).thenReturn(true);
426 List<UUID> uuids = asyncInstantiationBL.pushBulkJob(serviceInstantiationPayload, "az2016");
427 for (int i = 0; i < 2; i++) {
428 UUID currentUuid = uuids.get(i);
429 RequestDetailsWrapper<ServiceInstantiationRequestDetails> result =
430 msoRequestBuilder.generateMacroServiceInstantiationRequest(currentUuid, serviceInstantiationPayload,
431 MockedJob.getJob(currentUuid).getOptimisticUniqueServiceInstanceName(), "az2016");
432 String unique = i==0 ? "" : String.format("_00%s", i);
433 String expected = IOUtils.toString(resource, "UTF-8")
434 .replace("{SERVICE_UNIQENESS}", unique)
435 .replace("{VNF_UNIQENESS}", unique)
436 .replace("{VF_MODULE_UNIQENESS}", unique)
437 .replace("{VF_MODULE_2_UNIQENESS}", unique)
438 .replace("{VG_UNIQUENESS}", unique);
439 MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
440 Optional<ServiceInfo> optionalServiceInfo = getJobById(currentUuid);
441 assertThat(optionalServiceInfo.get().getServiceInstanceName(), equalTo("vPE_Service" + unique));
442 verifySearchNodeTypeByName(unique, "vPE_Service", ResourceType.SERVICE_INSTANCE);
443 verifySearchNodeTypeByName(unique, VNF_NAME, ResourceType.GENERIC_VNF);
444 verifySearchNodeTypeByName(unique, "vmxnjr001_AVPN_base_vPE_BV_base", ResourceType.VF_MODULE);
445 verifySearchNodeTypeByName(unique, "vmxnjr001_AVPN_base_vRE_BV_expansion", ResourceType.VF_MODULE);
446 verifySearchNodeTypeByName(unique, "myVgName", ResourceType.VOLUME_GROUP);
450 protected void verifySearchNodeTypeByName(String unique, String resourceName, ResourceType serviceInstance) {
451 String uniqueName = resourceName + unique;
452 verify(aaiClient, times(1)).isNodeTypeExistsByName(uniqueName, serviceInstance);
453 when(aaiClient.isNodeTypeExistsByName(uniqueName, serviceInstance)).thenReturn(true);
460 public static Object[][] dataProviderForInstanceNames() {
461 return new Object[][]{
462 {true, ImmutableList.of("vPE_Service", "vPE_Service_001", "vPE_Service_002")},
463 {false, ImmutableList.of("", "", "")},
467 @Test(dataProvider="dataProviderForInstanceNames")
468 public void pushBulkJob_bulkWithSize3_instancesNamesAreExactlyAsExpected(boolean isUserProvidedNaming, List<String> expectedNames) {
469 final ServiceInstantiation request = prepareServiceInstantiation(isUserProvidedNaming, 3);
472 asyncInstantiationBL.pushBulkJob(request, "myUserId");
474 List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, getPropsMap());
475 assertEquals(serviceInfoList.stream().map(ServiceInfo::getServiceInstanceName).collect(Collectors.toList()), expectedNames);
478 protected ServiceInstantiation prepareServiceInstantiation(String projectName, boolean isUserProvidedNaming, int bulkSize) {
479 final ServiceInstantiation request = generateMockMacroServiceInstantiationPayload(
481 createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true),
482 bulkSize, isUserProvidedNaming, projectName, true
485 // in "createServiceInstantiationJob()" we will probe the service, with the generated names
486 configureMockitoWithMockedJob();
490 protected ServiceInstantiation prepareServiceInstantiation(boolean isUserProvidedNaming, int bulkSize) {
491 return prepareServiceInstantiation(PROJECT_NAME, isUserProvidedNaming, bulkSize);
495 public void getSummarizedMap(){
496 ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject(
497 "/payload_jsons/templateSummarize4vnfs6vfmodules.json", ServiceInstantiation.class);
498 Map<String, Long> childrenMap = asyncInstantiationBL.getSummarizedChildrenMap(serviceInstantiation);
499 HashMap<String, Long> expectedMap = new HashMap<>();
500 expectedMap.put("vnf", Long.valueOf(4));
501 expectedMap.put("vfModule", Long.valueOf(6));
502 assertEquals(childrenMap,expectedMap);
508 public void whenPushBulkJob_thenJobRequestIsSaveInJobRequestDb() {
509 Mockito.reset(asyncInstantiationRepository);
511 final ServiceInstantiation request = prepareServiceInstantiation(true, bulkSize);
512 when(jobsBrokerServiceMock.add(any())).thenReturn(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID());
513 List<UUID> jobIds = asyncInstantiationBL.pushBulkJob(request, "abc");
515 ArgumentCaptor<JobAdapter.AsyncJobRequest> asyncJobRequestCaptor = ArgumentCaptor.forClass(JobAdapter.AsyncJobRequest.class);
516 ArgumentCaptor<ServiceInstantiation> requestsCaptor = ArgumentCaptor.forClass(ServiceInstantiation.class);
517 ArgumentCaptor<UUID> uuidsCaptor = ArgumentCaptor.forClass(UUID.class);
518 verify(asyncInstantiationRepository, times(bulkSize)).addJobRequest(uuidsCaptor.capture(), requestsCaptor.capture());
519 verify(jobsBrokerServiceMock, times(bulkSize)).add(any());
520 verify(jobAdapterMock, times(bulkSize)).createServiceInstantiationJob(any(), asyncJobRequestCaptor.capture(), any(), any(), any(), any(), any());
522 //verify that all for each job we saved an row in jobRequest table
523 assertThat(uuidsCaptor.getAllValues(), containsInAnyOrder(jobIds.toArray()));
525 //assert that each real job we created with the adaptor, request is save in jobRequest table
526 assertThat(requestsCaptor.getAllValues(), containsInAnyOrder(asyncJobRequestCaptor.getAllValues().toArray()));
528 assertThat(requestsCaptor.getAllValues(),everyItem(hasProperty("bulkSize", is(1))));
530 //assert that the requests that save in DB are the same as original request expect of the trackById
531 requestsCaptor.getAllValues().forEach(x->assertJsonEquals(request, x, whenIgnoringPaths(
534 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.trackById",
535 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:001.trackById",
536 "vnfs.2016-73_MOW-AVPN-vPE-BV-L.vfModules.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0.201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0:002.trackById"
539 //assert that each trackById on all bulk jobs is unique
540 Set<String> usedUUID = new HashSet<>();
541 requestsCaptor.getAllValues().forEach(x->assertTrackByIdRecursively(x, uuidRegexMatcher, usedUUID));
545 public void whenRetryJob_prevJobRetryIsDisabled() {
546 reset(asyncInstantiationRepository);
547 UUID jobId = UUID.randomUUID();
548 String userID = generateRandomAlphaNumeric(8);
549 addOriginalService(jobId, userID);
550 doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
551 asyncInstantiationBL.retryJob(jobId, userID);
552 assertRetryDisabled(jobId);
556 public void whenRetryJobWithEditedData_prevJobRetryIsDisabled() {
557 reset(asyncInstantiationRepository);
558 UUID jobId = UUID.randomUUID();
559 String userID = generateRandomAlphaNumeric(8);
560 addOriginalService(jobId, userID);
561 ServiceInstantiation editedServiceInstantiation = prepareServiceInstantiation("editedProjectName", true, 1);
562 asyncInstantiationBL.retryJob(editedServiceInstantiation, jobId, userID);
563 assertRetryDisabled(jobId);
567 public void retryJobWithEditedData_expectedNewJobDifferentData() {
568 reset(asyncInstantiationRepository);
569 UUID jobId = UUID.randomUUID();
570 String userID = generateRandomAlphaNumeric(8);
571 addOriginalService(jobId, userID);
572 ServiceInstantiation editedServiceInstantiation = prepareServiceInstantiation("editedProjectName", true, 1);
573 List<UUID> newJobIds = asyncInstantiationBL.retryJob(editedServiceInstantiation, jobId, userID);
574 assertNewJobExistsAsExpectedAfterRetry(newJobIds, editedServiceInstantiation, jobId, userID);
578 public void retryJob_expectedNewJob() {
579 reset(asyncInstantiationRepository);
580 UUID jobId = UUID.randomUUID();
581 String userID = "az2016";
582 ServiceInstantiation originalServiceInstantiation = addOriginalService(jobId, userID);
583 doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
584 List<UUID> newJobIds = asyncInstantiationBL.retryJob(jobId, userID);
585 assertNewJobExistsAsExpectedAfterRetry(newJobIds, originalServiceInstantiation, jobId, userID);
588 @Test (dataProvider = "aLaCarteAndMacroPayload")
589 public void generateMockServiceInstantiationPayload_serializeBackAndForth_sourceShouldBeTheSame(ServiceInstantiation serviceInstantiationPayload) throws IOException {
590 ObjectMapper mapper = new ObjectMapper();
591 final String asString = mapper.writeValueAsString(serviceInstantiationPayload);
593 final ServiceInstantiation asObject = mapper.readValue(asString, ServiceInstantiation.class);
594 final String asString2 = mapper.writeValueAsString(asObject);
596 assertJsonEquals(asString, asString2);
600 public Object[][] aLaCarteAndMacroPayload() {
601 ServiceInstantiation macroPayload = generateMockMacroServiceInstantiationPayload(
603 createVnfList(instanceParamsMapWithoutParams, ImmutableList.of(vnfInstanceParamsMapWithParamsToRemove, vnfInstanceParamsMapWithParamsToRemove), true),
604 2, false,PROJECT_NAME, false);
605 ServiceInstantiation aLaCartePayload = generateALaCarteServiceInstantiationPayload();
607 return new Object[][]{
613 public static class ServiceInfoComparator implements Comparator<ServiceInfo> {
616 public int compare(ServiceInfo o1, ServiceInfo o2) {
619 compare = o1.getCreatedBulkDate().compareTo(o2.getCreatedBulkDate());
624 // check jobStatus priority
625 int o1Priority = getPriority(o1);
626 int o2Priority = getPriority(o2);
627 compare = o1Priority - o2Priority;
632 // check statusModifiedDate
633 return o1.getStatusModifiedDate().compareTo(o2.getStatusModifiedDate());
636 private int getPriority(ServiceInfo o) throws JSONException {
637 Job.JobStatus status = o.getJobStatus();
656 public Object[][] pauseAndInstanceParams() {
657 return new Object[][]{
658 {Boolean.TRUE, instanceParamsMapWithoutParams, Collections.EMPTY_LIST},
659 {Boolean.FALSE, instanceParamsMapWithoutParams, Collections.EMPTY_LIST},
660 {Boolean.TRUE, vfModuleInstanceParamsMapWithParamsToRemove, Collections.singletonList(vnfInstanceParamsMapWithParamsToRemove)}
665 public void testUpdateServiceInfo_WithExistingServiceInfo_ServiceInfoIsUpdated() {
666 UUID uuid = createFakedJobAndServiceInfo();
667 final String STEPH_CURRY = "Steph Curry";
668 asyncInstantiationBL.updateServiceInfo(uuid, x -> {
669 x.setServiceInstanceName(STEPH_CURRY);
670 x.setJobStatus(Job.JobStatus.IN_PROGRESS);
672 Optional<ServiceInfo> optionalServiceInfo = getJobById(uuid);
673 assertThat(optionalServiceInfo.get().getServiceInstanceName(), equalTo(STEPH_CURRY));
674 assertThat(optionalServiceInfo.get().getJobStatus(), equalTo(Job.JobStatus.IN_PROGRESS));
677 private Optional<ServiceInfo> getJobById(UUID jobId) {
678 List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, null);
679 return serviceInfoList.stream().filter(x -> jobId.equals(x.getJobId())).findFirst();
682 private UUID createFakedJobAndServiceInfo() {
683 UUID uuid = UUID.randomUUID();
685 ServiceInfo serviceInfo = new ServiceInfo();
686 serviceInfo.setServiceInstanceName("Lebron James");
687 serviceInfo.setJobId(uuid);
688 serviceInfo.setJobStatus(Job.JobStatus.PENDING);
689 dataAccessService.saveDomainObject(serviceInfo, getPropsMap());
693 @Test(expectedExceptions = NotFoundException.class, expectedExceptionsMessageRegExp = UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE)
694 public void testUpdateServiceInfo_WithNonExisting_ThrowException() {
695 asyncInstantiationBL.updateServiceInfo(UUID.randomUUID(), x -> x.setServiceInstanceName("not matter"));
698 @Test(expectedExceptions = NotFoundException.class, expectedExceptionsMessageRegExp = UPDATE_SERVICE_INFO_EXCEPTION_MESSAGE)
699 public void testUpdateServiceInfo_WithDoubleServiceWithSameJobUuid_ThrowException() {
700 UUID uuid = createFakedJobAndServiceInfo();
701 ServiceInfo serviceInfo = new ServiceInfo();
702 serviceInfo.setJobId(uuid);
703 dataAccessService.saveDomainObject(serviceInfo, getPropsMap());
704 asyncInstantiationBL.updateServiceInfo(UUID.randomUUID(), x -> x.setServiceInstanceName("not matter"));
709 public static Object[][] isPauseAndPropertyDataProvider() {
710 return new Object[][]{
711 {true, "mso.restapi.serviceInstanceAssign"},
712 {false, "mso.restapi.service.instance"},
717 @Test(dataProvider = "isPauseAndPropertyDataProvider")
718 public void testServiceInstantiationPath_RequestPathIsAsExpected(boolean isPause, String expectedProperty) {
719 ServiceInstantiation serviceInstantiationPauseFlagTrue = generateMacroMockServiceInstantiationPayload(isPause, createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true));
720 String path = asyncInstantiationBL.getServiceInstantiationPath(serviceInstantiationPauseFlagTrue);
721 Assert.assertEquals(path, SystemProperties.getProperty(expectedProperty));
725 public void testCreateVnfEndpoint_useProvidedInstanceId() {
726 String path = asyncInstantiationBL.getVnfInstantiationPath("myGreatId");
727 assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myGreatId/vnfs"));
733 public void pushBulkJob_macroServiceverifyCreatedDateBehavior_createdDateIsTheSameForAllServicesInSameBulk() {
734 LocalDateTime startTestDate = LocalDateTime.now().withNano(0);
735 final ServiceInstantiation request = generateMockMacroServiceInstantiationPayload(
737 createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true),
738 100, true,PROJECT_NAME, true
741 pushJobAndAssertDates(startTestDate, request);
745 public void whenCreateServiceInfo_thenModelId_isModelVersionId() {
746 ServiceInfo serviceInfo = asyncInstantiationBL.createServiceInfo("userID",
747 generateALaCarteWithVnfsServiceInstantiationPayload(),
751 "myName", ServiceInfo.ServiceAction.INSTANTIATE);
752 assertEquals(SERVICE_MODEL_VERSION_ID, serviceInfo.getServiceModelId());
757 public void pushBulkJob_aLaCarteServiceverifyCreatedDateBehavior_createdDateIsTheSameForAllServicesInSameBulk() {
758 LocalDateTime startTestDate = LocalDateTime.now().withNano(0);
759 final ServiceInstantiation request = generateALaCarteServiceInstantiationPayload();
760 pushJobAndAssertDates(startTestDate, request);
763 protected void pushJobAndAssertDates(LocalDateTime startTestDate, ServiceInstantiation request) {
764 // in "createServiceInstantiationJob()" we will probe the service, with the generated names
765 configureMockitoWithMockedJob();
767 asyncInstantiationBL.pushBulkJob(request, "myUserId");
768 List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, getPropsMap());
770 List<Date> creationDates = new ArrayList<>();
771 for (ServiceInfo serviceInfo : serviceInfoList) {
772 creationDates.add(serviceInfo.getCreatedBulkDate());
774 LocalDateTime endTestDate = LocalDateTime.now();
776 //creation date of all services is the same
777 Assert.assertTrue(creationDates.stream().distinct().count() <= 1);
778 LocalDateTime creationDate = fromDate(creationDates.get(0));
779 assertFalse(creationDate.isBefore(startTestDate));
780 assertFalse(creationDate.isAfter(endTestDate));
783 protected void configureMockitoWithMockedJob() {
784 Mockito.reset(jobAdapterMock);
785 final Job job = mock(Job.class);
786 when(job.getStatus()).thenReturn(PENDING);
787 when(job.getUuid()).thenReturn(UUID.fromString("db2c5ed9-1c19-41ce-9cb7-edf0d878cdeb"));
788 when(jobAdapterMock.createServiceInstantiationJob(any(), any(), any(), any(), any(), any(), any())).thenReturn(job);
789 when(jobsBrokerServiceMock.add(job)).thenReturn(UUID.randomUUID());
793 public static Object[][] msoToJobStatusDataProvider() {
794 return new Object[][]{
795 {"IN_PROGRESS", JobStatus.IN_PROGRESS},
796 {"INPROGRESS", JobStatus.IN_PROGRESS},
797 {"IN ProGREsS", JobStatus.IN_PROGRESS},
798 {"JAMES_HARDEN", JobStatus.IN_PROGRESS},
799 {"FAILED", JobStatus.FAILED},
800 {"COMpleTE", JobStatus.COMPLETED},
801 {"PENDING", JobStatus.IN_PROGRESS},
802 {"Paused", JobStatus.PAUSE},
803 {"Pause", JobStatus.PAUSE},
804 {"PENDING_MANUAL_TASK", JobStatus.PAUSE},
805 {"UNLOCKED", JobStatus.IN_PROGRESS},
806 {"AbORtEd", COMPLETED_WITH_ERRORS},
807 {"RoLlED_baCK", FAILED},
808 {"ROllED_BAcK_To_ASsIGnED", FAILED},
809 {"rOLLED_bACK_tO_CrEATeD", FAILED},
813 @Test(dataProvider = "msoToJobStatusDataProvider")
814 public void whenGetStatusFromMso_calcRightJobStatus(String msoStatus, Job.JobStatus expectedJobStatus) {
815 AsyncRequestStatus asyncRequestStatus = asyncRequestStatusResponse(msoStatus);
816 assertThat(asyncInstantiationBL.calcStatus(asyncRequestStatus), equalTo(expectedJobStatus));
820 public static Object[][] msoRequestStatusFiles(Method test) {
821 return new Object[][]{
822 {"/responses/mso/orchestrationRequestsServiceInstance.json"},
823 {"/responses/mso/orchestrationRequestsVnf.json"},
824 {"/responses/mso/orchestrationRequestsMockedMinimalResponse.json"}
828 @Test(dataProvider="msoRequestStatusFiles")
829 public void verifyAsyncRequestStatus_canBeReadFromSample(String msoResponseFile) throws IOException {
830 AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
832 AsyncRequestStatus.class);
833 assertThat(asyncRequestStatus.request.requestStatus.getRequestState(), equalTo("COMPLETE"));
837 public void deleteJobInfo_pending_deleted() {
838 doNothing().when(jobsBrokerServiceMock).delete(any());
839 UUID uuid = createServicesInfoWithDefaultValues(PENDING);
840 asyncInstantiationBL.deleteJob(uuid);
841 assertNotNull(asyncInstantiationRepository.getServiceInfoByJobId(uuid).getDeletedAt(), "service info wasn't deleted");
844 @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE)
845 public void deleteJobInfo_notAllowdStatus_shouldSendError() {
846 UUID uuid = createServicesInfoWithDefaultValues(COMPLETED);
847 doThrow(new IllegalStateException(DELETE_SERVICE_INFO_STATUS_EXCEPTION_MESSAGE)).when(jobsBrokerServiceMock).delete(any());
849 asyncInstantiationBL.deleteJob(uuid);
850 } catch (Exception e) {
851 assertNull(asyncInstantiationRepository.getServiceInfoByJobId(uuid).getDeletedAt(), "service info shouldn't deleted");
857 public Object[][] jobStatusesFinal() {
858 return Arrays.stream(Job.JobStatus.values())
859 .filter(t -> ImmutableList.of(COMPLETED, FAILED, STOPPED).contains(t))
860 .map(v -> new Object[]{v}).collect(Collectors.toList()).toArray(new Object[][]{});
863 @Test(dataProvider = "jobStatusesFinal")
864 public void whenHideService_theServiceNotReturnedInServiceList(JobStatus jobStatus) {
865 UUID uuidToHide = createServicesInfoWithDefaultValues(jobStatus);
866 UUID uuidToShown = createServicesInfoWithDefaultValues(jobStatus);
867 List<UUID> serviceInfoList = listServicesUUID();
868 assertThat(serviceInfoList, hasItems(uuidToHide, uuidToShown));
870 asyncInstantiationBL.hideServiceInfo(uuidToHide);
871 serviceInfoList = listServicesUUID();
872 assertThat(serviceInfoList, hasItem(uuidToShown));
873 assertThat(serviceInfoList, not(hasItem(uuidToHide)));
877 protected List<UUID> listServicesUUID() {
878 return asyncInstantiationBL.getAllServicesInfo().stream().map(ServiceInfo::getJobId).collect(Collectors.toList());
882 public Object[][] jobStatusesNotFinal() {
883 return Arrays.stream(Job.JobStatus.values())
884 .filter(t -> ImmutableList.of(PENDING, IN_PROGRESS, PAUSE).contains(t))
885 .map(v -> new Object[]{v}).collect(Collectors.toList()).toArray(new Object[][]{});
888 @Test(dataProvider = "jobStatusesNotFinal",
889 expectedExceptions = OperationNotAllowedException.class,
890 expectedExceptionsMessageRegExp = "jobId.*Service status does not allow hide service, status = .*")
891 public void hideServiceInfo_notAllowedStatus_shouldSendError(JobStatus jobStatus) {
892 UUID uuid = createServicesInfoWithDefaultValues(jobStatus);
894 asyncInstantiationBL.hideServiceInfo(uuid);
895 } catch (Exception e) {
896 assertFalse(asyncInstantiationRepository.getServiceInfoByJobId(uuid).isHidden(), "service info shouldn't be hidden");
902 public void whenUseGetCounterInMultiThreads_EachThreadGetDifferentCounter() throws InterruptedException {
904 ExecutorService executor = Executors.newFixedThreadPool(SIZE);
905 List<Callable<Integer>> tasks = IntStream.rangeClosed(0, SIZE)
906 .mapToObj(x-> ((Callable<Integer>)() -> asyncInstantiationBL.getCounterForName("a")))
907 .collect(Collectors.toList());
908 Set<Integer> expectedResults = IntStream.rangeClosed(0, SIZE).boxed().collect(Collectors.toSet());
909 executor.invokeAll(tasks)
912 assertTrue( expectedResults.remove(future.get()), "got unexpected counter");
914 catch (Exception e) {
915 throw new RuntimeException(e);
919 assertThat(expectedResults.size(), is(0));
923 public void whenUseGetCounterForSameName_numbersReturnedByOrder() {
925 String name = UUID.randomUUID().toString();
927 for (int i=0; i<SIZE; i++) {
928 assertThat(asyncInstantiationBL.getCounterForName(name), is(i));
933 public void whenNamedInUsedInAai_getNextNumber() {
934 String name = someCommonStepsAndGetName();
935 ResourceType type = ResourceType.GENERIC_VNF;
936 when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(true);
937 when(aaiClient.isNodeTypeExistsByName(name+"_001", type)).thenReturn(false);
938 assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name+"_001"));
941 @Test(enabled = false) //skip till we will handle macro bulk again...
942 public void whenNamedNotInUsedInAai_getSameNameTwice() {
943 String name = someCommonStepsAndGetName();
944 ResourceType type = ResourceType.GENERIC_VNF;
945 when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(false);
946 assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name));
947 assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name));
948 when(aaiClient.isNodeTypeExistsByName(name, type)).thenReturn(true);
949 assertThat(asyncInstantiationBL.getUniqueName(name, type), equalTo(name+"_001"));
952 private String someCommonStepsAndGetName() {
953 mockAaiClientAaiStatusOK();
954 return UUID.randomUUID().toString();
957 @Test(expectedExceptions= ExceptionWithRequestInfo.class)
958 public void whenAaiBadResponseCode_throwInvalidAAIResponseException() {
959 String name = someCommonStepsAndGetName();
960 ResourceType type = ResourceType.SERVICE_INSTANCE;
961 when(aaiClient.isNodeTypeExistsByName(name, type)).thenThrow(aaiNodeQueryBadResponseException());
962 asyncInstantiationBL.getUniqueName(name, type);
965 @Test(expectedExceptions=MaxRetriesException.class)
966 public void whenAaiAlwaysReturnNameUsed_throwInvalidAAIResponseException() {
967 String name = someCommonStepsAndGetName();
968 ResourceType type = ResourceType.VF_MODULE;
969 when(aaiClient.isNodeTypeExistsByName(any(), eq(type))).thenReturn(true);
970 asyncInstantiationBL.setMaxRetriesGettingFreeNameFromAai(10);
971 asyncInstantiationBL.getUniqueName(name, type);
975 public void testFormattingOfNameAndCounter() {
976 AsyncInstantiationBusinessLogicImpl bl = (AsyncInstantiationBusinessLogicImpl) asyncInstantiationBL;
977 assertThat(bl.formatNameAndCounter("x", 0), equalTo("x"));
978 assertThat(bl.formatNameAndCounter("x", 3), equalTo("x_003"));
979 assertThat(bl.formatNameAndCounter("x", 99), equalTo("x_099"));
980 assertThat(bl.formatNameAndCounter("x", 100), equalTo("x_100"));
981 assertThat(bl.formatNameAndCounter("x", 1234), equalTo("x_1234"));
985 public void pushBulkJob_verifyAlacarteFlow_useALaCartServiceInstantiationJobType(){
986 final ServiceInstantiation request = generateALaCarteServiceInstantiationPayload();
988 // in "createServiceInstantiationJob()" we will probe the service, with the generated names
989 configureMockitoWithMockedJob();
991 ArgumentCaptor<JobType> argumentCaptor = ArgumentCaptor.forClass(JobType.class);
992 asyncInstantiationBL.pushBulkJob(request, "myUserId");
993 verify(jobAdapterMock).createServiceInstantiationJob(argumentCaptor.capture(),any(),any(),anyString(), anyString(), anyString(), anyInt());
994 assertTrue(argumentCaptor.getValue().equals(JobType.ALaCarteServiceInstantiation));
998 public void pushBulkJob_verifyMacroFlow_useMacroServiceInstantiationJobType(){
999 final ServiceInstantiation request = generateMacroMockServiceInstantiationPayload(false, Collections.emptyMap());
1001 // in "createServiceInstantiationJob()" we will probe the service, with the generated names
1002 configureMockitoWithMockedJob();
1004 ArgumentCaptor<JobType> argumentCaptor = ArgumentCaptor.forClass(JobType.class);
1005 asyncInstantiationBL.pushBulkJob(request, "myUserId");
1006 verify(jobAdapterMock).createServiceInstantiationJob(argumentCaptor.capture(),any(),any(),anyString(), any(), anyString(), anyInt());
1007 assertTrue(argumentCaptor.getValue().equals(JobType.MacroServiceInstantiation));
1013 public void getALaCarteServiceDeletionPath_verifyPathIsAsExpected() {
1015 String expected = "/serviceInstantiation/v7/serviceInstances/f36f5734-e9df-4fbf-9f35-61be13f028a1";
1017 String result = asyncInstantiationBL.getServiceDeletionPath("f36f5734-e9df-4fbf-9f35-61be13f028a1");
1019 assertThat(expected,equalTo(result));
1023 public void getResumeRequestPath_verifyPathIsAsExpected() {
1025 String expected = "/orchestrationRequests/v7/rq1234d1-5a33-55df-13ab-12abad84e333/resume";
1027 String result = asyncInstantiationBL.getResumeRequestPath("rq1234d1-5a33-55df-13ab-12abad84e333");
1029 assertThat(expected, equalTo(result));
1033 public void getInstanceGroupsDeletionPath_verifyPathIsAsExpected() {
1034 assertEquals(asyncInstantiationBL.getInstanceGroupDeletePath("9aada4af-0f9b-424f-ae21-e693bd3e005b"),
1035 "/serviceInstantiation/v7/instanceGroups/9aada4af-0f9b-424f-ae21-e693bd3e005b");
1039 public void whenLcpRegionNotEmpty_thenCloudRegionIdOfResourceIsLegacy() {
1040 String legacyCloudRegion = "legacyCloudRegion";
1041 Vnf vnf = new Vnf(new ModelInfo(), null, null, Action.Create.name(), null, "anyCloudRegion", legacyCloudRegion,
1042 null, null, null, false, null, null, UUID.randomUUID().toString(), null, null, null);
1043 assertThat(vnf.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
1047 public void whenLcpRegionNotEmpty_thenCloudRegionIdOfServiceIsLegacy() {
1048 String legacyCloudRegion = "legacyCloudRegion";
1049 ServiceInstantiation service = new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
1050 null, null, "anyCloudRegion", legacyCloudRegion, null, null, null, null, null, null, null, null, null,
1051 false, 1,false, false, null, null, Action.Create.name(), UUID.randomUUID().toString(), null, null, null);
1052 assertThat(service.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
1056 public static Object[][] getJobTypeByRequest_verifyResultAsExpectedDataProvider() {
1057 return new Object[][]{
1058 {false, Action.Create, JobType.MacroServiceInstantiation},
1059 {true, Action.Create, JobType.ALaCarteServiceInstantiation},
1060 {true, Action.Delete, JobType.ALaCarteService},
1064 @Test(dataProvider = "getJobTypeByRequest_verifyResultAsExpectedDataProvider")
1065 public void getJobTypeByRequest_verifyResultAsExpected(boolean isALaCarte, Action action, JobType expectedJobType) {
1066 ServiceInstantiation service = createServiceWithIsALaCarteAndAction(isALaCarte, action);
1067 assertThat(asyncInstantiationBL.getJobType(service), equalTo(expectedJobType));
1071 protected ServiceInstantiation createServiceWithIsALaCarteAndAction(boolean isALaCarte, Action action) {
1072 return new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
1073 null, null, null, null, null, null, null, null, null, null, null, null, null,
1074 false, 1, false, isALaCarte, null, null, action.name(),
1075 UUID.randomUUID().toString(), null, null, null);
1079 public static Object[][] isRetryEnabledForStatusDataProvider(Method test) {
1080 return new Object[][]{
1081 {FAILED, true, true},
1082 {COMPLETED_WITH_ERRORS, true, true},
1083 {COMPLETED_WITH_NO_ACTION, true, false},
1084 {COMPLETED, true, false},
1085 {IN_PROGRESS, true, false},
1086 {FAILED, false, false},
1087 {COMPLETED_WITH_ERRORS, false, false},
1088 {COMPLETED, false, false},
1092 @Test(dataProvider = "isRetryEnabledForStatusDataProvider")
1093 public void whenUpdateServiceInfoAndAuditStatus_thenServiceInfoRowIsUpdatedAndIsRetryIsRight(
1094 JobStatus jobStatus, boolean isRetryfeatureEnabled, boolean expectedIsRetry) {
1095 when(featureManager.isActive(Features.FLAG_1902_RETRY_JOB)).thenReturn(isRetryfeatureEnabled);
1096 UUID uuid = createFakedJobAndServiceInfo();
1097 asyncInstantiationBL.updateServiceInfoAndAuditStatus(uuid, jobStatus);
1098 ServiceInfo serviceInfo = ((List<ServiceInfo>)dataAccessService.getList(ServiceInfo.class, getPropsMap())).
1099 stream().filter(x->x.getJobId().equals(uuid)).findFirst().get();
1100 assertEquals(jobStatus, serviceInfo.getJobStatus());
1102 //we don't test serviceInfo.getStatusModifiedDate() because it's too complicated
1104 assertEquals(expectedIsRetry, serviceInfo.isRetryEnabled());
1108 public void givenServiceWithNullTrackByIds_whenReplaceTrackByIds_thenAllLevelsHasTrackByIdWithUUID() {
1109 ServiceInstantiation serviceInstantiation = FakeResourceCreator.createServiceWith2InstancesInEachLevel(Action.Create);
1110 //assert for the given that all trackById are null
1111 assertTrackByIdRecursively(serviceInstantiation, is(nullValue()), new HashSet<>());
1112 ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.prepareServiceToBeUnique(serviceInstantiation);
1113 assertTrackByIdRecursively(modifiedServiceInstantiation, uuidRegexMatcher, new HashSet<>());
1116 private void assertTrackByIdRecursively(BaseResource baseResource, org.hamcrest.Matcher matcher, Set<String> usedUuids) {
1117 assertThat(baseResource.getTrackById(), matcher);
1118 if (baseResource.getTrackById()!=null) {
1119 assertThat(usedUuids, not(hasItem(baseResource.getTrackById())));
1120 usedUuids.add(baseResource.getTrackById());
1122 baseResource.getChildren().forEach(x->assertTrackByIdRecursively(x, matcher, usedUuids));
1126 public void givenServicefromDB_returnsTheBulkRequest() throws IOException {
1127 ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1Request.json", ServiceInstantiation.class);
1128 UUID jobId = UUID.randomUUID();
1129 doReturn(serviceInstantiation).when(asyncInstantiationRepository).getJobRequest(jobId);
1130 doReturn(mock(Map.class)).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
1131 ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.getBulkForRetry(jobId);
1132 assertThat(modifiedServiceInstantiation, jsonEquals(serviceInstantiation).when(IGNORING_ARRAY_ORDER));
1136 public void givenServiceFromDB_returnsResolvedData() throws IOException {
1137 ServiceInstantiation serviceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1Request.json", ServiceInstantiation.class);
1138 ServiceInstantiation expectedServiceInstantiation = TestUtils.readJsonResourceFileAsObject("/payload_jsons/VnfGroupCreate3Delete1None1RequestResolvedForRetry.json", ServiceInstantiation.class);
1139 UUID jobId = UUID.randomUUID();
1140 AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
1141 "/responses/mso/orchestrationRequestsVnf.json",
1142 AsyncRequestStatus.class);
1143 Map<String, ResourceInfo> mockedResourceInfoMap = ImmutableMap.of(
1144 "groupingservicefortest..ResourceInstanceGroup..0:001", new ResourceInfo("groupingservicefortest..ResourceInstanceGroup..0:001",jobId,"VNF_GROUP1_INSTANCE_ID", COMPLETED, asyncRequestStatus),// TODO case: delete completed
1145 "ag5aav86u4j", new ResourceInfo("ag5aav86u4j",jobId, null, FAILED, asyncRequestStatus),// case: failed
1146 "asedrftjko", new ResourceInfo("asedrftjko",jobId, "VNF_GROUP1_INSTANCE_ID_3", COMPLETED, asyncRequestStatus),//case: completed after retry failed
1147 "rgedfdged4", new ResourceInfo("rgedfdged4", jobId,"VNF_GROUP1_INSTANCE_ID_4", COMPLETED, asyncRequestStatus ));// case: create completed
1149 doReturn(mockedResourceInfoMap).when(asyncInstantiationRepository).getResourceInfoByRootJobId(jobId);
1150 ServiceInstantiation modifiedServiceInstantiation = asyncInstantiationBL.enrichBulkForRetry(serviceInstantiation,jobId);
1151 assertThat(modifiedServiceInstantiation, jsonEquals(expectedServiceInstantiation).when(IGNORING_ARRAY_ORDER));
1155 public static Object[][] readStatusMsgDataProvider(Method test) throws IOException {
1156 AsyncRequestStatus asyncRequestStatus = TestUtils.readJsonResourceFileAsObject(
1157 "/responses/mso/orchestrationRequestsVnf.json",
1158 AsyncRequestStatus.class);
1159 return new Object[][]{
1161 {new AsyncRequestStatus(), null},
1162 {new AsyncRequestStatus(new AsyncRequestStatus.Request()), null},
1163 {new AsyncRequestStatus(new AsyncRequestStatus.Request(new RequestStatus())), null},
1164 {asyncRequestStatus, "Vnf has been created successfully."}
1168 @Test(dataProvider = "readStatusMsgDataProvider")
1169 public void resourceInfoReadStatusMsg_returnsStatusMsgOrNull(AsyncRequestStatus asyncRequestStatus, String expected) {
1170 ResourceInfo resourceInfo = new ResourceInfo("groupingservicefortest..ResourceInstanceGroup..0:001",UUID.randomUUID(),"VNF_GROUP1_INSTANCE_ID", COMPLETED, asyncRequestStatus);
1171 String msg= asyncInstantiationBL.readStatusMsg(resourceInfo);
1172 assertThat(msg, equalTo( expected));
1176 public void testAddResourceInfoForOkResponse() {
1177 reset(asyncInstantiationRepository);
1178 String serviceInstanceId = "service-instance-id";
1179 UUID jobUuid = UUID.randomUUID();
1181 asyncInstantiationBL.addResourceInfo(prepareSharedDataForAddResourceInfo(jobUuid), JobStatus.IN_PROGRESS, serviceInstanceId);
1183 ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1184 verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1186 ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1187 assertResourceInfoValues(resourceInfo, serviceInstanceId, jobUuid, JobStatus.IN_PROGRESS);
1188 assertThat(resourceInfo.getErrorMessage(), is(nullValue()));
1191 private JobSharedData prepareSharedDataForAddResourceInfo(UUID jobUuid) {
1192 ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class);
1193 when(serviceInstantiation.getTrackById()).thenReturn("track-by-id");
1194 return new JobSharedData(jobUuid, "", serviceInstantiation, "");
1197 private void assertResourceInfoValues(ResourceInfo resourceInfo, String serviceInstanceId, UUID jobUuid, JobStatus jobStatus) {
1198 assertThat(resourceInfo.getInstanceId(), equalTo(serviceInstanceId));
1199 assertThat(resourceInfo.getJobStatus(), equalTo(jobStatus));
1200 assertThat(resourceInfo.getRootJobId(), equalTo(jobUuid));
1201 assertThat(resourceInfo.getTrackById(), equalTo("track-by-id"));
1205 public static Object[][] addResourceInfoWithError() {
1206 String message = "Failed to create service instance";
1207 return new Object[][]{
1209 {199, "{\"serviceException\":{\"messageId\":\"SVC2000\",\"text\":\"Error: " + message + "\"}}"}
1213 @Test(dataProvider = "addResourceInfoWithError")
1214 public void testAddResourceInfoForErrorResponse(int errorCode, String errorMessage) {
1215 reset(asyncInstantiationRepository);
1216 UUID jobUuid = UUID.randomUUID();
1218 RestObject restObject = mock(RestObject.class);
1219 when(restObject.getStatusCode()).thenReturn(errorCode);
1220 when(restObject.getRaw()).thenReturn(errorMessage);
1221 asyncInstantiationBL.addFailedResourceInfo(prepareSharedDataForAddResourceInfo(jobUuid), restObject);
1223 ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1224 verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1226 ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1227 assertResourceInfoValues(resourceInfo, null, jobUuid, JobStatus.FAILED);
1228 assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), containsString("Failed to create service instance"));
1229 assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), containsString(String.valueOf(errorCode)));
1230 ZonedDateTime parsedDate = TimeUtils.parseZonedDateTime(resourceInfo.getErrorMessage().request.requestStatus.getTimestamp());
1231 assertThat(parsedDate.toLocalDate(), is(LocalDate.now()));
1233 doReturn(resourceInfo).when(asyncInstantiationRepository).getResourceInfoByTrackId(any());
1234 JobAuditStatus jobAuditStatus = auditService.getResourceAuditStatus(resourceInfo.getTrackById());
1235 assertThat(jobAuditStatus.getJobStatus(), equalTo("FAILED"));
1236 assertThat(jobAuditStatus.getAdditionalInfo(), containsString("Failed to create service instance"));
1237 assertThat(jobAuditStatus.getAdditionalInfo(), containsString(String.valueOf(errorCode)));
1238 assertTrue(DateUtils.isSameDay(jobAuditStatus.getCreatedDate(), new Date()));
1242 public static Object[][] updateResourceInfoParameters() {
1243 return new Object[][] {
1244 {JobStatus.COMPLETED, "Instance was created successfully"},
1245 {JobStatus.FAILED, "Failed to create instance"}
1249 @Test(dataProvider = "updateResourceInfoParameters")
1250 public void testUpdateResourceInfo(JobStatus jobStatus, String message) {
1251 reset(asyncInstantiationRepository);
1252 UUID jobUuid = UUID.randomUUID();
1253 JobSharedData sharedData = new JobSharedData(jobUuid, "", mock(ServiceInstantiation.class),"");
1255 ResourceInfo resourceInfoMock = new ResourceInfo();
1256 resourceInfoMock.setTrackById(UUID.randomUUID().toString());
1257 doReturn(resourceInfoMock).when(asyncInstantiationRepository).getResourceInfoByTrackId(any());
1259 AsyncRequestStatus asyncRequestStatus = asyncInstantiationBL.convertMessageToAsyncRequestStatus(message);
1261 asyncInstantiationBL.updateResourceInfo(sharedData, jobStatus, asyncRequestStatus);
1263 ArgumentCaptor<ResourceInfo> resourceInfoCaptor = ArgumentCaptor.forClass(ResourceInfo.class);
1264 verify(asyncInstantiationRepository).saveResourceInfo(resourceInfoCaptor.capture());
1266 ResourceInfo resourceInfo = resourceInfoCaptor.getValue();
1267 assertThat(resourceInfo.getJobStatus(), equalTo(jobStatus));
1268 if (jobStatus == JobStatus.FAILED) {
1269 assertThat(resourceInfo.getErrorMessage(), is(not(nullValue())));
1270 assertThat(resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage(), equalTo(message));
1271 ZonedDateTime parsedDate = TimeUtils.parseZonedDateTime(resourceInfo.getErrorMessage().request.requestStatus.getTimestamp());
1272 assertThat(parsedDate.toLocalDate(), is(LocalDate.now()));
1274 assertThat(resourceInfo.getErrorMessage(), is(nullValue()));
1277 JobAuditStatus jobAuditStatus = auditService.getResourceAuditStatus(resourceInfo.getTrackById());
1278 if (jobStatus == JobStatus.FAILED) {
1279 assertThat(jobAuditStatus.getJobStatus(), equalTo("FAILED"));
1280 assertThat(jobAuditStatus.getAdditionalInfo(), equalTo(message));
1282 assertThat(jobAuditStatus, is(nullValue()));
1287 static class MockedJob implements Job {
1289 private static Map<UUID, MockedJob> uuidToJob = new HashMap<>();
1291 public static void putJob(UUID uuid, MockedJob job) {
1292 uuidToJob.put(uuid, job);
1295 public static MockedJob getJob(UUID uuid) {
1296 return uuidToJob.get(uuid);
1300 private String optimisticUniqueServiceInstanceName;
1302 public MockedJob(String optimisticUniqueServiceInstanceName) {
1303 this.optimisticUniqueServiceInstanceName = optimisticUniqueServiceInstanceName;
1306 private UUID uuid = UUID.randomUUID();
1309 public UUID getUuid() {
1314 public void setUuid(UUID uuid) {
1319 public JobStatus getStatus() {
1320 return JobStatus.PENDING;
1324 public void setStatus(JobStatus status) {
1329 public Map<String, Object> getData() {
1334 public JobSharedData getSharedData() {
1335 return new JobSharedData(uuid, "", null,"");
1339 public void setTypeAndData(JobType jobType, Map<String, Object> commandData) {
1344 public UUID getTemplateId() {
1349 public void setTemplateId(UUID templateId) {
1354 public Integer getIndexInBulk() {
1359 public void setIndexInBulk(Integer indexInBulk) {
1364 public JobType getType() {
1368 public String getOptimisticUniqueServiceInstanceName() {
1369 return optimisticUniqueServiceInstanceName;
1375 public void testGetVfModuleReplacePath_asMSOexpected()
1377 String path = asyncInstantiationBL.getVfModuleReplacePath("myService", "myVNF", "myVFModule");
1378 assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myService/vnfs/myVNF/vfModules/myVFModule/replace"));