aboutsummaryrefslogtreecommitdiffstats
path: root/vid-app-common/src/test/java/org/onap/vid/job
diff options
context:
space:
mode:
Diffstat (limited to 'vid-app-common/src/test/java/org/onap/vid/job')
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java88
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java143
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java83
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java85
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java36
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java303
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java40
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java208
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java157
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java98
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java77
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java925
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterImplTest.java110
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterTest.java100
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/impl/JobSchedulerInitializerTest.java121
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/impl/JobWorkerTest.java9
16 files changed, 2047 insertions, 536 deletions
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java
new file mode 100644
index 000000000..61a54f250
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/CommandUtilsTest.java
@@ -0,0 +1,88 @@
+package org.onap.vid.job.command;
+
+import com.google.common.collect.ImmutableMap;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.vid.asdc.AsdcCatalogException;
+import org.onap.vid.model.GroupProperties;
+import org.onap.vid.model.ServiceModel;
+import org.onap.vid.model.VfModule;
+import org.onap.vid.services.VidService;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.mockito.Mockito.*;
+
+public class CommandUtilsTest {
+
+ @InjectMocks
+ CommandUtils commandUtils;
+
+ @Mock
+ VidService vidService;
+
+ @BeforeClass
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @AfterMethod
+ public void resetVidService() {
+ reset(vidService);
+ }
+
+ @DataProvider
+ public static Object[][] trueAndFalse() {
+ return new Object[][]{ {true}, {false} };
+ }
+
+ @Test(dataProvider="trueAndFalse")
+ void testIsVfModelIsBaseModule(boolean isBase) throws AsdcCatalogException {
+ final String serviceModelUuid = UUID.randomUUID().toString();
+ final String vfModuleUuid = UUID.randomUUID().toString();
+
+ ServiceModel mockedServiceModel = mock(ServiceModel.class);
+ VfModule mockedVfModule = mock(VfModule.class);
+ GroupProperties mockedGroupProperties = mock(GroupProperties.class);
+ Map<String, VfModule> vfModulesMap = ImmutableMap.of(randomAlphanumeric(10), mockedVfModule);
+
+ when(vidService.getService(serviceModelUuid)).thenReturn(mockedServiceModel);
+ when(mockedServiceModel.getVfModules()).thenReturn(vfModulesMap);
+ when(mockedVfModule.getUuid()).thenReturn(vfModuleUuid);
+ when(mockedVfModule.getProperties()).thenReturn(mockedGroupProperties);
+ when(mockedGroupProperties.getBaseModule()).thenReturn(isBase);
+
+ assertThat(commandUtils.isVfModuleBaseModule(serviceModelUuid, vfModuleUuid), equalTo(isBase));
+ }
+
+ @Test(expectedExceptions = AsdcCatalogException.class)
+ void whenCantFindModelInSdc_thenExceptionIsThrown() throws AsdcCatalogException {
+ String serviceModelUuid = UUID.randomUUID().toString();
+ when(vidService.getService(serviceModelUuid)).thenReturn(null);
+ commandUtils.isVfModuleBaseModule(serviceModelUuid, "abc");
+ }
+
+ @Test(expectedExceptions = AsdcCatalogException.class)
+ void whenCantFindVfModuleInModel_thenExceptionIsThrown() throws AsdcCatalogException {
+
+ String serviceModelUuid = UUID.randomUUID().toString();
+
+ ServiceModel mockedServiceModel = mock(ServiceModel.class);
+ Map<String, VfModule> emptyMap = Collections.emptyMap();
+
+ when(vidService.getService(serviceModelUuid)).thenReturn(mockedServiceModel);
+ when(mockedServiceModel.getVfModules()).thenReturn(emptyMap);
+
+ commandUtils.isVfModuleBaseModule(serviceModelUuid, "abc");
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java
deleted file mode 100644
index bc623928c..000000000
--- a/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusCommandTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2018 Nokia Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.job.command;
-
-
-import io.joshworks.restclient.http.HttpResponse;
-import org.mockito.Mock;
-import org.onap.vid.job.Job;
-import org.onap.vid.job.NextCommand;
-import org.onap.vid.mso.MsoInterface;
-import org.onap.vid.mso.rest.AsyncRequestStatus;
-import org.onap.vid.services.AsyncInstantiationBusinessLogic;
-import org.onap.vid.services.AuditService;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.ws.rs.ProcessingException;
-import java.util.UUID;
-
-
-import static org.assertj.core.api.Java6Assertions.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-public class InProgressStatusCommandTest {
-
- @Mock
- private AsyncInstantiationBusinessLogic asyncInstantiationBusinessLogic;
-
- @Mock
- private MsoInterface msoInterface;
-
- @Mock
- private AuditService auditService;
-
- @Mock
- private HttpResponse<AsyncRequestStatus> msoResponse;
-
- @Mock
- private AsyncRequestStatus asyncRequestStatus;
-
- @Mock
- private AsyncRequestStatus.Request request;
-
- private UUID uuid = UUID.randomUUID();
-
- private InProgressStatusCommand inProgressStatusCommand;
-
- @BeforeMethod
- public void setUp() {
- initMocks(this);
-
- inProgressStatusCommand = new InProgressStatusCommand(asyncInstantiationBusinessLogic, msoInterface, auditService, uuid, "sampleRequestId");
-
- when(asyncInstantiationBusinessLogic.getOrchestrationRequestsPath()).thenReturn("http://localhost:8080/samplePath");
- when(msoInterface.get("http://localhost:8080/samplePath/sampleRequestId", AsyncRequestStatus.class)).thenReturn(msoResponse);
- when(msoResponse.getBody()).thenReturn(asyncRequestStatus);
- }
-
-
- @Test
- public void whenSOReturnsErrorShouldSetProperFailureStateAndReturnRetryCommand() {
- when(msoResponse.getStatus()).thenReturn(500);
-
- NextCommand call = inProgressStatusCommand.call();
-
- assertThat(call.getStatus()).isEqualTo(Job.JobStatus.IN_PROGRESS);
- assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand);
-
- verify(auditService).setFailedAuditStatusFromMso(uuid, "sampleRequestId", 500, asyncRequestStatus.toString());
- }
-
- @Test
- public void shouldProperlyHandleFailedInstantiation() {
- when(msoResponse.getStatus()).thenReturn(200);
- when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenReturn(Job.JobStatus.FAILED);
- asyncRequestStatus.request = request;
-
- NextCommand call = inProgressStatusCommand.call();
-
- assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand);
- assertThat(call.getStatus()).isEqualTo(Job.JobStatus.FAILED);
-
- verify(asyncInstantiationBusinessLogic).handleFailedInstantiation(uuid);
- verify(asyncInstantiationBusinessLogic).auditMsoStatus(uuid, request);
- }
-
- @Test
- public void shouldRetryCommandWithPausedState() {
- when(msoResponse.getStatus()).thenReturn(200);
- when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenReturn(Job.JobStatus.PAUSE);
- asyncRequestStatus.request = request;
-
- NextCommand call = inProgressStatusCommand.call();
-
- assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand);
- assertThat(call.getStatus()).isEqualTo(Job.JobStatus.IN_PROGRESS);
-
- verify(asyncInstantiationBusinessLogic).auditMsoStatus(uuid, request);
- verify(asyncInstantiationBusinessLogic).updateServiceInfoAndAuditStatus(uuid, Job.JobStatus.PAUSE);
- }
-
- @Test
- public void shouldRetryCommandExitedWithProcessingException() {
- when(msoResponse.getStatus()).thenReturn(200);
- when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenThrow(new ProcessingException(""));
-
- NextCommand call = inProgressStatusCommand.call();
-
- assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand);
- assertThat(call.getStatus()).isEqualTo(Job.JobStatus.IN_PROGRESS);
- }
-
- @Test
- public void shouldSetStoppedStatusWhenRuntimeExceptionOccurs() {
- when(msoResponse.getStatus()).thenReturn(200);
- when(asyncInstantiationBusinessLogic.calcStatus(asyncRequestStatus)).thenThrow(new RuntimeException());
-
- NextCommand call = inProgressStatusCommand.call();
-
- assertThat(call.getCommand()).isEqualTo(inProgressStatusCommand);
- assertThat(call.getStatus()).isEqualTo(Job.JobStatus.STOPPED);
- }
-} \ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java
new file mode 100644
index 000000000..2e8139716
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/InProgressStatusServiceTest.java
@@ -0,0 +1,83 @@
+package org.onap.vid.job.command;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.vid.job.Job;
+import org.onap.vid.job.impl.JobSharedData;
+import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
+import org.onap.vid.mso.RestMsoImplementation;
+import org.onap.vid.mso.RestObject;
+import org.onap.vid.mso.rest.AsyncRequestStatus;
+import org.onap.vid.services.AsyncInstantiationBaseTest;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
+import static org.testng.AssertJUnit.assertEquals;
+
+public class InProgressStatusServiceTest {
+
+ @Mock
+ private RestMsoImplementation restMso;
+
+ @Mock
+ private AsyncInstantiationBusinessLogic asyncInstantiationBL;
+
+ @InjectMocks
+ private InProgressStatusService inProgressStatusService;
+
+ @BeforeClass
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @DataProvider
+ public static Object[][] jobStatuses() {
+ return Stream.of(Job.JobStatus.values())
+ .map(student -> new Object[] { student })
+ .toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "jobStatuses")
+ public void whenGetFromMsoRequestStatus_returnItToCaller(Job.JobStatus expectedJobStatus) {
+
+ UUID jobUuid = UUID.randomUUID();
+ String userId = "mockedUserID";
+ String requestId = UUID.randomUUID().toString();
+ ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class);
+
+ when(asyncInstantiationBL.getOrchestrationRequestsPath()).thenReturn("");
+
+ RestObject<AsyncRequestStatus> msoResponse = mock(RestObject.class);
+ AsyncRequestStatus requestStatus = AsyncInstantiationBaseTest.asyncRequestStatusResponse("");
+
+ when(msoResponse.getStatusCode()).thenReturn(200);
+ when(msoResponse.get()).thenReturn(requestStatus);
+ when(restMso.GetForObject(contains(requestId), eq(AsyncRequestStatus.class))).thenReturn(msoResponse);
+
+ when(asyncInstantiationBL.calcStatus(any())).thenReturn(expectedJobStatus);
+
+ ExpiryChecker expiryChecker = mock(ExpiryChecker.class);
+ when(expiryChecker.isExpired(any())).thenReturn(false);
+
+ JobSharedData sharedData = new JobSharedData(jobUuid, userId, serviceInstantiation);
+ Job.JobStatus actualJobStatus = inProgressStatusService.call(expiryChecker, sharedData, requestId);
+ assertEquals(expectedJobStatus, actualJobStatus);
+
+ verify(asyncInstantiationBL).auditMsoStatus(eq(jobUuid), same(requestStatus.request));
+
+ //verify we don't update service info during this case, which shall stay in_progress
+ verify(asyncInstantiationBL, never()).updateServiceInfo(any(), any());
+
+
+ }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java
new file mode 100644
index 000000000..4cd00174a
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/InstanceGroupCommandTest.java
@@ -0,0 +1,85 @@
+package org.onap.vid.job.command;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.beanutils.BeanUtils;
+import org.mockito.Answers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.vid.job.impl.JobSharedData;
+import org.onap.vid.model.RequestReferencesContainer;
+import org.onap.vid.model.serviceInstantiation.InstanceGroup;
+import org.onap.vid.mso.RestMsoImplementation;
+import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.springframework.http.HttpMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Optional;
+import java.util.Set;
+
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+public class InstanceGroupCommandTest {
+
+ @Mock(answer = Answers.RETURNS_MOCKS)
+ RestMsoImplementation restMso;
+
+ @Mock InstanceGroup instanceGroupRequest;
+
+ @Mock(answer = Answers.RETURNS_MOCKS)
+ MsoResultHandlerService msoResultHandlerService;
+
+ @Mock WatchChildrenJobsBL watchChildrenJobsBL;
+
+ @Mock(answer = Answers.RETURNS_MOCKS)
+ AsyncInstantiationBusinessLogic asyncInstantiationBL;
+
+ @Mock InProgressStatusService inProgressStatusService;
+
+ @InjectMocks
+ private InstanceGroupCommand command;
+
+ @BeforeMethod
+ public void initMocks() {
+ command = null;
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void createMyself_callsMso() {
+ final ModelInfo serviceModelInfo = setRandomStrings(new ModelInfo());
+ final String serviceInstanceId = "service-instance-id";
+ final String userId = "ff3223";
+
+ command.init(new JobSharedData(
+ null, userId, instanceGroupRequest
+ ), ImmutableMap.of(
+ "resourceModelInfos", ImmutableMap.of("SERVICE_MODEL_INFO", serviceModelInfo),
+ "resourceInstancesIds", ImmutableMap.of("SERVICE_INSTANCE_ID", serviceInstanceId)
+ ));
+
+ command.createMyself();
+
+ verify(asyncInstantiationBL).generateInstanceGroupInstantiationRequest(
+ same(instanceGroupRequest), eq(serviceModelInfo), eq(serviceInstanceId), eq(userId));
+ verify(restMso, only()).restCall(eq(HttpMethod.POST), eq(RequestReferencesContainer.class), any(), any(), eq(Optional.empty()));
+
+ }
+
+ private ModelInfo setRandomStrings(ModelInfo object) {
+ try {
+ Set<String> fields = BeanUtils.describe(object).keySet();
+ BeanUtils.populate(object,
+ fields.stream().collect(toMap(identity(), s -> randomAlphanumeric(4))));
+ return object;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java
index b51553be7..2138b77cd 100644
--- a/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/JobCommandFactoryTest.java
@@ -1,17 +1,22 @@
package org.onap.vid.job.command;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableMap;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.onap.vid.job.Job;
+import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobCommand;
import org.onap.vid.job.JobType;
+import org.onap.vid.job.impl.JobSharedData;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Map;
+import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -48,19 +53,48 @@ public class JobCommandFactoryTest {
}
+ public static class MockedRequest implements JobAdapter.AsyncJobRequest {
+
+ final public int x;
+ final public String y;
+
+ @JsonCreator
+ public MockedRequest(@JsonProperty("x")int x, @JsonProperty("y")String y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof MockedRequest)) return false;
+ MockedRequest that = (MockedRequest) o;
+ return x == that.x &&
+ Objects.equals(y, that.y);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(x, y);
+ }
+ }
+
@Test(dataProvider = "jobTypes")
public void givenJob_createCommandCallsTheInitAndReturnsTheInstance(JobType jobType) {
final UUID uuid = UUID.randomUUID();
final Map<String, Object> data = ImmutableMap.of("foo", "bar");
+ final JobSharedData sharedData = new JobSharedData(uuid, "userid", new MockedRequest(1,"a"));
when(job.getType()).thenReturn(jobType);
when(job.getUuid()).thenReturn(uuid);
when(job.getData()).thenReturn(data);
+ when(job.getSharedData()).thenReturn(sharedData);
final JobCommand command = jobCommandFactory.toCommand(job);
- verify(mockCommand).init(uuid, data);
+ verify(mockCommand).init(sharedData, data);
assertThat(command, equalTo(mockCommand));
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java
new file mode 100644
index 000000000..29be48edc
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java
@@ -0,0 +1,303 @@
+package org.onap.vid.job.command;
+
+import com.google.common.collect.ImmutableMap;
+import org.jetbrains.annotations.NotNull;
+import org.onap.vid.exceptions.GenericUncheckedException;
+import org.onap.vid.job.Job;
+import org.onap.vid.job.JobAdapter;
+import org.onap.vid.job.NextCommand;
+import org.onap.vid.job.impl.JobSharedData;
+import org.onap.vid.model.Action;
+import org.onap.vid.model.serviceInstantiation.BaseResource;
+import org.onap.vid.mso.RestMsoImplementation;
+import org.springframework.http.HttpMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import javax.ws.rs.ProcessingException;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE;
+import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE;
+import static org.onap.vid.utils.Logging.getMethodCallerName;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+
+public class ResourceCommandTest {
+
+ public static class MockCommand extends ResourceCommand {
+
+ public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus) {
+ super(mock(RestMsoImplementation.class, RETURNS_MOCKS), mock(InProgressStatusService.class), mock(MsoResultHandlerService.class, RETURNS_MOCKS), mock(WatchChildrenJobsBL.class));
+
+ this.mockedJobStatus = mockedJobStatus;
+ this.mockState = mockState;
+ this.mockPhase = mockPhase;
+ if (mockState==InternalState.INITIAL) {
+ init(mock(JobSharedData.class), Collections.emptyMap());
+ }
+ else {
+ init(mock(JobSharedData.class), ImmutableMap.of(INTERNAL_STATE, mockState.name(), ACTION_PHASE, mockPhase.name()));
+ }
+ when(this.getWatchChildrenJobsBL().cumulateJobStatus(any(), any())).thenReturn(mockedJobStatus);
+ }
+
+ private final Job.JobStatus mockedJobStatus;
+ private final InternalState mockState;
+ private final Action mockPhase;
+
+
+ @NotNull
+ @Override
+ public Job.JobStatus createChildren() {
+ if (mockState == InternalState.CREATING_CHILDREN || (mockState == InternalState.INITIAL && mockPhase== Action.Delete))
+ return mockedJobStatus;
+ throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
+ }
+
+ protected Job.JobStatus mockedStatusOrThrow(InternalState expectedState) {
+ if (mockState == expectedState)
+ return mockedJobStatus;
+ throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
+ }
+
+ protected MsoRestCallPlan mockedPlanOrThrow(InternalState expectedState) {
+ if (mockState == expectedState)
+ return new MsoRestCallPlan(HttpMethod.POST, "path", Optional.empty(), Optional.empty(), "nothing");
+ throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
+ }
+
+ @NotNull
+ @Override
+ public MsoRestCallPlan planCreateMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
+ return mockedPlanOrThrow(InternalState.CREATE_MYSELF);
+ }
+
+ @NotNull
+ @Override
+ public MsoRestCallPlan planDeleteMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
+ return mockedPlanOrThrow(InternalState.DELETE_MYSELF);
+ }
+ }
+
+ public static class MockCommandTestingStateMachine extends MockCommand {
+
+ private final JobSharedData sharedData;
+
+ public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf) {
+ this(mockState, mockPhase, mockedJobStatus, mockedNeedToDeleteMySelf, false);
+ }
+
+ public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf, boolean isService) {
+ super(mockState, mockPhase, mockedJobStatus);
+ this.mockedNeedToDeleteMySelf = mockedNeedToDeleteMySelf;
+ this.isService = isService;
+ this.sharedData = mock(JobSharedData.class, RETURNS_MOCKS);
+ }
+
+ protected final boolean mockedNeedToDeleteMySelf;
+ private final boolean isService;
+
+ @NotNull
+ @Override
+ public Job.JobStatus inProgress() {
+ return mockedStatusOrThrow(InternalState.IN_PROGRESS);
+ }
+
+ @NotNull
+ @Override
+ public Job.JobStatus watchChildren() {
+ return mockedStatusOrThrow(InternalState.WATCHING);
+ }
+
+ @Override
+ public boolean isNeedToDeleteMyself() {
+ return mockedNeedToDeleteMySelf;
+ }
+
+ @Override
+ protected boolean isServiceCommand() {
+ return isService;
+ }
+
+ @Override
+ public JobSharedData getSharedData() {
+ return sharedData;
+ }
+ }
+
+ @DataProvider
+ public static Object[][] nextStateDeletePhaseProvider() {
+ return new Object[][]{
+ {InternalState.CREATING_CHILDREN, Job.JobStatus.COMPLETED, InternalState.WATCHING},
+ {InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF},
+ {InternalState.WATCHING, Job.JobStatus.IN_PROGRESS, InternalState.WATCHING},
+ {InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING},
+ {InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS},
+ {InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, InternalState.TERMINAL},
+ {InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS},
+ {InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.IN_PROGRESS},
+ };
+ }
+
+ @Test(dataProvider = "nextStateDeletePhaseProvider")
+ public void whenCalcNextStateDeletePhase_expectedStateIsReturned(
+ InternalState internalState, Job.JobStatus jobStatus, InternalState expectedState) {
+
+ //there is no meaning to the constructor inputs here
+ MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.FAILED, true);
+ assertEquals(expectedState, underTest.calcNextStateDeletePhase(jobStatus, internalState));
+ }
+
+ @Test
+ public void whenNoNeedToDeleteMyself_internalStateMovesFromWatchingToTerminal() {
+ MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false);
+ assertEquals(InternalState.TERMINAL, underTest.calcNextStateDeletePhase(Job.JobStatus.COMPLETED, InternalState.WATCHING));
+ }
+
+ @DataProvider
+ public static Object[][] testShallStopJobDataProvider() {
+ return new Object[][]{
+ {Job.JobStatus.IN_PROGRESS, Action.None, false, false},
+ {Job.JobStatus.COMPLETED_WITH_NO_ACTION, Action.None, false, false},
+ {Job.JobStatus.COMPLETED, Action.None, false, false},
+ {Job.JobStatus.FAILED, Action.None, false, true},
+ {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, false, true},
+ {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, true, false},
+ {Job.JobStatus.FAILED, Action.None, true, false},
+ {Job.JobStatus.FAILED, Action.Delete, true, true},
+ {Job.JobStatus.FAILED, Action.Create, true, true},
+ };
+ }
+
+
+ @Test(dataProvider = "testShallStopJobDataProvider")
+ public void testShallStopJob(Job.JobStatus jobStatus, Action action, boolean isService, boolean expectedResult) {
+ //in this test, there is no meaning to constructor parameters besides isService
+ MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false, isService);
+
+ BaseResource mockedRequest = mock(BaseResource.class);
+ when(underTest.getSharedData().getRequest()).thenReturn(mockedRequest);
+ when(mockedRequest.getAction()).thenReturn(action);
+
+ assertEquals(expectedResult, underTest.shallStopJob(jobStatus));
+ }
+
+ @DataProvider
+ public static Object[][] testCallDataProvider() {
+ return new Object[][]{
+ {"initial state with successful creating children" ,InternalState.INITIAL, Job.JobStatus.COMPLETED, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ {"initial state with failed creating children", InternalState.INITIAL, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
+ {"watching state with children still in progress" ,InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ {"watching state with children that completed with errors" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_ERRORS, null, Job.JobStatus.COMPLETED_WITH_ERRORS},
+ {"watching state with children that completed with no action" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_NO_ACTION, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ {"watching state with children that has completed" ,InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ {"mso call state that failed" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
+ //TODO handle AAI get unique name state {"mso call state that still in progress" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED, false},
+ {"mso call state that success" ,InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ {"in progress return in progress" ,InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.PAUSE, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.STOPPED, null, Job.JobStatus.STOPPED},
+ {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
+ {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, null, Job.JobStatus.COMPLETED},
+
+ };
+ }
+
+ @Test(dataProvider = "testCallDataProvider")
+ public void whenCallCommandWithDeletePhase_nextJobStatusAndInternalStateAreAsExpected(
+ String description, InternalState internalState, Job.JobStatus currentStateResult,
+ InternalState expectedNextState, Job.JobStatus expectedNextStatus) {
+
+ MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(internalState, Action.Delete, currentStateResult, true);
+ NextCommand nextCommand = underTest.call();
+ assertEquals(expectedNextStatus, nextCommand.getStatus());
+
+ //expectedNextState == null means nextCommand has no real command
+ if (expectedNextState!=null) {
+ assertEquals(expectedNextState, (nextCommand.getCommand().getData().get(INTERNAL_STATE)));
+ assertFalse(nextCommand.getStatus().isFinal());
+ }
+ else {
+ assertNull(nextCommand.getCommand());
+ assertTrue(nextCommand.getStatus().isFinal());
+ }
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void whenCommandInUnMappedState_exceptionIsThrown() {
+ MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.COMPLETED, true);
+ underTest.call();
+ }
+
+ @DataProvider
+ public static Object[][] InProgressDataProvider() {
+ return Stream.of(Job.JobStatus.values())
+ .map(status -> new Object[] { status })
+ .toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "InProgressDataProvider")
+ public void whenGetResultFromMso_InProgressReturnThem(Job.JobStatus mockedJobStatus) {
+ Job.JobStatus expectedJobStatus = (mockedJobStatus== Job.JobStatus.PAUSE) ? Job.JobStatus.IN_PROGRESS : mockedJobStatus;
+ MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, mockedJobStatus);
+ when(underTest.getInProgressStatusService().call(any(), any(), any())).thenReturn(mockedJobStatus);
+ assertEquals(expectedJobStatus, underTest.inProgress());
+ }
+
+ @DataProvider
+ public static Object[][] InProgressExceptionsDataProvider() {
+ return new Object[][]{
+ {new ProcessingException(""), Job.JobStatus.IN_PROGRESS},
+ {new InProgressStatusService.BadResponseFromMso(null), Job.JobStatus.IN_PROGRESS},
+ {new GenericUncheckedException(""),Job.JobStatus.STOPPED }
+ };
+ }
+
+ @Test(dataProvider = "InProgressExceptionsDataProvider")
+ public void whenInProgressStatusServiceThrowException_InProgressReturnStatus(Exception exception, Job.JobStatus expectedJobStatus) {
+ MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, expectedJobStatus);
+ when(underTest.getInProgressStatusService().call(any(), any(), any())).thenThrow(exception);
+ assertEquals(expectedJobStatus, underTest.inProgress());
+ }
+
+ @DataProvider
+ public static Object[][] testIsNeedToDeleteMySelfDataProvider() {
+ return Stream.of(Action.values())
+ .map(status -> new Object[] { status })
+ .toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "testIsNeedToDeleteMySelfDataProvider")
+ public void testIsNeedToDeleteMySelf(Action action) {
+ boolean expectedResult = (action== Action.Delete);
+ MockCommand underTest = new MockCommand(InternalState.DELETE_MYSELF, Action.Delete, Job.JobStatus.IN_PROGRESS);
+ BaseResource mockedBaseResource = mock(BaseResource.class);
+ when(underTest.getSharedData().getRequest()).thenReturn(mockedBaseResource);
+ when(mockedBaseResource.getAction()).thenReturn(action);
+ assertEquals(expectedResult, underTest.isNeedToDeleteMyself());
+ }
+
+ @DataProvider
+ public static Object[][] testWatchingDataProvider() {
+ return new Object[][]{
+ {"all children final, no failed child ", Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED},
+ {"all children final, there is failed child ", Job.JobStatus.COMPLETED_WITH_ERRORS, Job.JobStatus.COMPLETED_WITH_ERRORS},
+ {"not all children final", Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS},
+ };
+ }
+
+ @Test(dataProvider = "testWatchingDataProvider")
+ public void testWatching(String desc, Job.JobStatus childrenJobsStatus, Job.JobStatus expectedJobStatus) {
+ MockCommand underTest = new MockCommand(InternalState.WATCHING, Action.Delete, Job.JobStatus.IN_PROGRESS);
+ when(underTest.getWatchChildrenJobsBL().retrieveChildrenJobsStatus(any())).thenReturn(childrenJobsStatus);
+ assertEquals(expectedJobStatus, underTest.watchChildren());
+ }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java
new file mode 100644
index 000000000..9ec49a2e5
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceInProgressStatusCommandTest.java
@@ -0,0 +1,40 @@
+package org.onap.vid.job.command;
+
+import org.mockito.InjectMocks;
+import org.mockito.MockitoAnnotations;
+import org.onap.vid.job.Job;
+import org.onap.vid.job.NextCommand;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+
+public class ResourceInProgressStatusCommandTest {
+
+ @InjectMocks
+ private ResourceInProgressStatusCommand commandUnderTest = new ResourceInProgressStatusCommand();
+
+ @BeforeMethod
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @DataProvider
+ public static Object[][] givenStatusToExpectedStatus() {
+ return new Object[][]{
+ {Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS},
+ {Job.JobStatus.FAILED, Job.JobStatus.FAILED},
+ {Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED}
+ };
+ }
+
+ @Test(dataProvider = "givenStatusToExpectedStatus")
+ public void whenGetStatusFromMso_returnExpectedNextCommand(Job.JobStatus jobStatus, Job.JobStatus expectedNextStatus) {
+ NextCommand nextCommand = commandUnderTest.processJobStatus(jobStatus);
+ assertThat(nextCommand.getStatus(), is(expectedNextStatus));
+ assertThat(nextCommand.getCommand(), is(commandUnderTest));
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java
new file mode 100644
index 000000000..bfda6cf34
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInProgressStatusCommandTest.java
@@ -0,0 +1,208 @@
+package org.onap.vid.job.command;
+
+import com.google.common.collect.ImmutableMap;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.job.*;
+import org.onap.vid.job.impl.JobSharedData;
+import org.onap.vid.model.serviceInstantiation.Network;
+import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
+import org.onap.vid.model.serviceInstantiation.Vnf;
+import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.properties.Features;
+import org.onap.vid.properties.VidProperties;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.springframework.core.env.Environment;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.togglz.core.manager.FeatureManager;
+
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+import static org.onap.vid.job.Job.JobStatus.*;
+
+public class ServiceInProgressStatusCommandTest {
+
+
+ @Mock
+ private AsyncInstantiationBusinessLogic asyncInstantiationBL;
+
+ @Mock
+ private JobsBrokerService jobsBrokerService;
+
+ @Mock
+ private JobAdapter jobAdapter;
+
+ @Mock
+ private FeatureManager featureManager;
+
+ @Mock
+ private JobSharedData sharedData;
+
+ @Mock
+ private Environment environment;
+
+ @Mock
+ private ServiceInstantiation request;
+
+ @Mock
+ private InProgressStatusService inProgressStatusService;
+
+ @InjectMocks
+ private ServiceInProgressStatusCommand command = new ServiceInProgressStatusCommand();
+
+ @DataProvider
+ public static Object[][] isNeedToCreateChildJobsDataProvider() {
+ return new Object[][]{
+ {new TreeMap<String,Vnf>() , true, true, false},
+ {null , true, true, false},
+ {ImmutableMap.of("a",mock(Vnf.class)), false, true, false},
+ {ImmutableMap.of("a",mock(Vnf.class)), true, false, false},
+ {ImmutableMap.of("a",mock(Vnf.class)), true, true, true},
+ };
+ }
+
+ @DataProvider
+ public static Object[][] processJobStatusData() {
+ return new Object[][]{
+ /* {MSO jobStatus, jobStartTime, isNeedToCreateChildJobs(), property vid.job.max.hoursInProgress, expected nextCommand.getStatus() } */
+ {IN_PROGRESS, false, IN_PROGRESS},
+ {FAILED, false, FAILED},
+ {PAUSE, false, IN_PROGRESS},
+ {COMPLETED, false, COMPLETED},
+ {COMPLETED, true, IN_PROGRESS},
+ {RESOURCE_IN_PROGRESS, false, RESOURCE_IN_PROGRESS},
+ {PENDING, false, PENDING},
+ {STOPPED, false, STOPPED},
+ {COMPLETED_WITH_ERRORS, false, COMPLETED_WITH_ERRORS},
+ {CREATING, false, CREATING}
+ };
+ }
+
+ @DataProvider
+ public static Object[][] isExpiredJobStatusData() {
+ return new Object[][]{
+ {ZonedDateTime.now(), "24", false},
+ {getTimeNowMinus(2), "1", true},
+ {getTimeNowMinus(24), "24", true},
+ {getTimeNowMinus(2), "0", false},
+ {getTimeNowMinus(2), "-1", false},
+ {getTimeNowMinus(2), "", false},
+ {getTimeNowMinus(2), "a", false}
+ };
+ }
+
+ private static ZonedDateTime getTimeNowMinus(int hoursAgo) {
+ return ZonedDateTime.ofInstant(Instant.now().minus(hoursAgo, ChronoUnit.HOURS), ZoneOffset.UTC);
+ }
+
+ @BeforeMethod
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test(dataProvider = "isNeedToCreateChildJobsDataProvider" )
+ public void testIsNeedToCreateChildJobs(Map<String, Vnf> serviceVnfs, boolean isALaCarte,
+ boolean isFeatureEnabled, boolean expected) {
+ MockitoAnnotations.initMocks(this);
+ ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class);
+ when(serviceInstantiation.getVnfs()).thenReturn(serviceVnfs);
+ when(serviceInstantiation.isALaCarte()).thenReturn(isALaCarte);
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(isFeatureEnabled);
+ assertThat(command.isNeedToCreateChildJobs(serviceInstantiation), is(expected));
+ }
+
+ @Test
+ public void whenGetFromMsoCompletedAndALaCarte_generateNewJobsForVnfs() {
+ UUID uuid = UUID.randomUUID();
+ String userId = "mockedUserID";
+ Vnf vnf1 = mock(Vnf.class);
+ Vnf vnf2 = mock(Vnf.class);
+ Network network1 = mock(Network.class);
+ ServiceInstantiation serviceInstantiation = mock(ServiceInstantiation.class);
+ when(serviceInstantiation.getVnfs()).thenReturn(ImmutableMap.of("a", vnf1, "b", vnf2));
+ when(serviceInstantiation.getNetworks()).thenReturn(ImmutableMap.of("c", network1));
+ when(serviceInstantiation.isALaCarte()).thenReturn(true);
+ when(serviceInstantiation.getModelInfo()).thenReturn(new ModelInfo());
+
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
+
+ UUID uuid1 = UUID.fromString("12345678-1234-1234-1234-123456789012");
+ UUID uuid2 = UUID.fromString("12345678-1234-1234-1234-123456789013");
+ UUID uuid3 = UUID.fromString("12345678-1234-1234-1234-123456789014");
+ when(jobsBrokerService.add(any())).thenReturn(uuid1).thenReturn(uuid2).thenReturn(uuid3);
+
+ JobSharedData sharedData = new JobSharedData(uuid, userId, serviceInstantiation);
+ command.init(sharedData, "", "");
+ when(inProgressStatusService.call(any(), eq(sharedData), any())).thenReturn(Job.JobStatus.COMPLETED);
+ NextCommand nextCommand = command.call();
+
+ ArgumentCaptor<JobAdapter.AsyncJobRequest> argumentCaptor = ArgumentCaptor.forClass(JobAdapter.AsyncJobRequest.class);
+ verify(jobAdapter, times(2)).createChildJob(eq(JobType.VnfInstantiation), eq(Job.JobStatus.CREATING), argumentCaptor.capture(), eq(sharedData), any());
+ verify(jobAdapter, times(1)).createChildJob(eq(JobType.NetworkInstantiation), eq(Job.JobStatus.CREATING), argumentCaptor.capture(), eq(sharedData), any());
+ assertThat(argumentCaptor.getAllValues(), containsInAnyOrder(vnf1, vnf2, network1));
+
+ verify(jobsBrokerService, times(3)).add(any());
+
+ //verify we don't update service info during this case, which shall stay in_progress
+ verify(asyncInstantiationBL, never()).updateServiceInfo(any(), any());
+
+ assertThat(nextCommand.getStatus(), is(Job.JobStatus.IN_PROGRESS));
+ assertThat(nextCommand.getCommand().getType(), is(new WatchingCommand().getType()));
+ assertThat(nextCommand.getCommand().getData().get("childrenJobs"), is(Arrays.asList(uuid1.toString(), uuid2.toString(), uuid3.toString())));
+ assertThat(nextCommand.getCommand().getData().get("isService"), is(true));
+ }
+
+ @Test(dataProvider = "processJobStatusData")
+ public void processJobStatusTest(Job.JobStatus jobStatus, boolean isNeedToCreateChildJobs, Job.JobStatus expectedStatus) {
+
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
+ // All mocks under are used for isNeedToCreateChildJobs=true case
+ when(sharedData.getRequest()).thenReturn(request);
+ when(request.isALaCarte()).thenReturn(true);
+ Map vnfs = mock(Map.class);
+ ModelInfo modelInfo = mock(ModelInfo.class);
+
+ // if vnfs.isEmpty -> isNeedToCreateChildJobs will return false
+ when(vnfs.isEmpty()).thenReturn(!isNeedToCreateChildJobs);
+
+ when(request.getVnfs()).thenReturn(vnfs);
+ when(request.getModelInfo()).thenReturn(modelInfo);
+ command.instanceId = "MockInstId";
+
+ NextCommand nextCommand = command.processJobStatus(jobStatus);
+ Assert.assertEquals(nextCommand.getStatus(), expectedStatus);
+ if (isNeedToCreateChildJobs) {
+ Assert.assertEquals(nextCommand.getCommand().getClass(), WatchingCommand.class);
+ } else {
+ Assert.assertEquals(nextCommand.getCommand(), command);
+ }
+ }
+
+ @Test(dataProvider = "isExpiredJobStatusData")
+ public void isExpiredJobStatusTest(ZonedDateTime jobStartTime, String configValue, boolean expectedResult) {
+ SystemProperties systemProperties = new SystemProperties();
+ systemProperties.setEnvironment(environment);
+ when(environment.getRequiredProperty(VidProperties.VID_JOB_MAX_HOURS_IN_PROGRESS)).thenReturn(configValue);
+ when(environment.containsProperty(VidProperties.VID_JOB_MAX_HOURS_IN_PROGRESS)).thenReturn(true);
+ Assert.assertEquals(command.getExpiryChecker().isExpired(jobStartTime), expectedResult);
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java
deleted file mode 100644
index e7ab4f098..000000000
--- a/vid-app-common/src/test/java/org/onap/vid/job/command/ServiceInstantiationCommandTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2018 Nokia Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.job.command;
-
-
-import io.joshworks.restclient.http.HttpResponse;
-import org.mockito.Mock;
-import org.onap.vid.aai.AaiResponse;
-import org.onap.vid.aai.exceptions.InvalidAAIResponseException;
-import org.onap.vid.changeManagement.RequestDetailsWrapper;
-import org.onap.vid.domain.mso.RequestReferences;
-import org.onap.vid.exceptions.MaxRetriesException;
-import org.onap.vid.job.Job;
-import org.onap.vid.job.NextCommand;
-import org.onap.vid.model.RequestReferencesContainer;
-import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
-import org.onap.vid.mso.MsoInterface;
-import org.onap.vid.mso.model.ServiceInstantiationRequestDetails;
-import org.onap.vid.services.AsyncInstantiationBusinessLogic;
-import org.onap.vid.services.AuditService;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.util.UUID;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-public class ServiceInstantiationCommandTest {
- @Mock
- private AsyncInstantiationBusinessLogic asyncInstantiationBusinessLogic;
-
- @Mock
- private MsoInterface msoInterface;
-
- @Mock
- private AuditService auditService;
-
- @Mock
- private ServiceInstantiation serviceInstantiation;
-
- @Mock
- private HttpResponse<RequestReferencesContainer> msoResponse;
-
- @Mock
- private RequestDetailsWrapper<ServiceInstantiationRequestDetails> requestDetailsWrapper;
-
- @Mock
- private AaiResponse aaiResponse;
-
- @Mock
- private RequestReferencesContainer requestReferencesContainer;
-
-
- private UUID uuid = UUID.randomUUID();
-
-
- private ServiceInstantiationCommand serviceInstantiationCommand;
-
- @BeforeMethod
- public void setUp() {
- initMocks(this);
- serviceInstantiationCommand = new ServiceInstantiationCommand(asyncInstantiationBusinessLogic, auditService, msoInterface, uuid, serviceInstantiation, "sampleUserId");
- }
-
-
- @Test
- public void shouldProperlyHandleMaxRetriesException() {
- when(asyncInstantiationBusinessLogic.generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId")).thenThrow(new MaxRetriesException("", 2));
-
- NextCommand call = serviceInstantiationCommand.call();
-
- assertThat(call.getCommand(), is(nullValue()));
- assertThat(call.getStatus(), is(equalTo(Job.JobStatus.FAILED)));
-
- verify(asyncInstantiationBusinessLogic).handleFailedInstantiation(uuid);
- }
-
- @Test
- public void shouldProperlyHandleInvalidAAIResponseException() {
- doThrow(new InvalidAAIResponseException(aaiResponse)).when(asyncInstantiationBusinessLogic).generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId");
-
- NextCommand call = serviceInstantiationCommand.call();
-
- assertThat(call.getCommand(), is(serviceInstantiationCommand));
- assertThat(call.getStatus(), is(equalTo(Job.JobStatus.IN_PROGRESS)));
- }
-
-
- @Test
- public void shouldProperlyHandleInvalidSOResponse() {
- when(asyncInstantiationBusinessLogic.generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId")).thenReturn(requestDetailsWrapper);
- when(asyncInstantiationBusinessLogic.getServiceInstantiationPath(serviceInstantiation)).thenReturn("samplePath");
- when(msoInterface.post("samplePath", requestDetailsWrapper, RequestReferencesContainer.class)).thenReturn(msoResponse);
- when(msoResponse.getStatus()).thenReturn(500);
- when(msoResponse.getBody()).thenReturn(requestReferencesContainer);
-
- NextCommand call = serviceInstantiationCommand.call();
-
- assertThat(call.getCommand(), is(nullValue()));
- assertThat(call.getStatus(), is(equalTo(Job.JobStatus.FAILED)));
-
- verify(auditService).setFailedAuditStatusFromMso(uuid, null, 500, requestReferencesContainer.toString());
- }
-
-
- @Test
- public void shouldProperlyUpdateServiceStatusAndReturnInProgressCommand() {
- RequestReferences requestReferences = createRequestReferences();
-
- when(asyncInstantiationBusinessLogic.generateServiceInstantiationRequest(uuid, serviceInstantiation, "sampleUserId")).thenReturn(requestDetailsWrapper);
- when(asyncInstantiationBusinessLogic.getServiceInstantiationPath(serviceInstantiation)).thenReturn("samplePath");
- when(msoInterface.post("samplePath", requestDetailsWrapper, RequestReferencesContainer.class)).thenReturn(msoResponse);
- when(msoResponse.getStatus()).thenReturn(200);
- when(msoResponse.getBody()).thenReturn(requestReferencesContainer);
- when(requestReferencesContainer.getRequestReferences()).thenReturn(requestReferences);
-
-
- NextCommand call = serviceInstantiationCommand.call();
-
- assertThat(call.getCommand(), instanceOf(InProgressStatusCommand.class));
- assertThat(call.getStatus(), is(equalTo(Job.JobStatus.IN_PROGRESS)));
-
- }
-
- private RequestReferences createRequestReferences() {
- RequestReferences requestReferences = new RequestReferences();
- requestReferences.setInstanceId("sampleInstanceId");
- requestReferences.setRequestId("sampleRequestId");
- return requestReferences;
- }
-} \ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java
new file mode 100644
index 000000000..98524c7db
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchChildrenJobsBLTest.java
@@ -0,0 +1,98 @@
+package org.onap.vid.job.command;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.portalsdk.core.service.DataAccessService;
+import org.onap.vid.job.Job.JobStatus;
+import org.onap.vid.job.impl.JobDaoImpl;
+import org.onap.vid.utils.DaoUtils;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.when;
+import static org.testng.AssertJUnit.assertEquals;
+
+public class WatchChildrenJobsBLTest {
+ @Mock
+ private DataAccessService dataAccessService;
+
+ @InjectMocks
+ private WatchChildrenJobsBL watchChildrenJobsBL;
+
+ @BeforeClass
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ public static Object[][] dataProviderForChildrenStatusOnly() {
+ return new Object[][]{
+ {Arrays.asList(JobStatus.STOPPED, JobStatus.COMPLETED_WITH_NO_ACTION, JobStatus.COMPLETED), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(null, JobStatus.COMPLETED), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(null, JobStatus.IN_PROGRESS), JobStatus.IN_PROGRESS},
+ {Arrays.asList(null, JobStatus.FAILED), JobStatus.FAILED},
+ {new ArrayList<>(), JobStatus.COMPLETED_WITH_NO_ACTION}
+ };
+ }
+
+ @DataProvider
+ public static Object[][] childrenStatusDataProvider() {
+
+ List<Object[]> result = new ArrayList<>();
+ result.addAll(Arrays.asList(dataProviderForChildrenStatusOnly()));
+ result.addAll(Arrays.asList(inputsStatusAndExpectedOutputDataProvider()));
+ return result.toArray(new Object[result.size()][]);
+ }
+
+ @DataProvider
+ public static Object[][] inputsStatusAndExpectedOutputDataProvider() {
+ return new Object[][]{
+ {Arrays.asList(JobStatus.COMPLETED, JobStatus.COMPLETED), JobStatus.COMPLETED},
+ {Arrays.asList(JobStatus.COMPLETED, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED},
+ {Arrays.asList(JobStatus.FAILED, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.FAILED},
+ {Arrays.asList(JobStatus.FAILED, JobStatus.COMPLETED), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(JobStatus.RESOURCE_IN_PROGRESS, JobStatus.FAILED), JobStatus.IN_PROGRESS},
+ {Arrays.asList(JobStatus.PAUSE, JobStatus.FAILED), JobStatus.IN_PROGRESS},
+ {Arrays.asList(JobStatus.PENDING, JobStatus.FAILED), JobStatus.IN_PROGRESS},
+ {Arrays.asList(JobStatus.IN_PROGRESS, JobStatus.COMPLETED), JobStatus.IN_PROGRESS},
+ {Arrays.asList(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS), JobStatus.IN_PROGRESS},
+ {Arrays.asList(JobStatus.COMPLETED, JobStatus.COMPLETED_WITH_ERRORS), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(JobStatus.COMPLETED_WITH_ERRORS, JobStatus.COMPLETED_WITH_ERRORS), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(JobStatus.COMPLETED_WITH_ERRORS, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED_WITH_ERRORS},
+ {Arrays.asList(JobStatus.COMPLETED_WITH_NO_ACTION, JobStatus.COMPLETED_WITH_NO_ACTION), JobStatus.COMPLETED_WITH_NO_ACTION},
+
+
+ };
+ }
+
+ @Test(dataProvider = "childrenStatusDataProvider")
+ public void whenRetrieveListOfChildrenWithStatues_thenAccumulatedChildrenStatusAsExpected(List<JobStatus> childJobs, JobStatus expectedChildrenJobsStatus) {
+ //init sql result mock
+ List<JobDaoImpl> mockChildren = childJobs.stream().map(st -> {
+ JobDaoImpl job = new JobDaoImpl();
+ job.setUuid(UUID.randomUUID());
+ job.setStatus(st);
+ return job;
+ }).collect(Collectors.toList());
+ when(dataAccessService.getList(eq(JobDaoImpl.class), anyString(), any(), eq(DaoUtils.getPropsMap())))
+ .thenReturn(mockChildren);
+
+ List<String> uuids = mockChildren.stream().map(job -> job.getUuid().toString()).collect(Collectors.toList());
+ assertEquals(expectedChildrenJobsStatus, watchChildrenJobsBL.retrieveChildrenJobsStatus(uuids));
+ }
+
+ @Test(dataProvider = "inputsStatusAndExpectedOutputDataProvider")
+ public void whenCumulate2JobStatus_thenResultAsExpected(List<JobStatus> jobs, JobStatus expectedChildrenJobsStatus) {
+ assertEquals(expectedChildrenJobsStatus, watchChildrenJobsBL.cumulateJobStatus(jobs.get(0), jobs.get(1)));
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java
new file mode 100644
index 000000000..f47a18d5f
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/WatchingCommandTest.java
@@ -0,0 +1,77 @@
+package org.onap.vid.job.command;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.portalsdk.core.service.DataAccessService;
+import org.onap.vid.job.Job;
+import org.onap.vid.job.NextCommand;
+import org.onap.vid.job.impl.JobSharedData;
+import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
+public class WatchingCommandTest {
+
+ @Mock
+ private AsyncInstantiationBusinessLogic asyncInstantiationBL;
+
+ @Mock
+ private DataAccessService dataAccessService;
+
+ @Mock
+ private WatchChildrenJobsBL watchChildrenJobsBL;
+
+ @InjectMocks
+ private WatchingCommand watchingCommand = new WatchingCommand();
+
+
+
+ @BeforeClass
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @DataProvider
+ public static Object[][] testWatchingDataProvider() {
+ return new Object[][]{
+ {"all children final, no failed child, is service", Job.JobStatus.COMPLETED, true, Job.JobStatus.COMPLETED},
+ {"all children final, there is failed child, is service", Job.JobStatus.COMPLETED_WITH_ERRORS, true, Job.JobStatus.COMPLETED_WITH_ERRORS},
+ {"not all children final, is service", Job.JobStatus.IN_PROGRESS, true, Job.JobStatus.IN_PROGRESS},
+ {"all children final, no failed child, not service", Job.JobStatus.COMPLETED, false, Job.JobStatus.COMPLETED},
+ {"all children final, there is failed child, not service", Job.JobStatus.COMPLETED_WITH_ERRORS, false, Job.JobStatus.COMPLETED_WITH_ERRORS},
+ {"not all children final, not service", Job.JobStatus.IN_PROGRESS, false, Job.JobStatus.RESOURCE_IN_PROGRESS},
+ };
+ }
+
+
+
+ @Test(dataProvider = "testWatchingDataProvider")
+ public void whenGetChildrenStatus_thenJobStatusAsExpected(String desc, Job.JobStatus childrenComulativeStatus, boolean isService, Job.JobStatus expectedCommandStatus) {
+ UUID jobUUID = UUID.randomUUID();
+ JobSharedData sharedData = new JobSharedData(jobUUID, "mockedUserID", mock(ServiceInstantiation.class));
+ List<String> uuids = mock(List.class);
+ watchingCommand.init(sharedData, uuids, isService);
+ when(watchChildrenJobsBL.retrieveChildrenJobsStatus(eq(uuids))).thenReturn(childrenComulativeStatus);
+ when(watchChildrenJobsBL.cumulateJobStatus(eq(childrenComulativeStatus),eq(Job.JobStatus.COMPLETED))).thenReturn(childrenComulativeStatus);
+
+ //execute command and verify
+ NextCommand nextCommand = watchingCommand.call();
+ assertThat(nextCommand.getStatus(), is(expectedCommandStatus));
+ if (!expectedCommandStatus.equals(Job.JobStatus.IN_PROGRESS) && isService) {
+ verify(asyncInstantiationBL).updateServiceInfoAndAuditStatus(jobUUID, expectedCommandStatus);
+ } else {
+ verify(asyncInstantiationBL, never()).updateServiceInfoAndAuditStatus(jobUUID, expectedCommandStatus);
+ }
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java b/vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java
new file mode 100644
index 000000000..f7f83bdfe
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java
@@ -0,0 +1,925 @@
+package org.onap.vid.job.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.StringUtils;
+import org.mockito.Mockito;
+import org.onap.portalsdk.core.service.DataAccessService;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.asdc.AsdcCatalogException;
+import org.onap.vid.config.DataSourceConfig;
+import org.onap.vid.config.JobCommandsConfigWithMockedMso;
+import org.onap.vid.config.MockedAaiClientAndFeatureManagerConfig;
+import org.onap.vid.job.Job;
+import org.onap.vid.job.Job.JobStatus;
+import org.onap.vid.job.JobType;
+import org.onap.vid.job.JobsBrokerService;
+import org.onap.vid.job.command.CommandUtils;
+import org.onap.vid.job.command.InternalState;
+import org.onap.vid.model.Action;
+import org.onap.vid.model.NameCounter;
+import org.onap.vid.model.RequestReferencesContainer;
+import org.onap.vid.model.ServiceInfo;
+import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
+import org.onap.vid.mso.RestMsoImplementation;
+import org.onap.vid.mso.RestObject;
+import org.onap.vid.mso.model.RequestReferences;
+import org.onap.vid.mso.rest.AsyncRequestStatus;
+import org.onap.vid.properties.Features;
+import org.onap.vid.services.AsyncInstantiationBaseTest;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.onap.vid.utils.DaoUtils;
+import org.springframework.test.context.ContextConfiguration;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.togglz.core.manager.FeatureManager;
+
+import javax.inject.Inject;
+import javax.ws.rs.ProcessingException;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.*;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasProperty;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.core.Every.everyItem;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.endsWith;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+import static org.onap.vid.job.Job.JobStatus.*;
+import static org.onap.vid.model.JobAuditStatus.SourceStatus.MSO;
+import static org.onap.vid.model.JobAuditStatus.SourceStatus.VID;
+import static org.testng.AssertJUnit.*;
+
+//it's more like integration test than UT
+//But it's very hard to test in API test so I use UT
+@ContextConfiguration(classes = {DataSourceConfig.class, SystemProperties.class, MockedAaiClientAndFeatureManagerConfig.class, JobCommandsConfigWithMockedMso.class})
+public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTest {
+
+ private static final String FAILED_STR = "FAILED";
+ private static final String COMPLETE_STR = "COMPLETE";
+ private static final String IN_PROGRESS_STR = "IN_PROGRESS";
+ private static final String REQUESTED = "REQUESTED";
+ private static final String PENDING_MANUAL_TASK = "PENDING_MANUAL_TASK";
+ public static final String RAW_DATA_FROM_MSO = "RAW DATA FROM MSO";
+ private static String USER_ID = "123";
+ public static String REQUEST_ID = UUID.randomUUID().toString();
+ public static String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
+
+ @Inject
+ private JobsBrokerService jobsBrokerService;
+
+ @Inject
+ private JobWorker jobWorker;
+
+ @Inject
+ private FeatureManager featureManager;
+
+ @Inject
+ private AsyncInstantiationBusinessLogic asyncInstantiationBL;
+
+ @Inject
+ private RestMsoImplementation restMso;
+
+ @Inject
+ private DataAccessService dataAccessService;
+
+ @Inject
+ private CommandUtils commandUtils;
+
+ @BeforeClass
+ void initServicesInfoService() {
+ createInstanceParamsMaps();
+ }
+
+ @BeforeMethod
+ void clearDb() {
+ dataAccessService.deleteDomainObjects(ServiceInfo.class, "1=1", DaoUtils.getPropsMap());
+ dataAccessService.deleteDomainObjects(JobDaoImpl.class, "1=1", DaoUtils.getPropsMap());
+ dataAccessService.deleteDomainObjects(NameCounter.class, "1=1", DaoUtils.getPropsMap());
+ }
+
+ @BeforeMethod
+ void defineMocks() {
+ mockAaiClientAnyNameFree();
+ }
+
+ //@Test
+ public void whenPushNewBulk_thenAllServicesAreInPending() {
+
+ pushMacroBulk();
+ List<ServiceInfo> serviceInfoList = asyncInstantiationBL.getAllServicesInfo();
+ assertThat( serviceInfoList, everyItem(hasProperty("jobStatus", is(PENDING))));
+ }
+
+ private List<UUID> pushMacroBulk() {
+ ServiceInstantiation serviceInstantiation = generateMockMacroServiceInstantiationPayload(false,
+ createVnfList(instanceParamsMapWithoutParams, Collections.EMPTY_LIST, true),
+ 3, true,PROJECT_NAME, true);
+ return asyncInstantiationBL.pushBulkJob(serviceInstantiation, USER_ID);
+ }
+
+ private UUID pushALaCarteWithVnf() {
+ ServiceInstantiation serviceInstantiation = generateALaCarteWithVnfsServiceInstantiationPayload();
+ List<UUID> uuids = asyncInstantiationBL.pushBulkJob(serviceInstantiation, USER_ID);
+ assertThat(uuids, hasSize(1));
+ return uuids.get(0);
+ }
+
+ private UUID pushALaCarteUpdateWithGroups() {
+ ServiceInstantiation serviceInstantiation = generateALaCarteUpdateWith1ExistingGroup2NewGroupsPayload();
+ List<UUID> uuids = asyncInstantiationBL.pushBulkJob(serviceInstantiation, USER_ID);
+ assertThat(uuids, hasSize(1));
+ return uuids.get(0);
+ }
+
+ public static RestObject<RequestReferencesContainer> createResponse(int statusCode) {
+ return createResponse(statusCode, SERVICE_INSTANCE_ID, REQUEST_ID);
+ }
+
+ public static RestObject<RequestReferencesContainer> createResponse(int statusCode, String instanceId, String requestId) {
+ RequestReferences requestReferences = new RequestReferences();
+ requestReferences.setRequestId(requestId);
+ requestReferences.setInstanceId(instanceId);
+ RestObject<RequestReferencesContainer> restObject = new RestObject<>();
+ restObject.set(new RequestReferencesContainer(requestReferences));
+ restObject.setStatusCode(statusCode);
+ restObject.setRaw(RAW_DATA_FROM_MSO);
+ return restObject;
+ }
+
+ ImmutableList<String> statusesToStrings(JobStatus... jobStatuses) {
+ return Stream.of(jobStatuses).map(
+ Enum::toString).collect(ImmutableList.toImmutableList());
+ }
+
+ /*
+ Make sure service state is in progress once request has sent to MSO
+ Make sure service state is in progress once request has sent to MSO and MSO status is in_progress
+ Make sure service state is Failed once we got from MSO failure state, and that job's are not collected any more.
+ Make sure service state is Completed successfully once we got from MSO complete, and that next job is peeked.
+ Once a service in the bulk is failed, other services moved to Stopped, and no other jobs from the bulk are peeked.
+ */
+ //@Test
+ public void testStatusesOfMacroServiceInBulkDuringBulkLifeCycle() {
+ when(restMso.PostForObject(any(), any(), eq(RequestReferencesContainer.class))).thenReturn(createResponse(200));
+ ImmutableList<ImmutableList<String>> expectedStatusesForVid = ImmutableList.of(
+ statusesToStrings(PENDING, IN_PROGRESS, COMPLETED),
+ statusesToStrings(PENDING, IN_PROGRESS, FAILED),
+ statusesToStrings(PENDING, STOPPED)
+ );
+
+ ImmutableList<ImmutableList<String>> expectedStatusesForMso = ImmutableList.of(
+ ImmutableList.of(REQUESTED, IN_PROGRESS_STR, "not a state", FAILED_STR ,COMPLETE_STR),
+ ImmutableList.of(REQUESTED, FAILED_STR),
+ ImmutableList.of()
+ );
+
+ List<UUID> uuids = pushMacroBulk();
+ pullPendingJobAndAssertJobStatus(JobStatus.IN_PROGRESS, PENDING);
+
+ //assert that when get ProcessingException from restMso, status remain the same
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).thenThrow(new ProcessingException("fake message"));
+ Job job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS);
+ UUID firstHandledJobUUID = job.getUuid();
+ listServicesAndAssertStatus(JobStatus.IN_PROGRESS, PENDING, job);
+
+ //assert that when get IN_PROGRESS status from restMso, status remain IN_PROGRESS
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).thenReturn(asyncRequestStatusResponseAsRestObject(IN_PROGRESS_STR));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS);
+ listServicesAndAssertStatus(JobStatus.IN_PROGRESS, PENDING, job);
+
+ //assert that when get unrecognized status from restMso, status remain IN_PROGRESS
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).thenReturn(asyncRequestStatusResponseAsRestObject("not a state"));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS);
+ listServicesAndAssertStatus(JobStatus.IN_PROGRESS, PENDING, job);
+
+ //assert that when get non 200 status code during IN_PROGRESS, status remain IN_PROGRESS
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR, 404));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS);
+ listServicesAndAssertStatus(JobStatus.IN_PROGRESS, PENDING, job);
+
+ //when get job COMPLETE from MSO, service status become COMPLETED
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, COMPLETED);
+ List<ServiceInfo> serviceInfoList = listServicesAndAssertStatus(COMPLETED, PENDING, job);
+
+
+ //for use later in the test
+ Map<UUID, JobStatus> expectedJobStatusMap = serviceInfoList.stream().collect(
+ Collectors.toMap(ServiceInfo::getJobId, x-> PENDING));
+ expectedJobStatusMap.put(job.getUuid(), COMPLETED);
+
+ //when handling another PENDING job, statuses are : COMPLETED, IN_PROGRESS, PENDING
+ job = pullJobProcessAndPushBack(PENDING, JobStatus.IN_PROGRESS);
+ assertThat(job.getUuid(), not(equalTo(firstHandledJobUUID))); //assert different job was handled now
+ expectedJobStatusMap.put(job.getUuid(), JobStatus.IN_PROGRESS);
+ listServicesAndAssertStatus(expectedJobStatusMap);
+
+ //when get FAILED status from MSO statuses are : COMPLETED, FAILED, STOPPED
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(FAILED_STR));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.FAILED);
+ expectedJobStatusMap.put(job.getUuid(), JobStatus.FAILED);
+ expectedJobStatusMap = expectedJobStatusMap.entrySet().stream().collect(Collectors.toMap(
+ e -> e.getKey(), e -> e.getValue() == PENDING ? JobStatus.STOPPED : e.getValue()
+ ));
+
+ listServicesAndAssertStatus(expectedJobStatusMap);
+ IntStream.range(0, uuids.size()).forEach(i -> {
+ UUID uuid = uuids.get(i);
+ List<String> msoStatuses = asyncInstantiationBL.getAuditStatuses(uuid, MSO).stream().map(x -> x.getJobStatus()).collect(Collectors.toList());
+ List<String> vidStatuses = asyncInstantiationBL.getAuditStatuses(uuid, VID).stream().map(x -> x.getJobStatus()).collect(Collectors.toList());
+ assertThat(msoStatuses, is(expectedStatusesForMso.get(i)));
+ assertThat(vidStatuses, is(expectedStatusesForVid.get(i)));
+ });
+ //
+ assertFalse(jobsBrokerService.pull(PENDING, randomUuid()).isPresent());
+ assertFalse(jobsBrokerService.pull(JobStatus.IN_PROGRESS, randomUuid()).isPresent());
+ }
+
+
+ @DataProvider
+ public static Object[][] AlaCarteStatuses(Method test) {
+ return new Object[][]{
+ {COMPLETE_STR, JobStatus.COMPLETED, JobStatus.COMPLETED},
+ {FAILED_STR, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED},
+ };
+ }
+
+ /*
+ Make sure service state is in progress once request has sent to MSO
+ Make sure service state is watching until state changes to complemented
+ Make sure service state is watching until vnf state changes to completed
+ Make sure service state is Completed successfully once we got from MSO complete for the vnf job.
+ status Creating
+ */
+ //@Test(dataProvider = "AlaCarteStatuses")
+ public void testStatusesOfServiceDuringALaCarteLifeCycleIgnoringVfModules(String msoVnfStatus, JobStatus expectedServiceStatus, JobStatus expectedVnfStatus) {
+ /*
+ [v] + push alacarte with 1 vnf
+ [v] verify STATUS pending
+ [v] + pull+execute (should post to MSO)
+ [v] verify STATUS in progress
+ [v] + pull+execute (should GET completed from MSO)
+ [v] verify STATUS in progress; TYPE watching
+ [v] verify job#2 *new* VNF job STATUS creating
+ [v] + pull+execute job#2 (should post to MSO)
+ [v] verify job#2 STATUS resource in progress
+ [v] verify job#1 STATUS in progress
+ [v] + pull+execute job#2 (should GET completed from MSO)
+ [v] verify job#2 STATUS completed
+ [v] + pull+execute job#1
+ [v] verify job#1 STATUS completed
+
+ * not looking on audit (yet)
+ */
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(false);
+ final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
+ final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
+ final String VNF_REQUEST_ID = UUID.randomUUID().toString();
+
+
+ //push alacarte with 1 vnf, verify STATUS pending
+ UUID uuid = pushALaCarteWithVnf();
+ singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
+
+ //mock mso to answer 200 of create service instance request, verify STATUS in progress
+ when(restMso.PostForObject(any(), endsWith("serviceInstances"), eq(RequestReferencesContainer.class))).thenReturn(
+ createResponse(200, SERVICE_INSTANCE_ID, SERVICE_REQUEST_ID));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.PENDING, JobStatus.IN_PROGRESS, JobType.InProgressStatus);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+
+ //mock mso to answer COMPLETE for service instance create, job status shall remain IN_PROGRESS and type shall be Watching
+ reset(restMso);
+ when(restMso.GetForObject(endsWith(SERVICE_REQUEST_ID), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS, JobType.Watching);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+
+ //mock mso to answer 200 of create vnf instance request, pull+execute vnf job, STATUS resource in progress
+ reset(restMso);
+ when(restMso.PostForObject(any(), endsWith(SERVICE_INSTANCE_ID + "/vnfs"), eq(RequestReferencesContainer.class))).thenReturn(
+ createResponse(200, UUID.randomUUID().toString(), VNF_REQUEST_ID));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.CREATING, JobStatus.RESOURCE_IN_PROGRESS, JobType.VnfInProgressStatus);
+
+ //verify service job STATUS in progress
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS, JobType.Watching);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+
+ //mock mso to answer msoVnfStatus (COMPLETE/FAILED) for vnf creation status,
+ //job status shall be final (COMPLETE/COMPLETE_WITH_ERRORS)
+ reset(restMso);
+ when(restMso.GetForObject(endsWith(VNF_REQUEST_ID), eq(AsyncRequestStatus.class))).thenReturn(
+ asyncRequestStatusResponseAsRestObject(msoVnfStatus));
+ pullJobProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, expectedVnfStatus, false);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+ pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, expectedServiceStatus, true);
+ singleServicesAndAssertStatus(expectedServiceStatus, uuid);
+
+ }
+
+ /*
+ this test is almost duplication of testStatusesOfServiceDuringALaCarteLifeCycleIgnoringVfModules.
+
+ IgnoringVfModules test check the scenario while FLAG_ASYNC_ALACARTE_VFMODULE is off
+ WithVfModules test check the scenario while FLAG_ASYNC_ALACARTE_VFMODULE is on
+
+ We shall consider later to remove testStatusesOfServiceDuringALaCarteLifeCycleIgnoringVfModules
+ And union these tests to single one.
+ */
+
+ //@Test
+ public void testALaCarteLifeCycle1Vnf2VfModules() {
+
+
+ String msoVnfStatus = COMPLETE_STR;
+ JobStatus expectedServiceStatus = IN_PROGRESS;
+ JobStatus expectedVnfStatus = RESOURCE_IN_PROGRESS;
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
+ final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
+ final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
+ final String VNF_REQUEST_ID = UUID.randomUUID().toString();
+ final String VNF_INSTANCE_ID = UUID.randomUUID().toString();
+ final String VG_REQUEST_ID = UUID.randomUUID().toString();
+ final String VG_INSTANCE_ID = UUID.randomUUID().toString();
+ final String VF_MODULE_REQUEST_ID = UUID.randomUUID().toString();
+ final String VF_MODULE_REQUEST_ID2 = UUID.randomUUID().toString();
+
+
+ //push alacarte with 1 vnf, verify STATUS pending
+ UUID uuid = pushALaCarteWithVnf();
+ singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
+
+ /*---------- service -----------*/
+
+ //mock mso to answer 200 of create service instance request, verify STATUS in progress
+ when(restMso.PostForObject(any(), endsWith("serviceInstances"), eq(RequestReferencesContainer.class))).thenReturn(
+ createResponse(200, SERVICE_INSTANCE_ID, SERVICE_REQUEST_ID));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.PENDING, JobStatus.IN_PROGRESS, JobType.InProgressStatus);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+
+ //mock mso to answer COMPLETE for service instance create, job status shall remain IN_PROGRESS and type shall be Watching
+ reset(restMso);
+ when(restMso.GetForObject(endsWith(SERVICE_REQUEST_ID), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS, JobType.Watching);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+
+ /*---------- vnf -----------*/
+
+ //mock mso to answer 200 of create vnf instance request, pull+execute vnf job, STATUS resource in progress
+ reset(restMso);
+ when(restMso.PostForObject(any(), endsWith(SERVICE_INSTANCE_ID + "/vnfs"), eq(RequestReferencesContainer.class))).thenReturn(
+ createResponse(200, VNF_INSTANCE_ID, VNF_REQUEST_ID));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.CREATING, JobStatus.RESOURCE_IN_PROGRESS, JobType.VnfInProgressStatus);
+
+ //verify service job STATUS in progress
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS, JobType.Watching);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+
+ //mock mso to answer msoVnfStatus (COMPLETE/FAILED) for vnf creation status,
+ //job status shall be final (COMPLETE/COMPLETE_WITH_ERRORS)
+ reset(restMso);
+ when(restMso.GetForObject(endsWith(VNF_REQUEST_ID), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+
+ try {
+ reset(commandUtils);
+ when(commandUtils.isVfModuleBaseModule(SERVICE_MODEL_VERSION_ID, VF_MODULE_0_MODEL_VERSION_ID)).thenReturn(true);
+ when(commandUtils.isVfModuleBaseModule(SERVICE_MODEL_VERSION_ID, VF_MODULE_1_MODEL_VERSION_ID)).thenReturn(false);
+ } catch (AsdcCatalogException e) {
+
+ }
+
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.RESOURCE_IN_PROGRESS, JobStatus.RESOURCE_IN_PROGRESS, JobType.WatchingBaseModule);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+ pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS, true);
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+
+ /*---------- vf Module without volume group name (base) -----------*/
+
+ //vg name not exist, so vf module created immediately
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.CREATING, JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching);
+
+ //verify vnf/volumeGroup job STATUS still watching with resource in progress
+ pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching, JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching);
+
+ //mock mso to answer 200 of create vfModule instance request, pull+execute volumeGroup job, STATUS resource in progress
+ reset(restMso);
+ when(restMso.PostForObject(any(), endsWith(SERVICE_INSTANCE_ID + "/vnfs/" + VNF_INSTANCE_ID + "/vfModules"), eq(RequestReferencesContainer.class))).thenReturn(
+ createResponse(200, UUID.randomUUID().toString(), VF_MODULE_REQUEST_ID));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.CREATING, JobStatus.RESOURCE_IN_PROGRESS, JobType.ResourceInProgressStatus);
+
+ //mock mso to answer for vf module orchestration request
+ reset(restMso);
+ when(restMso.GetForObject(endsWith(VF_MODULE_REQUEST_ID), eq(AsyncRequestStatus.class))).thenReturn(
+ asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, JobType.ResourceInProgressStatus, JobStatus.COMPLETED, JobType.ResourceInProgressStatus);
+
+ //verify volume group become completed
+ pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching, JobStatus.COMPLETED, JobType.Watching);
+
+ //vnf become watching after volume group completed, and new volume group created
+ pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, JobType.WatchingBaseModule, JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching);
+
+ /*---------- volume group & vf module (non base) -----------*/
+
+ /*---------- volume group -----------*/
+
+ //mock mso to answer 200 of create volumeGroup instance request, pull+execute volumeGroup job, STATUS resource in progress
+ reset(restMso);
+ when(restMso.PostForObject(any(), endsWith(SERVICE_INSTANCE_ID + "/vnfs/" + VNF_INSTANCE_ID + "/volumeGroups"), eq(RequestReferencesContainer.class))).thenReturn(
+ createResponse(200, VG_INSTANCE_ID, VG_REQUEST_ID));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.CREATING, JobStatus.RESOURCE_IN_PROGRESS, JobType.VolumeGroupInProgressStatus);
+
+ //verify vnf job STATUS still watching with resource in progress
+ pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching, JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching);
+
+ //mock mso to answer for volume group orchestration request
+ reset(restMso);
+ when(restMso.GetForObject(endsWith(VG_REQUEST_ID), eq(AsyncRequestStatus.class))).thenReturn(
+ asyncRequestStatusResponseAsRestObject(msoVnfStatus));
+ pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, JobType.VolumeGroupInProgressStatus, JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching);
+
+ /*---------- vfModule -----------*/
+
+ //mock mso to answer 200 of create vfModule instance request, pull+execute volumeGroup job, STATUS resource in progress
+ reset(restMso);
+ when(restMso.PostForObject(any(), endsWith(SERVICE_INSTANCE_ID + "/vnfs/" + VNF_INSTANCE_ID + "/vfModules"), eq(RequestReferencesContainer.class))).thenReturn(
+ createResponse(200, UUID.randomUUID().toString(), VF_MODULE_REQUEST_ID2));
+ pullJobProcessAndPushBackWithTypeAssertion(JobStatus.CREATING, JobStatus.RESOURCE_IN_PROGRESS, JobType.ResourceInProgressStatus);
+
+ //mock mso to answer for vf module orchestration request
+ reset(restMso);
+ when(restMso.GetForObject(endsWith(VF_MODULE_REQUEST_ID2), eq(AsyncRequestStatus.class))).thenReturn(
+ asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus.RESOURCE_IN_PROGRESS, JobType.ResourceInProgressStatus, JobStatus.COMPLETED, JobType.ResourceInProgressStatus);
+
+ //execute twice - 1 for parent volume group, 1 for parent vnf
+ pullAllJobProcessAndPushBackByType(JobStatus.RESOURCE_IN_PROGRESS, JobType.Watching , JobStatus.COMPLETED);
+
+ singleServicesAndAssertStatus(JobStatus.IN_PROGRESS, uuid);
+ pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.COMPLETED, true);
+ singleServicesAndAssertStatus(JobStatus.COMPLETED, uuid);
+ }
+
+ //@Test
+ public void testBadAaiResponseForSearchNamesAndBackToNormal() {
+ when(aaiClient.isNodeTypeExistsByName(any(), any())).thenThrow(aaiNodeQueryBadResponseException());
+ pushMacroBulk(); //JOB shall become IN_PROGRESS but service info is still pending
+ Job job = pullJobProcessAndPushBack(PENDING, JobStatus.IN_PROGRESS, true);
+ listServicesAndAssertStatus(PENDING, PENDING, job);
+
+ //JOB shall remain in IN_PROGRESS
+ job = pullJobProcessAndPushBack( JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS, true);
+ //make sure the job command is still ServiceInstantiation
+ assertThat(job.getType(), is(JobType.MacroServiceInstantiation));
+ listServicesAndAssertStatus(PENDING, PENDING, job);
+
+ //simulate AAI back to normal, AAI return name is free, and MSO return good response
+ Mockito.reset(aaiClient); // must forget the "thenThrow"
+ when(aaiClient.isNodeTypeExistsByName(any(), any())).thenReturn(false);
+ when(restMso.PostForObject(any(),any(), eq(RequestReferencesContainer.class))).thenReturn(createResponse(200));
+ job = pullJobProcessAndPushBack( JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS, true);
+ listServicesAndAssertStatus(JobStatus.IN_PROGRESS, PENDING, job);
+
+ //when get job COMPLETE from MSO, service status become COMPLETED
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, COMPLETED);
+ listServicesAndAssertStatus(COMPLETED, PENDING, job);
+ }
+
+ //@Test
+ public void testAaiResponseNameUsedTillMaxRetries() {
+ when(aaiClient.isNodeTypeExistsByName(any(), any())).thenReturn(true);
+ asyncInstantiationBL.setMaxRetriesGettingFreeNameFromAai(10);
+ pushMacroBulk();
+ //JOB shall become IN_PROGRESS but service info is still pending
+ Job job = pullJobProcessAndPushBack(PENDING, JobStatus.FAILED, true);
+ listServicesAndAssertStatus(JobStatus.FAILED, JobStatus.STOPPED, job);
+ }
+
+ private Job pullJobProcessAndPushBack(JobStatus topic, JobStatus expectedNextJobStatus) {
+ return pullJobProcessAndPushBack(topic, expectedNextJobStatus, true);
+ }
+
+ //return the pulled job (and not the pushed job)
+ private Job pullJobProcessAndPushBack(JobStatus topic, JobStatus expectedNextJobStatus, boolean pullingAssertion) {
+ Optional<Job> job = pullJob(topic, pullingAssertion);
+
+ Job nextJob = jobWorker.executeJobAndGetNext(job.get());
+
+ try {
+ assertThat("next job not ok: " + nextJob.getData(), nextJob.getStatus(), is(expectedNextJobStatus));
+
+ if (pullingAssertion) {
+ //assert another pulling on same topic return no result (before push back)
+ assertFalse(jobsBrokerService.pull(topic, randomUuid()).isPresent());
+ }
+
+ } finally {
+ jobsBrokerService.pushBack(nextJob); // push back to let retries - even if any assertion failure
+ }
+ assertThat(jobsBrokerService.peek(job.get().getUuid()).getStatus(), is(expectedNextJobStatus));
+ return job.get();
+ }
+
+ private Job pullJobProcessAndPushBackWithTypeAssertion(JobStatus topic, JobStatus expectedNextJobStatus,
+ JobType expectedNextJobType) {
+ Job job = pullJobProcessAndPushBack(topic, expectedNextJobStatus, false);
+ assertThat("job not ok: " + job.getData(), job.getType(), is(expectedNextJobType));
+ return job;
+ }
+
+ private Job pullJobProcessAndPushBackWithTypeAssertion(JobStatus topic, JobStatus expectedNextJobStatus,
+ JobType expectedNextJobType, int retries) {
+ return retryWithAssertionsLimit(retries, () -> {
+ return pullJobProcessAndPushBackWithTypeAssertion(topic, expectedNextJobStatus, expectedNextJobType);
+ });
+ }
+
+ private Job pullJobProcessAndPushBackWithTypeAssertion(JobStatus topic, JobStatus expectedNextJobStatus,
+ JobType expectedNextJobType, Action actionPhase, InternalState internalState, int retries) {
+ return retryWithAssertionsLimit(retries, () -> {
+ Job job = pullJobProcessAndPushBackWithTypeAssertion(topic, expectedNextJobStatus, expectedNextJobType);
+ assertThat("job not ok: " + job.getData(), job.getData(), is(jsonPartEquals("actionPhase", actionPhase.name())));
+ if (internalState != null) {
+ assertThat("job not ok: " + job.getData(), job.getData(), is(jsonPartEquals("internalState", internalState.name())));
+ }
+ return job;
+ });
+ }
+
+ private Job retryWithAssertionsLimit(int retries, Supplier<Job> supplier) {
+ java.util.Stack<AssertionError> history = new Stack<>();
+
+ do {
+ try {
+ return supplier.get();
+ } catch (AssertionError assertionError) {
+ history.push(assertionError);
+ }
+ } while (history.size() < retries);
+
+ // No success:
+ throw new AssertionError("No luck while all of these assertion errors: " + history.stream()
+ .map(Throwable::getMessage)
+ .map(s -> s.replace('\n', ' '))
+ .map(s -> s.replaceAll("\\s{2,}"," "))
+ .distinct()
+ .collect(joining("\n ", "\n ", "")), history.peek());
+ }
+
+ private Job pullMultipleJobsFindExpectedProcessAndPushBack(JobStatus topic, JobType expectedCurrentJobType, JobStatus expectedNextJobStatus,
+ JobType expectedNextJobType) {
+ List<Job> pulledJobs = new ArrayList<>();
+ Job lastJob = null;
+ while (lastJob == null || lastJob.getType() != expectedCurrentJobType) {
+ lastJob = pullJob(topic, false).get();
+ if (lastJob.getType() != expectedCurrentJobType) {
+ pulledJobs.add(lastJob);
+ }
+ }
+
+ Job nextJob = jobWorker.executeJobAndGetNext(lastJob);
+ assertThat(nextJob.getStatus(), is(expectedNextJobStatus));
+ assertThat(nextJob.getType(), is(expectedNextJobType));
+
+ jobsBrokerService.pushBack(nextJob);
+ assertThat(jobsBrokerService.peek(nextJob.getUuid()).getStatus(), is(expectedNextJobStatus));
+
+ pulledJobs.forEach(job ->
+ jobsBrokerService.pushBack(job)
+ );
+
+ return nextJob;
+ }
+
+ private void pullAllJobProcessAndPushBackByType(JobStatus topic, JobType commandType, JobStatus expectedFinalStatus) {
+ Map<UUID, JobStatus> jobStatusMap = new HashMap<>();
+ Optional<Job> job = pullJob(topic, false);
+ for (int i=0; i<1000 && job.isPresent() && job.get().getType() == commandType; i++) {
+ Job nextJob = jobWorker.executeJobAndGetNext(job.get());
+ jobStatusMap.put(nextJob.getUuid(), nextJob.getStatus());
+ jobsBrokerService.pushBack(nextJob);
+ job = jobsBrokerService.pull(topic, UUID.randomUUID().toString());
+ }
+ assertThat(jobStatusMap.values(), everyItem(is(expectedFinalStatus)));
+
+ }
+
+ private Optional<Job> pullJob(JobStatus topic, boolean pullingAssertion) {
+ if (pullingAssertion) {
+ //assert pulling on inverse topic return no result
+ assertFalse(jobsBrokerService.pull(inverseTopic(topic), randomUuid()).isPresent());
+ }
+
+ Optional<Job> job = jobsBrokerService.pull(topic, randomUuid());
+ assertTrue("no job fetched", job.isPresent());
+
+ if (pullingAssertion) {
+ //assert another pulling on same topic return no result
+ assertFalse(jobsBrokerService.pull(topic, randomUuid()).isPresent());
+ }
+
+ return job;
+ }
+
+ private JobStatus inverseTopic(JobStatus topic) {
+ return topic==JobStatus.IN_PROGRESS ? PENDING : JobStatus.IN_PROGRESS;
+ }
+
+
+ //@Test
+ public void whenPushNewBulk_andGetNoResponseFromMsoOnCreation_thenServiceMoveToFailedAndOtherToStopped() {
+ when(restMso.PostForObject(any(), any(), eq(RequestReferencesContainer.class))).thenReturn(createResponse(500));
+ pushBulkPullPendingJobAndAssertJobStatus(JobStatus.FAILED, JobStatus.STOPPED);
+ }
+
+ //@Test
+ public void whenMsoStatusIsPendingManualTask_ThenJobStatusIsPaused() {
+ when(restMso.PostForObject(any(), any(), eq(RequestReferencesContainer.class))).thenReturn(createResponse(200));
+
+ Job firstJob = pushBulkPullPendingJobAndAssertJobStatus(JobStatus.IN_PROGRESS, PENDING);
+
+ //assert that when get ProcessingException from restMso, status remain the same
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(PENDING_MANUAL_TASK));
+ Job job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS);
+ listServicesAndAssertStatus(PAUSE, PENDING, job);
+
+ //The paused job is pulled and remain in pause state. Other jobs from bulk remain pending
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS);
+ listServicesAndAssertStatus(PAUSE, PENDING, job);
+
+ //the job get IN_PROGRESS response (simulate activate operation) and status changed to IN_PROGRESS
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(IN_PROGRESS_STR));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.IN_PROGRESS);
+ listServicesAndAssertStatus(JobStatus.IN_PROGRESS, PENDING, job);
+
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ job = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, COMPLETED);
+ listServicesAndAssertStatus(COMPLETED, PENDING, job);
+
+ //Pulling PENDING job return another job
+ assertThat(jobsBrokerService.pull(PENDING, randomUuid()).get().getUuid(), not(equalTo(job.getUuid())));
+
+
+ ImmutableList<String> expectedStatusesForMso = ImmutableList.of(REQUESTED, PENDING_MANUAL_TASK, IN_PROGRESS_STR, COMPLETE_STR);
+ List<String> msoStatuses = asyncInstantiationBL.getAuditStatuses(firstJob.getUuid(), MSO).stream().map(x -> x.getJobStatus()).collect(Collectors.toList());
+ assertThat(msoStatuses, is(expectedStatusesForMso));
+
+ ImmutableList<String> expectedStatusesForVid = statusesToStrings(PENDING, IN_PROGRESS, PAUSE, IN_PROGRESS, COMPLETED);
+ List<String> vidStatuses = asyncInstantiationBL.getAuditStatuses(firstJob.getUuid(), VID).stream().map(x -> x.getJobStatus()).collect(Collectors.toList());
+ assertThat(vidStatuses, is(expectedStatusesForVid));
+ }
+
+ private Job pushBulkPullPendingJobAndAssertJobStatus(JobStatus pulledJobStatus, JobStatus otherJobsStatus) {
+ pushMacroBulk();
+ return pullPendingJobAndAssertJobStatus(pulledJobStatus, otherJobsStatus);
+ }
+
+ private Job pullPendingJobAndAssertJobStatus(JobStatus pulledJobStatus, JobStatus otherJobsStatus) {
+ Job job = pullJobProcessAndPushBack(PENDING, pulledJobStatus, false);
+ listServicesAndAssertStatus(pulledJobStatus, otherJobsStatus, job);
+ return job;
+ }
+
+ //@Test
+ public void test2BulksLifeCyclesAreIndependent() {
+ pushMacroBulk();
+ when(restMso.PostForObject(any(), any(), eq(RequestReferencesContainer.class))).thenReturn(createResponse(200));
+ //push 2nd job, then when pulling first job the job become in_progress, other jobs (from 2 bulks) remain pending
+ Job firstJob = pushBulkPullPendingJobAndAssertJobStatus(JobStatus.IN_PROGRESS, PENDING);
+
+ //assert we can pull another job from pending from other template id
+ Job secondJob = pullJobProcessAndPushBack(PENDING, JobStatus.IN_PROGRESS, false);
+ assertThat(firstJob.getTemplateId(), not(equalTo(secondJob.getTemplateId())));
+
+ //assert no more PENDING jobs to pull
+ assertFalse(jobsBrokerService.pull(PENDING, randomUuid()).isPresent());
+
+ //when get FAILED status from MSO statuses for failed bulk are: FAILED, STOPPED, for other bulk: IN_PROGRESS, 2 pending
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(FAILED_STR));
+ Job failedJob = pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, JobStatus.FAILED, false);
+ Map<UUID, List<ServiceInfo>> servicesByTemplateId =
+ asyncInstantiationBL.getAllServicesInfo()
+ .stream().collect(groupingBy(ServiceInfo::getTemplateId));
+ assertServicesStatus(servicesByTemplateId.get(failedJob.getTemplateId()), JobStatus.FAILED, JobStatus.STOPPED, failedJob);
+ Job successJob = failedJob.getUuid().equals(firstJob.getUuid()) ? secondJob : firstJob;
+ assertServicesStatus(servicesByTemplateId.get(successJob.getTemplateId()), JobStatus.IN_PROGRESS, PENDING, successJob);
+
+ //yet no more PENDING jobs to pull
+ assertFalse(jobsBrokerService.pull(PENDING, randomUuid()).isPresent());
+
+ //assert that job from non failed bulk can progress.
+ //When completed, failed bulk statuses: FAILED, STOPPED. Succeeded bulk statuses are : COMPLETED, 2 pending
+ when(restMso.GetForObject(any(), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+ pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, COMPLETED, false);
+ servicesByTemplateId =
+ asyncInstantiationBL.getAllServicesInfo()
+ .stream().collect(groupingBy(ServiceInfo::getTemplateId));
+ assertServicesStatus(servicesByTemplateId.get(failedJob.getTemplateId()), JobStatus.FAILED, JobStatus.STOPPED, failedJob);
+ assertServicesStatus(servicesByTemplateId.get(successJob.getTemplateId()), COMPLETED, PENDING, successJob);
+
+ //advance other jobs of succeeded bulk till al of them reach to COMPLETED
+ pullJobProcessAndPushBack(PENDING, JobStatus.IN_PROGRESS, false);
+ pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, COMPLETED, false);
+ pullJobProcessAndPushBack(PENDING, JobStatus.IN_PROGRESS, false);
+ pullJobProcessAndPushBack(JobStatus.IN_PROGRESS, COMPLETED, false);
+ servicesByTemplateId =
+ asyncInstantiationBL.getAllServicesInfo()
+ .stream().collect(groupingBy(ServiceInfo::getTemplateId));
+ assertServicesStatus(servicesByTemplateId.get(failedJob.getTemplateId()), JobStatus.FAILED, JobStatus.STOPPED, failedJob);
+ assertServicesStatus(servicesByTemplateId.get(successJob.getTemplateId()), COMPLETED, COMPLETED, successJob);
+
+ //assert no more PENDING jobs nor IN_PROGRESS jobs to pull
+ assertFalse(jobsBrokerService.pull(PENDING, randomUuid()).isPresent());
+ assertFalse(jobsBrokerService.pull(JobStatus.IN_PROGRESS, randomUuid()).isPresent());
+ }
+
+ public void deploy2NewGroupsToServiceWith1ExistingGroup() {
+
+ /*
+ new feature: skip service (existing impl) and skip group (new impl)
+ service+group aren't touched, 2 groups ARE created
+
+ [v] success if all GROUPs success
+
+ Next test variation should:
+ [ ] error if all GROUPs error
+ [ ] completed with error if 1 GROUP error
+
+
+ [v] + service with 3 groups - 1 action=none, 2 action=create; service's action=none
+ [v] verify STATUS pending
+ [v] + pull+execute (should NOT post to MSO)
+ [v] verify STATUS in progress; TYPE watching
+ ...
+ [v] verify job#2 *new* GROUP job STATUS completed with no action TYPE group INTERNAL STATE terminal PHASE delete
+ [v] verify job#3 *new* GROUP job STATUS completed with no action TYPE group INTERNAL STATE terminal PHASE delete
+ [v] verify job#4 *new* GROUP job STATUS completed with no action TYPE group INTERNAL STATE terminal PHASE delete
+
+ [v] + pull+execute job#1 (should NOT post to MSO)
+ [v] verify STATUS in progress; TYPE watching
+ [v] verify job#5 *new* GROUP job STATUS creating TYPE group INTERNAL STATE initial PHASE create
+ [v] verify job#6 *new* GROUP job STATUS creating TYPE group INTERNAL STATE initial PHASE create
+ [v] verify job#7 *new* GROUP job STATUS creating TYPE group INTERNAL STATE initial PHASE create
+
+ [v] + pull+execute job#5 (should NOT post to MSO)
+ [v] verify job#5 STATUS completed with no action TYPE group INTERNAL STATE terminal PHASE create
+ [v] + pull+execute job#1
+ [v] verify job#1 STATUS in progress; TYPE watching
+
+ [v] + pull+execute job#6 (should post to MSO)
+ [v] verify job#6 STATUS resource in progress
+ [v] + pull+execute job#1
+ [v] verify job#1 STATUS in progress; TYPE watching
+ [v] + pull+execute job#6 (should get from MSO)
+ [v] verify job#6 STATUS completed
+ [v] + pull+execute job#1
+ [v] verify job#1 STATUS in progress; TYPE watching
+
+ [v] + pull+execute job#7 (should post to MSO)
+ [v] verify job#7 STATUS resource in progress
+ [v] + pull+execute job#1
+ [v] verify job#1 STATUS in progress; TYPE watching
+ [v] + pull+execute job#7 (should get from MSO)
+ [v] verify job#7 STATUS completed
+ [v] + pull+execute job#1
+ [v] verify job#1 STATUS completed
+
+ */
+
+ final String GROUP1_REQUEST_ID = UUID.randomUUID().toString();
+ final String GROUP1_INSTANCE_ID = UUID.randomUUID().toString();
+ final String GROUP2_REQUEST_ID = UUID.randomUUID().toString();
+ final String GROUP2_INSTANCE_ID = UUID.randomUUID().toString();
+
+ // Utility method
+ final BiConsumer<Action, JobStatus> verify_Job1InProgress = (phase, nextJobStatus) -> {
+ pullJobProcessAndPushBackWithTypeAssertion(IN_PROGRESS, nextJobStatus, JobType.ALaCarteService, phase, InternalState.WATCHING, 2);
+ };
+
+ //service with 3 groups - 1 action=none, 2 action=create; service's action=none
+ UUID uuid = pushALaCarteUpdateWithGroups();
+ singleServicesAndAssertStatus(PENDING, uuid);
+
+ // take from pending, put in-progress -> 3 delete-child were born
+ pullJobProcessAndPushBackWithTypeAssertion(PENDING, IN_PROGRESS, JobType.ALaCarteService, Action.Delete, InternalState.WATCHING, 1);
+ verifyQueueSizes(ImmutableMap.of(
+ IN_PROGRESS, 1, CREATING, 3
+ ));
+
+ Stream.of(1, 2, 3).forEach(i -> {
+ // take each child creating, put in-progress
+ verify_Job1InProgress.accept(Action.Delete, IN_PROGRESS);
+ pullJobProcessAndPushBackWithTypeAssertion(CREATING, RESOURCE_IN_PROGRESS, JobType.InstanceGroup, Action.Delete, null, 1);
+
+ // execute each in-progress -> job is completed
+ verify_Job1InProgress.accept(Action.Delete, IN_PROGRESS);
+ pullJobProcessAndPushBackWithTypeAssertion(RESOURCE_IN_PROGRESS, COMPLETED/*_WITH_NO_ACTION*/, JobType.InstanceGroup,1);
+ });
+ verifyQueueSizes(ImmutableMap.of(
+ IN_PROGRESS, 1, COMPLETED, 3
+ ));
+
+ // take job #1 from phase delete to phase create -> 3 create-child were born
+ verify_Job1InProgress.accept(Action.Create, IN_PROGRESS);
+ verifyQueueSizes(ImmutableMap.of(
+ IN_PROGRESS, 1, CREATING, 3, COMPLETED, 3
+ ));
+
+ // prepare MSO mock
+ when(restMso.PostForObject(any(), endsWith("instanceGroups"), eq(RequestReferencesContainer.class)))
+ .thenReturn(createResponse(200, GROUP1_INSTANCE_ID, GROUP1_REQUEST_ID))
+ .thenReturn(createResponse(200, GROUP2_INSTANCE_ID, GROUP2_REQUEST_ID))
+ .thenReturn(null);
+ when(restMso.GetForObject(argThat(uri -> StringUtils.endsWithAny(uri, GROUP1_REQUEST_ID, GROUP2_REQUEST_ID)), eq(AsyncRequestStatus.class))).
+ thenReturn(asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
+
+ // take first "none" child from creating to completed
+ // note there's no concrete mechanism that makes the first child be
+ // the "action=None" case, but that's what happens, and following line
+ // relies on that fact.
+ pullJobProcessAndPushBackWithTypeAssertion(CREATING, COMPLETED_WITH_NO_ACTION, JobType.InstanceGroupInstantiation, 1);
+
+ // take each of next two children from creating to in-progress, then to completed
+ // verify job #1 is watching, and MSO is getting requests
+ Stream.of(1, 2).forEach(i -> {
+ verify_Job1InProgress.accept(Action.Create, IN_PROGRESS);
+ pullJobProcessAndPushBackWithTypeAssertion(CREATING, RESOURCE_IN_PROGRESS, JobType.ResourceInProgressStatus);
+ verify(restMso, times(i)).PostForObject(any(), any(), any());
+
+ verify_Job1InProgress.accept(Action.Create, IN_PROGRESS);
+ pullJobProcessAndPushBackWithTypeAssertion(RESOURCE_IN_PROGRESS, COMPLETED, JobType.ResourceInProgressStatus);
+ verify(restMso, times(i)).GetForObject(any(), any());
+ });
+
+ // job #1 is done as all children are done
+ verify_Job1InProgress.accept(Action.Create, COMPLETED);
+ verifyQueueSizes(ImmutableMap.of(COMPLETED, 7));
+ }
+
+ private void verifyQueueSizes(ImmutableMap<JobStatus, Integer> expected) {
+ final Collection<Job> peek = jobsBrokerService.peek();
+ final Map<JobStatus, Long> jobTypes = peek.stream().collect(groupingBy(Job::getStatus, counting()));
+ assertThat(jobTypes, is(expected));
+ }
+
+ private List<ServiceInfo> listServicesAndAssertStatus(JobStatus pulledJobStatus, JobStatus otherJobsStatus, Job job) {
+ List<ServiceInfo> serviceInfoList = asyncInstantiationBL.getAllServicesInfo();
+ assertServicesStatus(serviceInfoList, pulledJobStatus, otherJobsStatus, job);
+
+ return serviceInfoList;
+ }
+
+ private ServiceInfo singleServicesAndAssertStatus(JobStatus expectedStatus, UUID jobUUID) {
+ List<ServiceInfo> serviceInfoList = asyncInstantiationBL.getAllServicesInfo();
+ assertEquals(1, serviceInfoList.size());
+ ServiceInfo serviceInfo = serviceInfoList.get(0);
+ assertThat(serviceInfo.getJobStatus(), is(expectedStatus));
+ assertThat(serviceInfo.getJobId(), is(jobUUID));
+ return serviceInfo;
+ }
+
+ private void assertServicesStatus(List<ServiceInfo> serviceInfoList, JobStatus pulledJobStatus, JobStatus otherJobsStatus, Job job) {
+ serviceInfoList.forEach(si->{
+ if (si.getJobId().equals(job.getUuid())) {
+ assertThat(si.getJobStatus(), is(pulledJobStatus));
+ }
+ else {
+ assertThat(si.getJobStatus(), is(otherJobsStatus));
+ }
+ });
+ }
+
+ private void listServicesAndAssertStatus(Map<UUID, JobStatus> expectedJobStatusMap) {
+ Map<UUID, JobStatus> actualStatuses = asyncInstantiationBL.getAllServicesInfo()
+ .stream().collect(Collectors.toMap(ServiceInfo::getJobId, ServiceInfo::getJobStatus));
+ assertThat(actualStatuses.entrySet(), equalTo(expectedJobStatusMap.entrySet()));
+ }
+
+ private String randomUuid() {
+ return UUID.randomUUID().toString();
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterImplTest.java b/vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterImplTest.java
deleted file mode 100644
index dc2eafc9b..000000000
--- a/vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterImplTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2018 Nokia Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.job.impl;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import org.mockito.Mock;
-import org.onap.vid.job.Job;
-import org.onap.vid.job.JobAdapter;
-import org.onap.vid.job.JobType;
-import org.onap.vid.model.JobBulk;
-import org.onap.vid.model.JobModel;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.Stream;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-public class JobAdapterImplTest {
-
-
- private static final int SAMPLE_INDEX = 10;
- private static final String SAMPLE_USER_ID = "sampleUserId";
-
- @Mock
- private Job job;
-
- @Mock
- private JobAdapter.AsyncJobRequest asyncJobRequest;
-
- private UUID sampleUuid=UUID.randomUUID();
-
- private JobAdapterImpl jobAdapter = new JobAdapterImpl();
-
- @BeforeMethod
- public void setUp() {
- initMocks(this);
-
- when(job.getUuid()).thenReturn(sampleUuid);
- when(job.getStatus()).thenReturn(Job.JobStatus.IN_PROGRESS);
- when(job.getTemplateId()).thenReturn(sampleUuid);
- }
-
- @Test
- public void shouldConvertJobToJobModel() {
-
-
- JobModel convertedJob = jobAdapter.toModel(job);
-
- assertThat(convertedJob.getUuid()).isEqualByComparingTo(sampleUuid);
- assertThat(convertedJob.getStatus()).isEqualByComparingTo(Job.JobStatus.IN_PROGRESS);
- assertThat(convertedJob.getTemplateId()).isEqualByComparingTo(sampleUuid);
- }
-
-
- @Test
- public void shouldProperlyCreateJob() {
- UUID uuid = UUID.randomUUID();
-
- Job createdJob = jobAdapter.createJob(JobType.ServiceInstantiation, asyncJobRequest, uuid, SAMPLE_USER_ID, SAMPLE_INDEX);
-
- assertThat(createdJob.getStatus()).isEqualByComparingTo(Job.JobStatus.PENDING);
- assertThat(createdJob.getTemplateId()).isEqualByComparingTo(uuid);
- assertThat(createdJob.getType()).isEqualByComparingTo(JobType.ServiceInstantiation);
- assertThat(createdJob.getData()).isEqualTo(ImmutableMap.of("request", asyncJobRequest, "userId", SAMPLE_USER_ID));
- }
-
- @Test
- public void shouldProperlyCreateBulkOfJobs(){
- List<Job> bulkOfJobs = jobAdapter.createBulkOfJobs(ImmutableMap.of("count", 5, "type", JobType.InProgressStatus.name()));
-
-
- assertThat(bulkOfJobs).hasSize(5);
-
- Stream<Job> jobStream = bulkOfJobs.stream().filter(x -> JobType.InProgressStatus.equals(x.getType()) && Job.JobStatus.PENDING.equals(x.getStatus()));
-
- assertThat(jobStream).hasSize(5);
- }
-
-
- @Test
- public void shouldConvertListToBulkJob(){
- JobBulk jobBulk = jobAdapter.toModelBulk(ImmutableList.of(job, job));
-
- assertThat(jobBulk.getJobs()).hasSize(2);
- }
-}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterTest.java b/vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterTest.java
new file mode 100644
index 000000000..95228476b
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/impl/JobAdapterTest.java
@@ -0,0 +1,100 @@
+package org.onap.vid.job.impl;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.RandomUtils;
+import org.onap.vid.job.Job;
+import org.onap.vid.job.JobAdapter;
+import org.onap.vid.job.JobType;
+import org.onap.vid.job.command.JobCommandFactoryTest;
+import org.testng.annotations.Test;
+
+import java.util.UUID;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+
+public class JobAdapterTest {
+
+ @Test
+ public void testCreateServiceInstantiationJob() {
+ JobAdapter jobAdapter = new JobAdapterImpl();
+
+ JobType jobType = JobType.NoOp;
+ JobAdapter.AsyncJobRequest request = new JobCommandFactoryTest.MockedRequest(42,"nothing");
+ UUID templateId = UUID.randomUUID();
+ String userId = "ou012t";
+ String optimisticUniqueServiceInstanceName = "optimisticUniqueServiceInstanceName";
+ int indexInBulk = RandomUtils.nextInt();
+ Job job = jobAdapter.createServiceInstantiationJob(
+ jobType,
+ request,
+ templateId,
+ userId,
+ optimisticUniqueServiceInstanceName,
+ indexInBulk
+ );
+
+ assertEquals(job.getType(), jobType);
+ assertEquals(job.getSharedData().getRequest(), request);
+ assertEquals(job.getSharedData().getRequestType(), request.getClass());
+ assertEquals(job.getSharedData().getUserId(), userId);
+ assertEquals(job.getSharedData().getJobUuid(), job.getUuid());
+ assertEquals(job.getSharedData().getRootJobId(), job.getUuid());
+ assertNotNull(job.getUuid());
+ assertEquals(job.getTemplateId(), templateId);
+ assertEquals(job.getData().get("optimisticUniqueServiceInstanceName"), optimisticUniqueServiceInstanceName);
+ assertEquals((int)job.getIndexInBulk(), indexInBulk );
+ assertEquals(job.getStatus(), Job.JobStatus.PENDING);
+ }
+
+ @Test
+ public void testCreateChildJob() {
+
+ JobAdapter jobAdapter = new JobAdapterImpl();
+
+ UUID templateId = UUID.randomUUID();
+ String userId = "ou012t";
+ String optimisticUniqueServiceInstanceName = "optimisticUniqueServiceInstanceName";
+ int indexInBulk = RandomUtils.nextInt();
+ Job grandJob = jobAdapter.createServiceInstantiationJob(
+ JobType.HttpCall,
+ new JobCommandFactoryTest.MockedRequest(99, "anything"),
+ templateId,
+ userId,
+ optimisticUniqueServiceInstanceName,
+ indexInBulk
+ );
+
+ Job.JobStatus jobStatus = Job.JobStatus.PAUSE;
+ JobType jobType = JobType.NoOp;
+ JobAdapter.AsyncJobRequest request = new JobCommandFactoryTest.MockedRequest(42,"nothing");
+ Job parentJob = jobAdapter.createChildJob(jobType, jobStatus, request, grandJob.getSharedData(), ImmutableMap.of());
+
+ assertEquals(parentJob.getType(), jobType);
+ assertEquals(parentJob.getSharedData().getRequest(), request);
+ assertEquals(parentJob.getSharedData().getRequestType(), request.getClass());
+ assertEquals(parentJob.getSharedData().getUserId(), userId);
+ assertEquals(parentJob.getSharedData().getJobUuid(), parentJob.getUuid());
+ assertNotNull(parentJob.getUuid());
+ assertNotEquals(parentJob.getUuid(), grandJob.getUuid());
+ assertEquals(parentJob.getStatus(), jobStatus);
+ assertEquals(parentJob.getSharedData().getRootJobId(), grandJob.getUuid());
+
+ Job.JobStatus jobStatus2 = Job.JobStatus.IN_PROGRESS;
+ JobType jobType2 = JobType.AggregateState;
+ JobAdapter.AsyncJobRequest request2 = new JobCommandFactoryTest.MockedRequest(66,"abc");
+ Job job = jobAdapter.createChildJob(jobType2, jobStatus2, request2, parentJob.getSharedData(), ImmutableMap.of());
+
+ assertEquals(job.getType(), jobType2);
+ assertEquals(job.getSharedData().getRequest(), request2);
+ assertEquals(job.getSharedData().getRequestType(), request2.getClass());
+ assertEquals(job.getSharedData().getUserId(), userId);
+ assertEquals(job.getSharedData().getJobUuid(), job.getUuid());
+ assertNotNull(job.getUuid());
+ assertNotEquals(job.getUuid(), parentJob.getUuid());
+ assertEquals(job.getStatus(), jobStatus2);
+ assertEquals(job.getSharedData().getRootJobId(), grandJob.getUuid());
+
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/impl/JobSchedulerInitializerTest.java b/vid-app-common/src/test/java/org/onap/vid/job/impl/JobSchedulerInitializerTest.java
deleted file mode 100644
index 93afd1709..000000000
--- a/vid-app-common/src/test/java/org/onap/vid/job/impl/JobSchedulerInitializerTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2018 Nokia Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.job.impl;
-
-
-import org.mockito.ArgumentCaptor;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.onap.vid.job.JobsBrokerService;
-import org.onap.vid.job.command.JobCommandFactory;
-import org.onap.vid.properties.Features;
-import org.quartz.JobDetail;
-import org.quartz.Scheduler;
-import org.quartz.SchedulerException;
-import org.quartz.Trigger;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.togglz.core.manager.FeatureManager;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-public class JobSchedulerInitializerTest {
-
- @Mock
- private JobsBrokerService brokerService;
-
- @Mock
- private SchedulerFactoryBean schedulerFactoryBean;
-
- @Mock
- private FeatureManager featureManager;
-
- @Mock
- private JobCommandFactory commandFactory;
-
- @Mock
- private Scheduler scheduler;
-
- @InjectMocks
- private JobSchedulerInitializer jobSchedulerInitializer;
-
- @BeforeMethod
- public void setUp() {
- initMocks(this);
- }
-
-
- @Test
- public void shouldNotInitializeSchedulerWhenAsyncJobsAreDisabled() {
- when(featureManager.isActive(Features.FLAG_ASYNC_JOBS)).thenReturn(false);
-
- jobSchedulerInitializer.init();
-
- verifyZeroInteractions(schedulerFactoryBean);
- }
-
-
- @Test
- public void shouldInitializeSchedulerWhenAsyncJobsAreEnabled() throws SchedulerException {
- ArgumentCaptor<JobDetail> jobDetailArgumentCaptor = ArgumentCaptor.forClass(JobDetail.class);
- ArgumentCaptor<Trigger> triggerArgumentCaptor = ArgumentCaptor.forClass(Trigger.class);
- when(featureManager.isActive(Features.FLAG_ASYNC_JOBS)).thenReturn(true);
- when(schedulerFactoryBean.getScheduler()).thenReturn(scheduler);
-
- jobSchedulerInitializer.init();
-
- verify(scheduler, times(2)).scheduleJob(jobDetailArgumentCaptor.capture(), triggerArgumentCaptor.capture());
-
- List<Object> topics = extractTopics(jobDetailArgumentCaptor);
-
- List<String> descriptions = extractDescription(triggerArgumentCaptor);
-
- assertThat(topics, containsInAnyOrder(org.onap.vid.job.Job.JobStatus.IN_PROGRESS, org.onap.vid.job.Job.JobStatus.PENDING));
- assertThat(descriptions, containsInAnyOrder("Trigger to run async worker for PENDING", "Trigger to run async worker for IN_PROGRESS"));
- }
-
- private List<Object> extractTopics(ArgumentCaptor<JobDetail> jobDetailArgumentCaptor) {
- return jobDetailArgumentCaptor
- .getAllValues()
- .stream()
- .map(JobDetail::getJobDataMap)
- .map(x -> x.get("topic"))
- .collect(Collectors.toList());
- }
-
- private List<String> extractDescription(ArgumentCaptor<Trigger> triggerArgumentCaptor) {
- return triggerArgumentCaptor
- .getAllValues()
- .stream()
- .map(Trigger::getDescription)
- .collect(Collectors.toList());
- }
-} \ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/impl/JobWorkerTest.java b/vid-app-common/src/test/java/org/onap/vid/job/impl/JobWorkerTest.java
index e58b6ba03..3ff324d61 100644
--- a/vid-app-common/src/test/java/org/onap/vid/job/impl/JobWorkerTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/job/impl/JobWorkerTest.java
@@ -19,7 +19,7 @@ import java.util.UUID;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
-import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -47,12 +47,13 @@ public class JobWorkerTest {
public final String foobar = "aux";
};
- originalType = JobType.ServiceInstantiation;
- jobUnderTest = new JobAdapterImpl().createJob(
+ originalType = JobType.MacroServiceInstantiation;
+ jobUnderTest = new JobAdapterImpl().createServiceInstantiationJob(
originalType,
originalData,
UUID.randomUUID(),
"my user id",
+ "optimisticUniqueServiceInstanceName",
RandomUtils.nextInt()
);
}
@@ -62,7 +63,7 @@ public class JobWorkerTest {
assertNextJobAfterExecuteJob(null, new String[]{"status"}, allOf(
hasProperty("status", is(Job.JobStatus.STOPPED)),
- hasProperty("data", hasEntry("request", originalData)),
+ hasProperty("sharedData", hasProperty("request", is(originalData))),
hasProperty("type", is(originalType)))
);
}