Merge from ECOMP's repository
[vid.git] / vid-automation / src / test / java / org / onap / vid / api / AsyncInstantiationApiTest.java
1 package org.onap.vid.api;
2
3 import com.google.common.collect.ImmutableList;
4 import com.google.common.collect.ImmutableSet;
5 import net.bytebuddy.utility.RandomString;
6 import net.javacrumbs.jsonunit.JsonAssert;
7 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
8 import org.apache.commons.lang3.builder.ToStringStyle;
9 import org.hamcrest.BaseMatcher;
10 import org.hamcrest.CoreMatchers;
11 import org.hamcrest.Description;
12 import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
13 import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
14 import org.onap.simulator.presetGenerator.presets.aai.PresetAAISearchNodeQueryEmptyResult;
15 import org.onap.simulator.presetGenerator.presets.ecompportal_att.PresetGetSessionSlotCheckIntervalGet;
16 import org.onap.simulator.presetGenerator.presets.mso.*;
17 import org.onap.vid.model.asyncInstantiation.JobAuditStatus;
18 import org.onap.vid.model.asyncInstantiation.ServiceInfo;
19 import org.onap.vid.model.mso.MsoResponseWrapper2;
20 import org.springframework.core.ParameterizedTypeReference;
21 import org.springframework.http.HttpStatus;
22 import org.springframework.http.ResponseEntity;
23 import org.springframework.web.client.HttpClientErrorException;
24 import org.springframework.web.client.RestTemplate;
25 import org.testng.Assert;
26 import org.testng.annotations.DataProvider;
27 import org.testng.annotations.Test;
28 import vid.automation.test.infra.FeatureTogglingTest;
29 import vid.automation.test.infra.Features;
30 import vid.automation.test.infra.Wait;
31 import vid.automation.test.model.JobStatus;
32 import vid.automation.test.services.SimulatorApi;
33
34 import java.util.*;
35 import java.util.function.Predicate;
36 import java.util.stream.Collectors;
37 import java.util.stream.IntStream;
38 import java.util.stream.Stream;
39
40 import static java.lang.Boolean.FALSE;
41 import static java.lang.Boolean.TRUE;
42 import static java.util.stream.Collectors.*;
43 import static org.hamcrest.CoreMatchers.*;
44 import static org.hamcrest.MatcherAssert.assertThat;
45 import static org.hamcrest.Matchers.hasProperty;
46 import static org.hamcrest.Matchers.hasSize;
47 import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys;
48 import static org.testng.Assert.assertNotNull;
49 import static org.testng.AssertJUnit.assertTrue;
50
51 @FeatureTogglingTest({Features.FLAG_ASYNC_JOBS, Features.FLAG_ASYNC_INSTANTIATION})
52 public class AsyncInstantiationApiTest extends BaseMsoApiTest {
53
54     private static final String CREATE_BULK_OF_MACRO_REQUEST = "asyncInstantiation/vidRequestCreateBulkOfMacro.json";
55
56     @DataProvider
57     public static Object[][] trueAndFalse() {
58             return new Object[][]{{TRUE},{FALSE}};
59     }
60
61     private String getCreateBulkUri() {
62         return uri.toASCIIString() + "/asyncInstantiation/bulk";
63     }
64
65     private String getHideServiceUri(String jobId) {
66         return uri.toASCIIString() + "/asyncInstantiation/hide/"+jobId;
67     }
68
69     private String getServiceInfoUrl() {
70         return uri.toASCIIString() + "/asyncInstantiation";
71     }
72
73     private String getJobAuditUrl() {
74         return uri.toASCIIString() + "/asyncInstantiation/auditStatus/{JOB_ID}?source={SOURCE}";
75     }
76
77     private String getDeleteServiceUrl(String uuid) {
78         return uri.toASCIIString() + "/asyncInstantiation/job/" + uuid;
79     }
80
81     public static class JobIdAndStatusMatcher extends BaseMatcher<ServiceInfo> {
82         private String expectedJobId;
83
84         public JobIdAndStatusMatcher(String expectedJobId) {
85             this.expectedJobId = expectedJobId;
86         }
87
88         @Override
89         public boolean matches(Object item) {
90             if (!(item instanceof ServiceInfo)) {
91                 return false;
92             }
93             ServiceInfo serviceInfo = (ServiceInfo) item;
94             return expectedJobId.equals(serviceInfo.jobId);
95         }
96
97         @Override
98         public void describeTo(Description description) {
99             description.appendText("failed to find job with uuid ")
100                     .appendValue(expectedJobId);
101         }
102     }
103
104
105
106     @Test
107     public void createBulkOfCreateInstances(){
108         Map<Keys, String> names = generateNames();
109         final int bulkSize = 3;
110         ImmutableList<BasePreset> presets = addPresetsForCreateBulkOfCreateInstances(bulkSize, names);
111         createBulkOfInstancesAndAssert(presets, false, bulkSize, JobStatus.COMPLETED, names);
112     }
113
114     private Map<Keys,String> generateNames() {
115         return Stream.of(Keys.values()).collect(
116                 Collectors.toMap(x->x, x -> UUID.randomUUID().toString().replace("-","")));
117     }
118
119     private ImmutableList<BasePreset> addPresetsForCreateBulkOfCreateInstances(int bulkSize, Map<Keys, String> names){
120         ImmutableList<BasePreset> msoBulkPresets = IntStream.rangeClosed(1,bulkSize).
121                 mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i))
122                 .collect(ImmutableList.toImmutableList());
123         ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
124                 .add(new PresetGetSessionSlotCheckIntervalGet())
125                 .add(new PresetAAIGetSubscribersGet())
126                 .add(new PresetAAISearchNodeQueryEmptyResult())
127                 .addAll(msoBulkPresets)
128                 .add(new PresetMSOOrchestrationRequestGet())
129                 .build();
130         return presets;
131
132     }
133
134     private ResponseEntity<List<JobAuditStatus>> auditStatusCall(String url) {
135         return restTemplate.exchange(
136                 url,
137                 org.springframework.http.HttpMethod.GET,
138                 null,
139                 new ParameterizedTypeReference<List<JobAuditStatus>>() {});
140     }
141
142     @DataProvider
143     public static Object[][] auditSources() {
144         return new Object[][]{{JobAuditStatus.SourceStatus.VID},{JobAuditStatus.SourceStatus.MSO}};
145     }
146
147
148     @Test(dataProvider = "auditSources")
149    public void getAuditStatus_nonExistingJobId_returnsEmptyList(JobAuditStatus.SourceStatus source){
150        List<JobAuditStatus> audits = getAuditStatuses(UUID.randomUUID().toString(), source.name());
151        Assert.assertEquals(audits.size(),0);
152    }
153
154     @Test(expectedExceptions = HttpClientErrorException.class)
155     public void getAuditStatus_nonExistingSource_returnsError() {
156         try {
157             getAuditStatuses(UUID.randomUUID().toString(), new RandomString(8).nextString());
158         } catch (HttpClientErrorException e) {
159             Assert.assertEquals(e.getResponseBodyAsString(),"The parameter source must have a value among : MSO, VID");
160             assertThat(e.getStatusCode(), is(HttpStatus.BAD_REQUEST));
161             throw e;
162         }
163     }
164
165     @Test()
166     public void simulateBulkRequest_getAuditStatus_auditStatusesReturnedAccordingSource() {
167         final int bulkSize = 2;
168         final List<String> jobIds = createBulkAndWaitForBeCompleted(bulkSize);
169
170         for(String jobId: jobIds) {
171             List<JobAuditStatus> actualVidAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.VID.name());
172             List<JobAuditStatus> expectedVidAudits = Stream.of(JobStatus.PENDING, JobStatus.IN_PROGRESS, JobStatus.COMPLETED)
173                     .map(status->new JobAuditStatus(UUID.fromString(jobId),
174                             status.name(),
175                             JobAuditStatus.SourceStatus.VID,
176                             null,
177                             null,
178                             status.equals(JobStatus.COMPLETED))).collect(toList());
179             assertThat(actualVidAudits, is(expectedVidAudits));
180
181             List<JobAuditStatus> actualMsoAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name());
182             List<JobAuditStatus> expectedMsoAudits = Stream.of("REQUESTED", "COMPLETE")
183                     .map(status-> new JobAuditStatus(UUID.fromString(jobId),
184                             status,
185                             JobAuditStatus.SourceStatus.MSO,
186                             UUID.fromString("c0011670-0e1a-4b74-945d-8bf5aede1d9c"),
187                             status.equals("COMPLETE") ? "Service Instance was created successfully." : null,
188                             false)).collect(toList());
189             assertThat(actualMsoAudits, is(expectedMsoAudits));
190         }
191     }
192
193     protected List<String> createBulkAndWaitForBeCompleted(int bulkSize){
194         Map<Keys, String> names = generateNames();
195         ImmutableList<BasePreset> presets = addPresetsForCreateBulkOfCreateInstances(bulkSize, names);
196         final List<String> jobIds = createBulkOfInstances(presets, false, bulkSize, names);
197         Assert.assertEquals(jobIds.size(),bulkSize);
198
199         assertTrue(String.format("Not all services with ids: %s are in state completed after 30 sec",
200                 jobIds.stream().collect(joining(","))),
201
202                 Wait.waitFor(y-> serviceListCall().getBody().stream()
203                         .filter(si -> jobIds.contains(si.jobId))
204                         .filter(si -> si.jobStatus==JobStatus.COMPLETED)
205                         .count() == bulkSize,
206                 null, 30, 1 ));
207         return jobIds;
208     }
209
210     private List<JobAuditStatus> getAuditStatuses(String jobUUID, String source){
211         String url = getJobAuditUrl().replace("{JOB_ID}",jobUUID).replace("{SOURCE}", source);
212         ResponseEntity<List<JobAuditStatus>> statusesResponse = auditStatusCall(url);
213         assertThat(statusesResponse.getStatusCode(), CoreMatchers.equalTo(HttpStatus.OK));
214         return statusesResponse.getBody();
215     }
216
217     @Test(expectedExceptions = HttpClientErrorException.class)
218     public void addBulkAndDeleteInProgress_deletionIsRejected(){
219         try {
220             final Map<String, JobStatus> jobs = addBulkAllPendingButOneInProgress();
221             deleteOneJobHavingTheStatus(jobs, JobStatus.IN_PROGRESS);
222         } catch (HttpClientErrorException e) {
223             JsonAssert.assertJsonPartEquals(
224                     "Service status does not allow deletion from the queue (Request id: null)",
225                     e.getResponseBodyAsString(),
226                     "message"
227             );
228             assertThat(e.getStatusCode(), is(HttpStatus.METHOD_NOT_ALLOWED));
229
230             throw e;
231         }
232     }
233
234     @Test
235     public void addBulkAndDeletePending_deletedIsHiddenFromServiceInfoResults(){
236         Map<String, JobStatus> statusesBefore = addBulkAllPendingButOneInProgress();
237
238         final String deletedJob = deleteOneJobHavingTheStatus(statusesBefore, JobStatus.PENDING);
239
240         final Map<String, JobStatus> statusesNow = serviceListCall().getBody().stream()
241                 .filter(si -> statusesBefore.keySet().contains(si.jobId))
242                 .collect(toMap(si -> si.jobId, si -> si.jobStatus));
243
244         statusesBefore.remove(deletedJob);
245         assertThat("deleted job shall not be present in StatusInfo response", statusesNow, is(statusesBefore));
246     }
247
248     private Map<String, JobStatus> addBulkAllPendingButOneInProgress(){
249         return addBulkAllPendingButOneInProgress(3);
250     }
251     
252     private Map<String, JobStatus> addBulkAllPendingButOneInProgress(int bulkSize){
253         Map<Keys, String> names = generateNames();
254         ImmutableList<BasePreset> msoBulkPresets = IntStream.rangeClosed(1,bulkSize)
255                 .mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i))
256                 .collect(ImmutableList.toImmutableList());
257         ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
258                 .add(new PresetGetSessionSlotCheckIntervalGet())
259                 .add(new PresetAAISearchNodeQueryEmptyResult())
260                 .add(new PresetAAIGetSubscribersGet())
261                 .addAll(msoBulkPresets)
262                 .add(new PresetMSOOrchestrationRequestGet("IN_PROGRESS"))
263                 .build();
264         final List<String> jobIds = createBulkOfInstances(presets, false, bulkSize, names);
265
266         // wait for single IN_PROGRESS, so statuses will stop from changing
267         Wait.waitFor(foo -> serviceListCall().getBody().stream()
268                         .filter(si -> jobIds.contains(si.jobId))
269                         .anyMatch(si -> si.jobStatus.equals(JobStatus.IN_PROGRESS)),
270                 null, 20, 1);
271
272         final Map<String, JobStatus> statusMapBefore = serviceListCall().getBody().stream()
273                 .filter(si -> jobIds.contains(si.jobId))
274                 .collect(toMap(si -> si.jobId, si -> si.jobStatus));
275
276         assertThat(jobIds, hasSize(bulkSize));
277
278
279         return statusMapBefore;
280     }
281
282     private String deleteOneJobHavingTheStatus(Map<String, JobStatus> jobIdToStatus, JobStatus jobStatus) {
283         final String jobToDelete = jobIdToStatus.entrySet().stream()
284                 .filter(entry -> entry.getValue().equals(jobStatus))
285                 .map(Map.Entry::getKey)
286                 .findFirst().orElseThrow(() -> new AssertionError("no job in " + jobStatus + " state: " + jobIdToStatus));
287
288
289         restTemplate.delete(getDeleteServiceUrl(jobToDelete));
290
291         return jobToDelete;
292     }
293
294     @Test(invocationCount = 3)
295     public void createBulkOfCreateInstancesWithSinglePreset_firstOneInProgressOtherArePending(){
296         final int bulkSize = 3;
297         Map<String, JobStatus> statusMap = addBulkAllPendingButOneInProgress(bulkSize);
298         Set<String> jobIds = statusMap.keySet();
299
300         final Map<JobStatus, List<ServiceInfo>> statuses = serviceListCall().getBody().stream()
301                 .filter(si -> jobIds.contains(si.jobId))
302                 .collect(groupingBy(ServiceInfo::getJobStatus));
303
304         // Variable "statuses" contains two lists by status:
305         // IN_PROGRESS:  The ultimate first job - named with _001 - is always the only one in progress
306         // PENDING:      The other two jobs - named with _002 and _003 - are the still pending
307         assertThat(jobIds, hasSize(bulkSize));
308         assertThat(statuses.get(JobStatus.IN_PROGRESS), hasSize(1));
309         assertThat(statuses.get(JobStatus.IN_PROGRESS), everyItem(hasProperty("serviceInstanceName", endsWith("_001"))));
310
311         assertThat(statuses.get(JobStatus.PENDING), hasSize(bulkSize - 1));
312     }
313
314
315     @Test(dataProvider = "trueAndFalse" )
316     public void whenServiceInBulkFailed_otherServicesAreStopped(Boolean isPresetForCreate){
317         Map<Keys, String> names = generateNames();
318         final int bulkSize = 3;
319
320         //if there is a preset for create,  service shall failed during in_progress (upon get status)
321         //it there is no preset for create, service shall failed during pending (upon create request)
322         List<BasePreset> msoBulkPresets = isPresetForCreate ?
323                 IntStream.rangeClosed(1,bulkSize)
324                         .mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i))
325                         .collect(ImmutableList.toImmutableList()) :
326                 new LinkedList<>();
327         ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
328                 .add(new PresetGetSessionSlotCheckIntervalGet())
329                 .add(new PresetAAIGetSubscribersGet())
330                 .add(new PresetAAISearchNodeQueryEmptyResult())
331                 .addAll(msoBulkPresets)
332                 .add(new PresetMSOOrchestrationRequestGet("FAILED"))
333                 .build();
334         List<String> jobIds = createBulkOfInstances(presets, false, bulkSize, names);
335         Assert.assertEquals(jobIds.size(),bulkSize);
336         boolean result = Wait.waitFor(x->{
337                 List<ServiceInfo> serviceInfoList = serviceListCall().getBody();
338                 Map<JobStatus, Long> statusCount = serviceInfoList.stream().filter(si->jobIds.contains(si.jobId)).collect(groupingBy(ServiceInfo::getJobStatus, counting()));
339                 return Objects.equals(statusCount.get(JobStatus.FAILED), 1L) && Objects.equals(statusCount.get(JobStatus.STOPPED), 2L);
340             }, null, 15, 1);
341         assertTrue(String.format("failed to get jobs [%s] to state of: 1 failed and 2 stopped ",
342                 String.join(",", jobIds)),result);
343     }
344
345     @Test
346     public void createBulkOfAssignInstances(){
347         Map<Keys, String> names = generateNames();
348         final int bulkSize = 2;
349         ImmutableList<BasePreset> msoBulkPresets = IntStream.rangeClosed(1,bulkSize)
350                 .mapToObj(i-> new PresetMSOAssignServiceInstanceGen2WithNames(names, i))
351                 .collect(ImmutableList.toImmutableList());
352         ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
353                 .add(new PresetGetSessionSlotCheckIntervalGet())
354                 .add(new PresetAAIGetSubscribersGet())
355                 .add(new PresetAAISearchNodeQueryEmptyResult())
356                 .addAll(msoBulkPresets)
357                 .add(new PresetMSOOrchestrationRequestGet())
358                 .build();
359         createBulkOfInstancesAndAssert(presets, true, bulkSize, JobStatus.COMPLETED, names);
360     }  
361
362     @Test
363     public void tryToCreateBulkOfAssignInstancesErrorResponseFromMso(){
364         ImmutableList<BasePreset> presets = ImmutableList.of(
365                 new PresetGetSessionSlotCheckIntervalGet(),
366                 new PresetAAIGetSubscribersGet(),
367                 new PresetAAISearchNodeQueryEmptyResult(),
368                 new PresetMSOServiceInstanceGen2ErrorResponse(406));
369
370         List<String> jobIds = createBulkOfInstancesAndAssert(presets, true,1, JobStatus.FAILED, generateNames());
371         String jobId  = jobIds.get(0);
372         List<JobAuditStatus> actualMsoAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name());
373         JobAuditStatus expectedMsoAudit = new JobAuditStatus(UUID.fromString(jobId),"FAILED",JobAuditStatus.SourceStatus.MSO,
374                         null,
375                         "Http Code:406, \"messageId\":\"SVC0002\",\"text\":\"JSON Object Mapping Request\"" ,
376                         false);
377         assertThat(actualMsoAudits.get(0), is(expectedMsoAudit));
378     }
379
380     @Test
381     public void whenHideCompletedService_thenServiceNotReturnInServiceList(){
382         List<String> services = createBulkAndWaitForBeCompleted(2);
383         hideService(services.get(0));
384         List<String> serviceInfoList = serviceListCall().getBody().stream().map(ServiceInfo::getJobId).collect(toList());
385         assertThat(serviceInfoList, hasItem(services.get(1)));
386         assertThat(serviceInfoList, not(hasItem(services.get(0))));
387     }
388
389     private MsoResponseWrapper2 hideService(String jobId) {
390         MsoResponseWrapper2 responseWrapper2 = callMsoForResponseWrapper(org.springframework.http.HttpMethod.POST, getHideServiceUri(jobId), "");
391         return responseWrapper2;
392     }
393
394     private List<String> createBulkOfInstancesAndAssert(ImmutableList<BasePreset> presets, boolean isPause, int bulkSize, JobStatus finalState, Map<Keys, String> names){
395         List<String> jobIds = createBulkOfInstances(presets, isPause, bulkSize, names);
396         Assert.assertEquals(jobIds.size(),bulkSize);
397         for(String jobId: jobIds) {
398             ServiceInfo expectedServiceInfo = new ServiceInfo("vid1", JobStatus.IN_PROGRESS, isPause, "someID",
399                     "someName", "myProject", "NFT1", "NFTJSSSS-NFT1", "greatTenant", "greatTenant", "mtn3", null,
400                     "mySubType", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", null, names.get(Keys.SERVICE_NAME),
401                     "300adb1e-9b0c-4d52-bfb5-fa5393c4eabb", "AIM_TRANSPORT_00004", "1.0", jobId, null);
402             JobInfoChecker jobInfoChecker = new JobInfoChecker(
403                     restTemplate, ImmutableSet.of(JobStatus.PENDING, JobStatus.IN_PROGRESS, finalState), jobId, expectedServiceInfo);
404             boolean result = jobInfoChecker.test(null);
405             assertTrue("service info of jobId: " + jobId + " was in status: " + jobInfoChecker.lastStatus, result);
406
407             jobInfoChecker.setExpectedJobStatus(ImmutableSet.of(finalState));
408             if (ImmutableList.of(JobStatus.COMPLETED, JobStatus.PAUSE).contains(finalState)) {
409                 expectedServiceInfo.serviceInstanceId = "f8791436-8d55-4fde-b4d5-72dd2cf13cfb";
410             }
411             result = Wait.waitFor(jobInfoChecker, null, 20, 1);
412             assertTrue("service info of jobId: " + jobId + " was in status: " + jobInfoChecker.lastStatus, result);
413         }
414
415         return jobIds;
416     }
417
418     private List<String> createBulkOfInstances(ImmutableList<BasePreset> presets, boolean isPause, int bulkSize, Map<Keys, String> names){
419
420         SimulatorApi.registerExpectationFromPresets(presets, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
421
422         String requestBody = TestUtils.convertRequest(objectMapper, CREATE_BULK_OF_MACRO_REQUEST);
423         requestBody = requestBody.replace("\"IS_PAUSE_VALUE\"", String.valueOf(isPause)).replace("\"BULK_SIZE\"", String.valueOf(bulkSize));
424         for (Map.Entry<Keys, String> e : names.entrySet()) {
425             requestBody = requestBody.replace(e.getKey().name(), e.getValue());
426         }
427         MsoResponseWrapper2 responseWrapper2 = callMsoForResponseWrapper(org.springframework.http.HttpMethod.POST, getCreateBulkUri(), requestBody);
428         assertNotNull(responseWrapper2);
429         return (List<String>)responseWrapper2.getEntity();
430     }
431
432     public class JobInfoChecker<Integer> implements Predicate<Integer> {
433
434         private final RestTemplate restTemplate;
435         private Set<JobStatus> expectedJobStatus;
436         private ServiceInfo expectedServiceInfo;
437         private final String jobId;
438         private JobStatus lastStatus;
439
440         public JobInfoChecker(RestTemplate restTemplate, Set<JobStatus> expectedJobStatus, String jobId, ServiceInfo expectedServiceInfo) {
441             this.restTemplate = restTemplate;
442             this.expectedJobStatus = expectedJobStatus;
443             this.jobId = jobId;
444             this.expectedServiceInfo = expectedServiceInfo;
445         }
446
447         public void setExpectedJobStatus(Set<JobStatus> expectedJobStatus) {
448             this.expectedJobStatus = expectedJobStatus;
449         }
450
451         @Override
452         public boolean test(Integer integer) {
453             ResponseEntity<List<ServiceInfo>> serviceListResponse = serviceListCall();
454             assertThat(serviceListResponse.getStatusCode(), CoreMatchers.equalTo(HttpStatus.OK));
455             assertThat(serviceListResponse.getBody(), hasItem(new JobIdAndStatusMatcher(jobId)));
456             ServiceInfo serviceInfoFromDB = serviceListResponse.getBody().stream()
457                     .filter(serviceInfo -> serviceInfo.jobId.equals(jobId))
458                     .findFirst().orElse(null);
459             Assert.assertNotNull(serviceInfoFromDB);
460             Assert.assertEquals(serviceInfoDataReflected(serviceInfoFromDB), serviceInfoDataReflected(expectedServiceInfo));
461             assertTrue("actual service instance doesn't contain template service name:" + expectedServiceInfo.serviceInstanceName,
462                     serviceInfoFromDB.serviceInstanceName.contains(expectedServiceInfo.serviceInstanceName));
463             if (serviceInfoFromDB.jobStatus==JobStatus.IN_PROGRESS || serviceInfoFromDB.jobStatus==JobStatus.COMPLETED) {
464                 assertTrue("actual service instance doesn't contain template service name and trailing numbers:" + expectedServiceInfo.serviceInstanceName,
465                         serviceInfoFromDB.serviceInstanceName.contains(expectedServiceInfo.serviceInstanceName+"_00"));
466             }
467
468             if (expectedServiceInfo.serviceInstanceId != null) {
469                 assertThat(serviceInfoFromDB.serviceInstanceId, is(expectedServiceInfo.serviceInstanceId));
470             }
471             lastStatus = serviceInfoFromDB.jobStatus;
472             return expectedJobStatus.contains(serviceInfoFromDB.jobStatus);
473         }
474     }
475
476     private ResponseEntity<List<ServiceInfo>> serviceListCall() {
477         return restTemplate.exchange(
478                 getServiceInfoUrl(),
479                 org.springframework.http.HttpMethod.GET,
480                 null,
481                 new ParameterizedTypeReference<List<ServiceInfo>>() {});
482     }
483
484     //serialize fields except of fields we cannot know ahead of time
485     private static String serviceInfoDataReflected(ServiceInfo service1) {
486         return new ReflectionToStringBuilder(service1, ToStringStyle.SHORT_PREFIX_STYLE)
487                 .setExcludeFieldNames("jobStatus", "templateId", "statusModifiedDate", "createdBulkDate", "serviceInstanceId", "serviceInstanceName")
488                 .toString();
489     }
490
491     @Test
492     public void errorResponseInGetStatusFromMso_getAuditStatusFromMso_errorMsgExistInAdditionalInfo(){
493         Map<Keys, String> names = generateNames();
494         ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
495                 .add(new PresetGetSessionSlotCheckIntervalGet())
496                 .add(new PresetAAIGetSubscribersGet())
497                 .add(new PresetAAISearchNodeQueryEmptyResult())
498                 .add(new PresetMSOAssignServiceInstanceGen2WithNames(names, 1))
499                 .add(new PresetMSOOrchestrationRequestGetErrorResponse(406))
500                 .build();
501
502         final List<String> jobIds = createBulkOfInstancesAndAssert(presets, true,1, JobStatus.IN_PROGRESS, names);
503         String jobId = jobIds.get(0);
504         Wait.waitFor(y-> getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name()).stream()
505                         .anyMatch(si -> si.getJobStatus().equals("FAILED")),
506                 null, 10, 1 );
507         List<JobAuditStatus> actualMsoAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name());
508         List<JobAuditStatus> expectedMsoAudits = Stream.of("REQUESTED", "FAILED")
509                 .map(status -> new JobAuditStatus(UUID.fromString(jobId),
510                         status,
511                         JobAuditStatus.SourceStatus.MSO,
512                         UUID.fromString("c0011670-0e1a-4b74-945d-8bf5aede1d9c"),
513                         status.equals("FAILED") ? "Http Code:406, \"messageId\":\"SVC0002\",\"text\":\"JSON Object Mapping Request\"" : null,
514                         false)).collect(toList());
515         assertThat(actualMsoAudits, is(expectedMsoAudits));
516
517     }
518
519 }