Mutation test not being. covered in spring boot for Exception and BeanUtils.copyProperties - spring-boot

public PartsServiceCombineModelDTO getServicePartsByModel(String model) {
ServiceInstance instance = loadBalancer.choose("PARTS_APP");
if (instance == null || instance.getUri() == null) {
throw new NoInstanceExistException("Part App Instance Not Available ");
}
String url = instance.getUri().toString();
ParameterizedTypeReference<List<PartsDTO>> responseType = new ParameterizedTypeReference<List<PartsDTO>>() {
};
HttpEntity<String> entity = new HttpEntity<>(new HttpHeaders());
ResponseEntity<List<PartsDTO>> response = restTemplate.exchange(url + properties.getPartModel() + model, HttpMethod.GET, entity, responseType);
List<CarService> service = repository.findAllByModel(model);
List<ServiceDTO> carsDto;
if (service.isEmpty()) {
throw new NoSuchCarExistException("Car Service Not Available");
} else {
carsDto = new ArrayList<>();
for (CarService car : service) {
ServiceDTO carDto = new ServiceDTO();
BeanUtils.copyProperties(car, carDto);
carsDto.add(carDto);
}
}
PartsServiceCombineModelDTO partsServiceCombineModelDTO = new PartsServiceCombineModelDTO(response.getBody(), carsDto);
return partsServiceCombineModelDTO;
}
Mutation Test Report
Here my test method which is not able to to mutate below topics
void getServicePartsByModel() {
when(properties.getPartModel()).thenReturn("/parts/model/");
ServiceInstance instance = mock(ServiceInstance.class);
when(instance.getUri()).thenReturn(URI.create("http://localhost:8080"));
when(loadBalancerClient.choose(eq("PARTS_APP"))).thenReturn(instance);
PartsDTO partsDTO = new PartsDTO();
partsDTO.setId("42");
partsDTO.setManufacturer("Manufacturer");
partsDTO.setMaterial("Material");
partsDTO.setModel("Model");
partsDTO.setPartName("Part Name");
partsDTO.setPartNumber("42");
partsDTO.setPrice(1);
partsDTO.setStock(1);
partsDTO.setWarranty("Warranty");
partsDTO.setYear(1);
PartsDTO partsDTO1 = new PartsDTO();
partsDTO1.setId("42");
partsDTO1.setManufacturer("Manufacturer");
partsDTO1.setMaterial("Material");
partsDTO1.setModel("Model");
partsDTO1.setPartName("Part Name");
partsDTO1.setPartNumber("42");
partsDTO1.setPrice(1);
partsDTO1.setStock(1);
partsDTO1.setWarranty("Warranty");
partsDTO1.setYear(1);
List<PartsDTO> parts = new ArrayList<>();
parts.add(partsDTO1);
parts.add(partsDTO);
ResponseEntity<List<PartsDTO>> partsResponse = ResponseEntity.ok(parts);
when(restTemplate.exchange(any(String.class), eq(HttpMethod.GET), any(HttpEntity.class), eq(new ParameterizedTypeReference<List<PartsDTO>>() {
}))).thenReturn(partsResponse);
List<CarService> carServices = new ArrayList<>();
CarService carService = new CarService();
carService.setCertified(true);
carService.setDealershipTrained(true);
carService.setId("42");
carService.setModel("Model");
carService.setOemParts(true);
carService.setServiceKM(1);
carService.setServiceMileage(1);
carService.setServiceName("Service Name");
carService.setServiceType(1);
carServices.add(carService);
when(serviceRepository.findAllByModel(eq(carService.getModel()))).thenReturn(carServices);
assertNotNull(carService);
verify(beanUtils, atLeastOnce());
BeanUtils.copyProperties(new CarService(),new ServiceDTO());
PartsServiceCombineModelDTO result = carServiceImpl.getServicePartsByModel(partsDTO.getModel());
}
Which throwing error :
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
-> at com.example.carserviceapp.service.CarServiceImplTest.getServicePartsByModel(CarServiceImplTest.java:728)
-> at com.example.carserviceapp.service.CarServiceImplTest.getServicePartsByModel(CarServiceImplTest.java:731)
-> at com.example.carserviceapp.service.CarServiceImplTest.getServicePartsByModel(CarServiceImplTest.java:763)
-> at com.example.carserviceapp.service.CarServiceImplTest.getServicePartsByModel(CarServiceImplTest.java:778)
Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.
org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Can Anyone Please help me in mutating the above method
BeanUtils.copyProperties(car, carDto); and
throw new NoSuchCarExistException("Car Service Not Available");

Related

Calling an Oracle GlInterface SOAP service in .net Core

Error : System.ServiceModel.FaultException`1[Service.ServiceErrorMessage]: JBO-GL:::GL_INVALID_LEDGER: GL-781535You have entered an invalid ledger value. (Fault Detail is equal to Service.ServiceErrorMessage).
only result when I search
BasicHttpBinding basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress endpointAddress = new EndpointAddress(new Uri("https://fa-eosd-dev1-saasfaprod1.fa.ocs.oraclecloud.com:443/fscmService/JournalImportService?WSDL"));
ChannelFactory<JournalImportService> factory = new ChannelFactory<JournalImportService>(basicHttpBinding, endpointAddress);
factory.Credentials.UserName.UserName = "user";
factory.Credentials.UserName.Password = "pass";
JournalImportService serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
var opContext = new OperationContext((IClientChannel)serviceProxy);
var prevOpContext = OperationContext.Current; // Optional if there's no way this might already be set
OperationContext.Current = opContext;
importJournalsRequest importJournalsRequest = new importJournalsRequest();
GlInterfaceTransHeader glInterfaceTransHeader = new GlInterfaceTransHeader();
glInterfaceTransHeader.LedgerId = 300000001958365;
List<GlInterface> glInterface = new List<GlInterface>();
glInterface.Add(glInter);
glInterfaceTransHeader.GlInterface = glInterface.ToArray();
importJournalsRequest.interfaceRows = glInterfaceTransHeader;
try
{
var result = await serviceProxy.importJournalsAsync(importJournalsRequest);
//cleanup
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (Exception ex)
{
throw ex;
}
finally
{
// *** ENSURE CLEANUP *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
OperationContext.Current = prevOpContext; // Or set to null if you didn't capture the previous context
}
}
glInterfaceTransHeader.AccountingDateSpecified = true;

Return ldap entries on paginated form in springboot

I have a ldap method that returns all users that are in it (almost 1300 users) and I want to return them by page, similar to what PagingAndSortingRepository does in Springboot:
If I have this endpoint ( users/?page=0&size=1 )and I wnat to return on page 0 just 1 entry.
Is there any way to do that?
Currently I have this but it doesn´t work:
SearchRequest searchRequest = new SearchRequest(ldapConfig.getBaseDn(), SearchScope.SUB,
Filter.createEqualityFilter("objectClass", "person"));
ASN1OctetString resumeCookie = null;
while (true) {
searchRequest.setControls(new SimplePagedResultsControl(pageable.getPageSize(), resumeCookie));
SearchResult searchResult = ldapConnection.search(searchRequest);
numSearches++;
totalEntriesReturned += searchResult.getEntryCount();
for (SearchResultEntry e : searchResult.getSearchEntries()) {
String[] completeDN = UaaUtils.searchCnInDn(e.getDN());
String[] username = completeDN[0].split("=");
UserEntity u = new UserEntity(username[1]);
list.add(u);
System.out.println("TESTE");
}
SimplePagedResultsControl responseControl = SimplePagedResultsControl.get(searchResult);
if (responseControl.moreResultsToReturn()) {
// The resume cookie can be included in the simple paged results
// control included in the next search to get the next page of results.
System.out.println("Antes "+resumeCookie);
resumeCookie = responseControl.getCookie();
System.out.println("Depois "+resumeCookie);
} else {
break;
}
Page<UserEntity> newPage = new PageImpl<>(list, pageable, totalEntriesReturned);
System.out.println("content " + newPage.getContent());
System.out.println("total elements " + newPage.getTotalElements());
System.out.println(totalEntriesReturned);
}
I'm unsure if this is the proper way, but here's how I went about it:
public PaginatedLookup getAll(String page, String perPage) {
PagedResultsCookie cookie = null;
List<LdapUser> results;
try {
if ( page != null ) {
cookie = new PagedResultsCookie(Hex.decode(page));
} // end if
Integer pageSize = perPage != null ? Integer.parseInt(perPage) : PROCESSOR_PAGE_SIZE;
PagedResultsDirContextProcessor processor = new PagedResultsDirContextProcessor(pageSize, cookie);
LdapName base = LdapUtils.emptyLdapName();
SearchControls sc = new SearchControls();
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
sc.setTimeLimit(THREE_SECONDS);
sc.setCountLimit(pageSize);
sc.setReturningAttributes(new String[]{"cn", "title"});
results = ldapTemplate.search(base, filter.encode(), sc, new PersonAttributesMapper(), processor);
cookie = processor.getCookie();
} catch ( Exception e ) {
log.error(e.getMessage());
return null;
} // end try-catch
String nextPage = null;
if ( cookie != null && cookie.getCookie() != null ) {
nextPage = new String(Hex.encode(cookie.getCookie()));
} // end if
return new PaginatedLookup(nextPage, results);
}
The main issue I kept on hitting was trying to get the cookie as something that could be sent to the client, which is where my Hex.decode and Hex.encode came in handy.
PersonAttributesMapper is a private mapper that I have to make the fields more human readable, and PaginatedLookup is a custom class I use for API responses.

CRM 2013 : How can I Schedule Concurrent Appointments (using Appointment & RecurringAppointmentMaster entities)?

We have a plugin that uses the BookRequest & RescheduleRequest Methods to schedule Appointment & RecurringAppointmentMaster entities.
Recently I was tasked with implementing the ability to schedule multiple appts in a given timeslot.
So in researching this, I found some posts referring to resource capacity (in work hours) & setting the Effort field of the ActivityParty to 1.0 in the Appointment.
I thought, great this will be easy.
So I changed the plugin to store the effort:
activityParty = new Entity("activityparty");
activityParty["partyid"] = new EntityReference("systemuser", apptCaregiverId);
activityParty["effort"] = (Double)1.0;
But when I ran the code, the BookRequest returned this error that confused me: ErrorCode.DifferentEffort
I searched for ErrorCode.DifferentEffort, 2139095040, BookRequest, you name it found nothing useful.
What exactly does this error mean?
Why is it so difficult to schedule concurrent appointments in CRM?
This is what I learned the hard way, so maybe it will spare someone else some frustration.
I looked in the database & noticed that the activityparty entities associated with appointments all had the effort field set to 2139095040 and I wondered where that number was coming from? In a post unrelated to CRM, I found out the 2139095040 means 'positive infinity'.
I revisited the posts where they talk about setting the effort to 1.0 & realized that they were all referring to the ServiceAppointment entity (not Appointment) and then I finally stumbled on the list of error codes
Scheduling Error Codes
DifferentEffort = The required capacity of this service does not match the capacity of resource {resource name}.
Not exactly the truth, but whatever.
The real issue is the Appointment entity does not reference a Service, therefore the capacity of the non-existent service is ‘Positive Infinity’ (2139095040).
Setting the Effort equal to anything but 2139095040 throws this error.
It isn’t really checking the capacity of the resource here, it’s just saying that the non-existent service capacity must be = 2139095040
Anyway to get around this I removed the logic that sets the effort = 1.0 and when BookRequest or RescheduleRequest returns ErrorCode.ResourceBusy, I check the Capacity vs the # appts scheduled in that timeslot & if there is capacity left over, I force it to overbook by using Create or Update.
private Guid BookAppointment(Entity appointment, bool setState, out List<string> errors)
{
Guid apptId = Guid.Empty;
try
{
BookRequest request = new BookRequest
{
Target = appointment
};
BookResponse booked = (BookResponse)this.orgService.Execute(request);
apptId = ParseValidationResult(booked.ValidationResult, setState, appointment, true, out errors);
}
catch (Exception ex)
{
errors = new List<string> { ex.GetBaseException().Message };
}
return apptId;
}
private Guid RescheduleAppointment(Entity appointment, out List<string> errors)
{ // used to reschedule non-recurring appt or appt in recurrence
Guid apptId = Guid.Empty;
try
{
RescheduleRequest request = new RescheduleRequest
{
Target = appointment
};
RescheduleResponse rescheduled = (RescheduleResponse)this.orgService.Execute(request);
apptId = ParseValidationResult(rescheduled.ValidationResult, false, appointment, false, out errors);
}
catch (Exception ex)
{
errors = new List<string> { ex.GetBaseException().Message };
}
return apptId;
}
private Guid ParseValidationResult(ValidationResult result, bool setState, Entity appointment, Boolean addNew, out List<string> errors)
{
Guid apptId = result.ActivityId;
errors = new List<string>();
if (result.ValidationSuccess == true)
{
if (setState == true)
{
SetStateRequest state = new SetStateRequest();
state.State = new OptionSetValue(3); // Scheduled
state.Status = new OptionSetValue(5); // Busy
state.EntityMoniker = new EntityReference("appointment", apptId);
SetStateResponse stateSet = (SetStateResponse)this.orgService.Execute(state);
}
}
else
{
String error;
String errortxt;
Boolean overbookAppt = true;
foreach (var errorInfo in result.TraceInfo.ErrorInfoList)
{
bool unavailable = false;
if (errorInfo.ErrorCode == "ErrorCode.ResourceNonBusinessHours")
{
errortxt = "{0} is being scheduled outside work hours";
}
else if (errorInfo.ErrorCode == "ErrorCode.ResourceBusy")
{
errortxt = "{0} is unavailable at this time";
unavailable = true;
}
else
{
errortxt = "failed to schedule {0}, error code = " + errorInfo.ErrorCode;
}
Dictionary<Guid, String> providers;
Dictionary<Guid, String> resources;
DateTime start = DateTime.Now, end = DateTime.Now;
Guid[] resourceIds = errorInfo.ResourceList.Where(r => r.EntityName == "equipment").Select(r => r.Id).ToList().ToArray();
if (unavailable == true)
{
if (appointment.LogicalName == "recurringappointmentmaster")
{
start = (DateTime)appointment["starttime"];
end = (DateTime)appointment["endtime"];
}
else
{
start = (DateTime)appointment["scheduledstart"];
end = (DateTime)appointment["scheduledend"];
}
Dictionary<Guid, Boolean> availability = GetAvailabilityOfResources(resourceIds, start, end);
resourceIds = availability.Where(a => a.Value == false).Select(t => t.Key).ToArray(); // get ids of all unavailable resources
if (resourceIds.Count() == 0)
{ // all resources still have capacity left at this timeslot - overbook appt timeslot
overbookAppt = true;
} // otherwise at least some resources are booked up in this timeslot - return error
}
if (errortxt.Contains("{0}"))
{ // include resource name in error msg
if (resourceIds.Count() > 0)
{
LoadProviderAndResourceInfo(resourceIds, out providers, out resources);
foreach (var resource in providers)
{
error = String.Format(errortxt, resource.Value);
errors.Add(error);
}
foreach (var resource in resources)
{
error = String.Format(errortxt, resource.Value);
errors.Add(error);
}
}
}
else
{ // no place for name in msg - just store it
errors.Add(errortxt);
break;
}
}
if (overbookAppt == true && errors.Count() == 0)
{ // all resources still have capacity left at this timeslot & no other errors have been returned - create appt anyway
if (addNew)
{
appointment.Attributes.Remove("owner"); // Create message does not like when owner field is specified
apptId = this.orgService.Create(appointment);
if (setState == true)
{
SetStateRequest state = new SetStateRequest();
state.State = new OptionSetValue(3); // Scheduled
state.Status = new OptionSetValue(5); // Busy
state.EntityMoniker = new EntityReference("appointment", apptId);
SetStateResponse stateSet = (SetStateResponse)this.orgService.Execute(state);
}
}
else
{
this.orgService.Update(appointment);
}
}
}
return apptId;
}
private Dictionary<Guid, Boolean> GetAvailabilityOfResources(Guid[] resourceIds, DateTime start, DateTime end)
{
Dictionary<Guid, Boolean> availability = new Dictionary<Guid, Boolean>();
QueryMultipleSchedulesRequest scheduleRequest = new QueryMultipleSchedulesRequest();
scheduleRequest.ResourceIds = resourceIds;
scheduleRequest.Start = start;
scheduleRequest.End = end;
// TimeCode.Unavailable - gets appointments
// TimeCode.Filter - gets resource capacity
scheduleRequest.TimeCodes = new TimeCode[] { TimeCode.Unavailable, TimeCode.Filter };
QueryMultipleSchedulesResponse scheduleResponse = (QueryMultipleSchedulesResponse)this.orgService.Execute(scheduleRequest);
int index = 0;
TimeInfo[][] timeInfo = new TimeInfo[scheduleResponse.TimeInfos.Count()][];
foreach (var schedule in scheduleResponse.TimeInfos)
{
TimeInfo resourceCapacity = schedule.Where(s => s.SubCode == SubCode.ResourceCapacity).FirstOrDefault();
Int32 capacity = (resourceCapacity != null) ? (Int32)resourceCapacity.Effort : 1;
Int32 numAppts = schedule.Where(s => s.SubCode == SubCode.Appointment).Count();
// resource is available if capacity is more than # appts in timeslot
availability.Add(resourceIds[index++], (capacity > numAppts) ? true : false);
}
return availability;
}
This is really a better solution than setting the Effort = 1 anyway because now we don’t need a one-time on-demand workflow to update existing data.
I hope this helps save you some time if you ever need to do this.

ElasticsearchTemplate retrieve big data sets

I am new to ElasticsearchTemplate. I want to get 1000 documents from Elasticsearch based on my query.
I have used QueryBuilder to create my query , and it is working perfectly.
I have gone through the following links , which states that it is possible to achieve big data sets using scan and scroll.
link one
link two
I am trying to implement this functionality in the following section of code, which I have copy pasted from one of the link , mentioned above.
But I am getting following error :
The type ResultsMapper is not generic; it cannot be parameterized with arguments <myInputDto>.
MyInputDto is a class with #Document annotation in my project.
End of the day , I just want to retrieve 1000 documents from Elasticsearch.
I tried to find size parameter but I think it is not supported.
String scrollId = esTemplate.scan(searchQuery, 1000, false);
List<MyInputDto> sampleEntities = new ArrayList<MyInputDto>();
boolean hasRecords = true;
while (hasRecords) {
Page<MyInputDto> page = esTemplate.scroll(scrollId, 5000L,
new ResultsMapper<MyInputDto>() {
#Override
public Page<MyInputDto> mapResults(SearchResponse response) {
List<MyInputDto> chunk = new ArrayList<MyInputDto>();
for (SearchHit searchHit : response.getHits()) {
if (response.getHits().getHits().length <= 0) {
return null;
}
MyInputDto user = new MyInputDto();
user.setId(searchHit.getId());
user.setMessage((String) searchHit.getSource().get("message"));
chunk.add(user);
}
return new PageImpl<MyInputDto>(chunk);
}
});
if (page != null) {
sampleEntities.addAll(page.getContent());
hasRecords = page.hasNextPage();
} else {
hasRecords = false;
}
}
What is the issue here ?
Is there any other alternative to achieve this?
I will be thankful if somebody could tell me how this ( code ) is working in the back end.
Solution 1
If you want to use ElasticsearchTemplate, it would be much simpler and readable to use CriteriaQuery, as it allows to set the page size with setPageable method. With scrolling, you can get next sets of data:
CriteriaQuery criteriaQuery = new CriteriaQuery(Criteria.where("productName").is("something"));
criteriaQuery.addIndices("prods");
criteriaQuery.addTypes("prod");
criteriaQuery.setPageable(PageRequest.of(0, 1000));
ScrolledPage<TestDto> scroll = (ScrolledPage<TestDto>) esTemplate.startScroll(3000, criteriaQuery, TestDto.class);
while (scroll.hasContent()) {
LOG.info("Next page with 1000 elem: " + scroll.getContent());
scroll = (ScrolledPage<TestDto>) esTemplate.continueScroll(scroll.getScrollId(), 3000, TestDto.class);
}
esTemplate.clearScroll(scroll.getScrollId());
Solution 2
If you'd like to use org.elasticsearch.client.Client instead of ElasticsearchTemplate, then SearchResponse allows to set the number of search hits to return:
QueryBuilder prodBuilder = ...;
SearchResponse scrollResp = client.
prepareSearch("prods")
.setScroll(new TimeValue(60000))
.setSize(1000)
.setTypes("prod")
.setQuery(prodBuilder)
.execute().actionGet();
ObjectMapper mapper = new ObjectMapper();
List<TestDto> products = new ArrayList<>();
try {
do {
for (SearchHit hit : scrollResp.getHits().getHits()) {
products.add(mapper.readValue(hit.getSourceAsString(), TestDto.class));
}
LOG.info("Next page with 1000 elem: " + products);
products.clear();
scrollResp = client.prepareSearchScroll(scrollResp.getScrollId())
.setScroll(new TimeValue(60000))
.execute()
.actionGet();
} while (scrollResp.getHits().getHits().length != 0);
} catch (IOException e) {
LOG.error("Exception while executing query {}", e);
}

CRM SDK 2013 Activity doesn't exist just after creating it

I have a custom comment activity which I'm updating in code and this used to work but has started failing recently. It creates the activity but when I try to retrieve it or execute SetStateResponse on it, I get "tk_comment With Id = 9a1686d1-7d9d-e611-80e3-00155d001104 Does Not Exist" - which doesn't make sense as I've just created it! The activity record shows up against the account but I can't click on it there or do anything (Record is unavailable - The requested record was not found or you do not have sufficient permissions to view it.).
This is the code I'm using. I'd love you to tell me I've made some simple mistake :)
using (_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig))
{
_serviceProxy.EnableProxyTypes();
try
{
tk_comment comment = new tk_comment();
int maxLength = 190; //subject has a max length of 200 characters
if (subject.Length > maxLength)
{
comment.Subject = subject.Substring(0, maxLength);
comment.Description = subject.Substring(maxLength, subject.Length - maxLength);
}
else
{
comment.Subject = subject;
}
comment.RegardingObjectId = entity.ToEntityReference();
comment.ActualStart = CommentDate;
comment.ActualEnd = CommentDate;
comment.ScheduledStart = CommentDate;
comment.ScheduledEnd = CommentDate;
Guid commentID = _serviceProxy.Create(comment);
try
{
tk_comment aComment = (tk_comment)_serviceProxy.Retrieve(tk_comment.EntityLogicalName, commentID, new ColumnSet(allColumns: true));
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("Always an error here " + ex.Message);
}
Account test = (Account) _serviceProxy.Retrieve(Account.EntityLogicalName, entity.Id, new ColumnSet(allColumns: true));
// tk_comment newComment = (tk_comment)_serviceProxy.Retrieve(tk_comment.EntityLogicalName, commentID, new ColumnSet(allColumns: true));
SetStateRequest request = new SetStateRequest();
request.EntityMoniker = new EntityReference(tk_comment.EntityLogicalName, commentID);
request.State = new OptionSetValue((int) tk_commentState.Completed); //completed
request.Status = new OptionSetValue(2); //completed
SetStateResponse response = (SetStateResponse)_serviceProxy.Execute(request); //always an error here too
}
Appreciate any suggestions
Cheers, Mick
It seems like you don't have proper read permission of this custom activity entity.
OR You need to validate all the permissions of this custom entity.

Resources